- Replace ~/.local/projects-meta-mcp → ~/projects/.common/lib/projects-meta-mcp - Update setup-projects-meta and using-projects-meta skills - Rebuild dist/ with new paths Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 KiB
name, version, description
| name | version | description |
|---|---|---|
| using-projects-meta | 1.1.0 | Use when working across multiple projects on one or many machines — cross-project task aggregation (`mcp__projects-meta__tasks_*`), shared Gitea-backed wiki query / ingest (`mcp__projects-meta__knowledge_*`), or sync diagnostics (`mcp__projects-meta__meta_status`). Triggers on phrases like "across all projects", "what's on the boards", "check shared wiki", "search projects-wiki", "ingest into shared wiki", "что у меня на досках", "по всем проектам", "общая вики", "cross-project status", or any time the user wants to see / mutate state in another repo than the current cwd. v1.1.0 mandates a Step 0 freshness gate (probe `meta_status`, sync if stale, pull `projects-wiki` before shared-wiki writes) — see SKILL body. Mutation tools require two-step preview → confirm. Skip for the **current** project's tasks/wiki — those live on disk in `.tasks/` / `.wiki/`. |
Using the projects-meta MCP server
Overview
projects-meta-mcp is a local stdio MCP server. Two responsibilities:
- Cross-project task aggregation — parses
.tasks/STATUS.mdfrom every repo on the user's Gitea, caches them in~/.cache/projects-mcp/tasks.json. Read tools (tasks_aggregate,tasks_search,tasks_get) hit the cache. Mutations (tasks_create,tasks_update,tasks_close) commit back to Gitea with sha-based optimistic lock. - Shared knowledge wiki — single Gitea repo (
projects-wiki) cloned at~/projects/projects-wiki/with content at~/projects/projects-wiki/.wiki/, structured as packages / concepts / entities / sources / raw.knowledge_search+knowledge_getfor queries,knowledge_ingest+knowledge_promotefor writes.
Source of truth: Gitea (https://git.kzntsv.site, owner OpeItcLoc03). Cache and clone are local convenience.
Full reference: mcp__projects-meta__knowledge_get slug=packages/projects-meta-mcp.
Prerequisites
This skill assumes mcp__projects-meta__* tools are available. If they aren't (tools missing from the session, or calls fail with a connection error), the server isn't running for this session. Trigger the setup-projects-meta skill to clone, build, write auth.toml, and register mcpServers.projects-meta in ~/.claude.json. It's a one-time procedure with confirmation gates.
Local-first rule
For the current project — read disk directly. .tasks/STATUS.md and .wiki/ files in cwd are always fresher than the MCP cache. The cache:
- May be stale (default sync runs only when triggered).
- Hides 🟢 done by default.
- May not contain locally-developed projects that aren't pushed to Gitea yet.
Use MCP only for other projects, other machines, or shared wiki content.
| Question | Where to read |
|---|---|
| "What's the status of this project?" | local .tasks/STATUS.md |
| "What's on all my boards?" | mcp__projects-meta__tasks_aggregate |
| "Has this project's wiki got a page on X?" | local .wiki/index.md + relevant file |
| "Has the shared wiki got a page on X?" | mcp__projects-meta__knowledge_search |
| "Sync state across machines?" | mcp__projects-meta__meta_status |
When to use
- Cross-project task overview ("what am I working on across projects", "по всем проектам", "across the board").
- Hopping into another repo's task state without cloning it ("what's the status of project X").
- Querying the shared wiki for cross-cutting concepts (patterns, package references, design notes that apply to several repos).
- Ingesting a finished design / decision into the shared wiki so other machines / projects can see it.
- Creating a task in another project's
.tasks/STATUS.mdfrom the current repo (cross-project handoff). - Sync diagnostics (when did the cache last refresh, are there errors, how many projects).
When NOT to use
- The current project's own tasks or wiki — read disk.
- Anything inside a single project —
.tasks/<task>.mdand.wiki/<page>.mdare always closer. - One-off questions answered by
git logor a single file. - Library / framework documentation — that's
using-context7. - Code search — that's
Glob/Grep.
Step 0 — Freshness gate (run before any tool)
projects-meta is a bus between machines. Another host may have pushed minutes ago. Without this gate, reads return stale data and writes hit sha-based optimistic-lock 422s with no explanation. Mandatory pre-flight, every session, every workflow:
1. Call mcp__projects-meta__meta_status.
2. Branch on cache freshness:
• If cache_age_minutes > 10 OR errors_count > 0:
run `node ~/projects/.common/lib/projects-meta-mcp/dist/sync.js`
(or `npm run sync` from ~/projects/.common/lib/projects-meta-mcp).
• Else: cache is fresh enough — skip sync, no need to hit the network.
3. For shared-wiki WRITES (knowledge_ingest, knowledge_promote):
ALWAYS additionally run `git -C ~/projects/projects-wiki pull --ff-only`
regardless of cache age. The MCP server uses sha-based optimistic locking;
without an up-to-date local file SHA, the commit will be rejected (422)
and the failure mode is opaque to the user.
4. For tasks-mutations (tasks_create, tasks_update, tasks_close):
sync via dist/sync.js is enough — there's no local clone of the target
tasks repo, mutations go straight through Gitea API. Sync only refreshes
the local view so you reason from current state.
5. If sync returns 401 or 403:
STOP. The Gitea token in ~/.config/projects-mcp/auth.toml is dead or
wrong-scoped. Tell the user explicitly:
"Gitea sync failed with <401|403>. Rotate gitea_token in
~/.config/projects-mcp/auth.toml (Gitea: settings/applications)
and rerun."
Do not pretend sync succeeded. Do not retry silently.
Don't sync unconditionally on every call. Network overhead + risk of 401 even on a casual "what's on my boards". The 10-minute cache window is the right balance — catches multi-machine drift without burning Gitea round-trips for back-to-back questions.
Don't apply Step 0 to meta_status itself — it's the freshness probe, not a downstream read.
Workflow
Read (no confirmation needed)
0. Run Step 0 — Freshness gate (above) first.
1. Identify what you need: cross-project tasks? shared wiki page? sync state?
2. Pick the right read tool (table below).
3. Cite the result with the source slug / project name.
Mutate (always two-step)
0. Run Step 0 — Freshness gate (above) first.
For shared-wiki writes (knowledge_ingest, knowledge_promote): unconditional
`git -C ~/projects/projects-wiki pull --ff-only` is part of Step 0.
1. Identify the mutation: tasks_create / tasks_update / tasks_close / knowledge_ingest / knowledge_promote.
2. Call the tool WITHOUT `confirm: true` → returns a dry-run preview (the proposed file diff and the Gitea commit message).
3. Show the preview to the user. Wait for explicit "ok" / "go" / "поехали".
4. Re-call with `confirm: true` to commit.
Never inline confirm: true on the first call. A trigger phrase ("create a task in project X") is permission to plan, not to commit.
Tool quick reference
Read tools
| Tool | Required args | Purpose |
|---|---|---|
mcp__projects-meta__tasks_aggregate |
— | All active tasks across all cached projects |
mcp__projects-meta__tasks_search |
query |
Substring search across slug + next_action |
mcp__projects-meta__tasks_get |
project |
Raw STATUS.md of one project (cached snapshot) |
mcp__projects-meta__knowledge_search |
query; opt domain, limit |
Shared-wiki search; auto-detects domain from cwd, pass domain="all" to disable |
mcp__projects-meta__knowledge_get |
slug |
Full text of one wiki page (e.g. packages/projects-meta-mcp) |
mcp__projects-meta__knowledge_suggest_promote |
— | Local .wiki/concepts/ candidates for shared-wiki promotion |
mcp__projects-meta__meta_status |
— | Sync diagnostics: cache age, project count, error count, page count |
Mutation tools (need write:repository Gitea scope; preview → confirm)
| Tool | Required args | Effect |
|---|---|---|
mcp__projects-meta__tasks_create |
target_project, slug, description, next_action (+ opt where_stopped, status, blocker, branch, source_project) |
Append block to <target>/.tasks/STATUS.md via Gitea commit |
mcp__projects-meta__tasks_update |
target_project, slug + ≥1 of where_stopped / next_action / blocker / branch / description / status |
Sha-based optimistic lock; 422 on conflict |
mcp__projects-meta__tasks_close |
target_project, slug (+ opt note) |
Sets task to 🟢 done; appends identity-footer |
mcp__projects-meta__knowledge_ingest |
target_project, type, slug, body (+ opt frontmatter, source_project) |
Three commits: <type>/<slug>.md + index.md + log.md. type ∈ entities / concepts / packages / sources / raw |
mcp__projects-meta__knowledge_promote |
target_project, slug, body (+ opt frontmatter, source_project) |
Move raw/<slug>.md → sources/<slug>.md with auto raw_path link |
target_project is either a Gitea repo name, or _meta (the dedicated meta-tasks / meta-wiki repos from auth.toml).
Examples
Read example: cross-project status
User: "что у меня на досках?"
1. mcp__projects-meta__tasks_aggregate
→ 7 projects, 12 active tasks
2. Group by project, summarize 1 line per active task.
Cite project name; if a task is stale (cache age > 1h), flag it.
Read example: shared wiki query
User: "есть ли в общей вики что-то про setup-using паттерн?"
1. mcp__projects-meta__knowledge_search
query: "setup-using skill pair pattern"
domain: "all"
→ hits include concepts/setup-using-skill-pair
2. mcp__projects-meta__knowledge_get
slug: "concepts/setup-using-skill-pair"
→ full text
3. Summarize, link with markdown to the slug.
Mutation example: create cross-project task
User: "заведи в проекте books задачу на миграцию settings.json"
1. mcp__projects-meta__tasks_create
target_project: "books"
slug: "settings-json-migration"
description: "<...>"
next_action: "<...>"
(no `confirm`)
→ preview: proposed STATUS.md diff + commit message
2. Show preview to user.
3. User: "ok, go"
4. mcp__projects-meta__tasks_create
(same args + confirm: true)
→ committed to Gitea
Mutation example: closing a cross-project task
User: "close [projects-meta-skills] in claude-skills"
1. mcp__projects-meta__tasks_close
target_project: "claude-skills"
slug: "projects-meta-skills"
note: "<one-line summary>"
(no `confirm`)
→ preview
2. User confirms.
3. Re-call with confirm: true.
Common mistakes
| Mistake | Fix |
|---|---|
Reading current project's tasks via tasks_get instead of disk |
Read .tasks/STATUS.md directly. MCP is for other projects. |
Inlining confirm: true on the first mutation call |
Always preview first; show user; only then confirm: true. |
Using knowledge_search for the project's own wiki |
The shared wiki is a separate Gitea repo. Local .wiki/ is in cwd. |
Acting on a stale tasks_aggregate without checking meta_status |
Step 0 — Freshness gate is mandatory. If cache_age_minutes > 10 (or errors > 0), run node ~/projects/.common/lib/projects-meta-mcp/dist/sync.js first. |
Skipping git -C ~/projects/projects-wiki pull before knowledge_ingest / knowledge_promote |
sha-based optimistic lock will reject the commit (422) and the failure is opaque. Pull is unconditional for shared-wiki writes — fast-forward is a no-op when current. |
| Treating sync 401/403 as "MCP is fine, the page just doesn't exist yet" | 401/403 means the Gitea token is dead. Stop, tell the user to rotate gitea_token in ~/.config/projects-mcp/auth.toml. Never guess on stale data. |
Calling knowledge_ingest with the wrong type |
type must be one of entities / concepts / packages / sources / raw. Mis-typed pages land in the wrong section and break index.md. |
Vague knowledge_search queries ("auth", "config") |
Specific multi-word queries return targeted snippets; vague ones return noise. |
Forgetting domain="all" when searching across families |
Default domain is auto-detected from cwd; use "all" if the wiki page lives in a different family. |
Red flags
- "I'll just commit it directly" → no. Mutation tools have a preview step for a reason — silent writes to another repo are a recipe for drift.
- "The cache is fresh enough" → run Step 0. The 10-minute window is the threshold; below it skip sync, above it sync. Don't eyeball this — the bus moves fast in cross-machine sessions.
- "I'll skip the pull, my last write was 30 seconds ago" → another machine pushed in between. Always pull before shared-wiki writes; the sha-lock check is your only safety net.
- "I'll skip the wiki page" → if you're answering a cross-cutting question and there's no wiki page, that's a
knowledge_ingestcandidate. Surface it to the user.