feat(skills): add setup-projects-meta + using-projects-meta pair
Wraps the local projects-meta-mcp stdio server with the validated split-pair pattern (setup-X / using-X), 4th application after context7 / wiki / tasks. setup-projects-meta — 8-phase install: clones server repo to ~/.local/projects-meta-mcp, builds, writes ~/.config/projects-mcp/auth.toml, clones shared wiki to ~/projects/projects-wiki/ (canon path; legacy ~/projects/.wiki is detected and migrated — old path caused the wiki-path-mismatch bug, fixed upstream in 621a69f), registers mcpServers.projects-meta in ~/.claude.json. Confirmation gates between discovery and writes. using-projects-meta — runtime policy: read tools (tasks_aggregate, knowledge_search, meta_status, ...) and mutation tools with mandatory two-step preview→confirm. Carries the local-first rule inline: for the current project read .tasks/ / .wiki/ from disk; MCP cache is for *other* projects only. Wiki concept page concepts/projects-meta-skills.md documents the design, the path-canon fix, and the round-trip task lifecycle across machines. Closes [projects-meta-skills] in claude-skills (created from DESKTOP-NSEF0UK via projects-meta-mcp). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
144
skills/using-projects-meta/README.md
Normal file
144
skills/using-projects-meta/README.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# using-projects-meta
|
||||
|
||||
Runtime policy for the local `projects-meta-mcp` stdio server. Two
|
||||
responsibilities, one server:
|
||||
|
||||
1. **Cross-project task aggregation** — reads / writes `.tasks/STATUS.md` in
|
||||
any of the user's Gitea repos.
|
||||
2. **Shared knowledge wiki** — query / ingest a single Gitea-backed wiki at
|
||||
`~/projects/projects-wiki/.wiki/` (clone root: `~/projects/projects-wiki/`,
|
||||
Gitea repo: `projects-wiki`).
|
||||
|
||||
`using-projects-meta` governs *usage* of an installed server. Initial setup
|
||||
(clone, build, `auth.toml`, MCP registration) is owned by
|
||||
[`setup-projects-meta`](../setup-projects-meta/).
|
||||
|
||||
Full server reference:
|
||||
`mcp__projects-meta__knowledge_get slug=packages/projects-meta-mcp`.
|
||||
|
||||
## When it triggers
|
||||
|
||||
- User asks for cross-project state ("what's on the boards", "across all
|
||||
projects", "что у меня на досках", "по всем проектам").
|
||||
- User wants to query / ingest the shared wiki ("check shared wiki", "search
|
||||
projects-wiki", "ingest into shared wiki", "общая вики", "заингесть в общую").
|
||||
- User wants to create / update / close a task in *another* project from the
|
||||
current cwd ("заведи в проекте X задачу", "close task Y in project Z").
|
||||
- User asks for sync diagnostics ("when did the cache last refresh", "are there
|
||||
sync errors").
|
||||
- If `mcp__projects-meta__*` tools are missing, this skill delegates to
|
||||
[`setup-projects-meta`](../setup-projects-meta/) before doing anything else.
|
||||
|
||||
## Local-first rule (critical)
|
||||
|
||||
For the **current** project — read disk directly (`.tasks/STATUS.md`,
|
||||
`.wiki/index.md`). The MCP cache:
|
||||
|
||||
- May be stale (sync runs only when triggered).
|
||||
- Hides `🟢 done` by default.
|
||||
- May not contain unpushed projects.
|
||||
|
||||
Use MCP only for **other** projects, **other** machines, or the **shared**
|
||||
wiki content. See the table below.
|
||||
|
||||
| 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 X?" | local `.wiki/index.md` |
|
||||
| "Has the **shared** wiki got X?" | `mcp__projects-meta__knowledge_search` |
|
||||
| "Sync state across machines?" | `mcp__projects-meta__meta_status` |
|
||||
|
||||
## Two operation classes
|
||||
|
||||
### Read (no confirmation)
|
||||
|
||||
`tasks_aggregate`, `tasks_search`, `tasks_get`, `knowledge_search`,
|
||||
`knowledge_get`, `knowledge_suggest_promote`, `meta_status` — all
|
||||
side-effect-free. Call directly, cite the result.
|
||||
|
||||
### Mutate (always two-step)
|
||||
|
||||
`tasks_create`, `tasks_update`, `tasks_close`, `knowledge_ingest`,
|
||||
`knowledge_promote` — write to Gitea. Procedure:
|
||||
|
||||
1. Call **without** `confirm: true` → returns dry-run preview (proposed file
|
||||
diff + commit message).
|
||||
2. Show the preview to the user. Wait for explicit "ok" / "go" / "поехали".
|
||||
3. Re-call with `confirm: true` → committed.
|
||||
|
||||
**Never inline `confirm: true` on the first call.** A trigger phrase is
|
||||
permission to plan, not to commit.
|
||||
|
||||
## Tool quick reference
|
||||
|
||||
### Read
|
||||
|
||||
| Tool | Required args | Purpose |
|
||||
|---|---|---|
|
||||
| `mcp__projects-meta__tasks_aggregate` | — | All active tasks across 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 (cache snapshot) |
|
||||
| `mcp__projects-meta__knowledge_search` | `query`; opt `domain`, `limit` | Shared-wiki search; default domain auto-detected from cwd |
|
||||
| `mcp__projects-meta__knowledge_get` | `slug` | Full text of one wiki page |
|
||||
| `mcp__projects-meta__knowledge_suggest_promote` | — | Local `.wiki/concepts/` candidates for shared promotion |
|
||||
| `mcp__projects-meta__meta_status` | — | Sync diagnostics (cache age, project / page / error counts) |
|
||||
|
||||
### Mutate (need `write:repository` Gitea scope)
|
||||
|
||||
| Tool | Required args | Effect |
|
||||
|---|---|---|
|
||||
| `mcp__projects-meta__tasks_create` | `target_project`, `slug`, `description`, `next_action` | Append block to target's `.tasks/STATUS.md` via Gitea commit |
|
||||
| `mcp__projects-meta__tasks_update` | `target_project`, `slug` + ≥1 mutable field | Sha-based optimistic lock; 422 on conflict |
|
||||
| `mcp__projects-meta__tasks_close` | `target_project`, `slug` (+ opt `note`) | Marks task 🟢 done with identity-footer |
|
||||
| `mcp__projects-meta__knowledge_ingest` | `target_project`, `type`, `slug`, `body` | Three commits: `<type>/<slug>.md` + `index.md` + `log.md` |
|
||||
| `mcp__projects-meta__knowledge_promote` | `target_project`, `slug`, `body` | Move `raw/<slug>.md` → `sources/<slug>.md` |
|
||||
|
||||
`type` ∈ `entities` / `concepts` / `packages` / `sources` / `raw`.
|
||||
`target_project` = Gitea repo name, or `_meta` (meta-tasks / meta-wiki repos
|
||||
from `auth.toml`).
|
||||
|
||||
## Common mistakes
|
||||
|
||||
- **Reading current project's tasks via `tasks_get`.** Read `.tasks/STATUS.md`
|
||||
on disk; the MCP cache is for *other* projects.
|
||||
- **Inlining `confirm: true` on first call.** Always preview first; show user;
|
||||
only then `confirm: true`.
|
||||
- **Confusing the local `.wiki/` with the shared `projects-wiki`.** They are
|
||||
two different stores. `using-wiki` operates on the local one;
|
||||
`using-projects-meta` queries / ingests the shared one.
|
||||
- **Acting on stale `tasks_aggregate`.** If `meta_status.age_seconds` > 3600,
|
||||
either run `node dist/sync.js` (in `~/.local/projects-meta-mcp`) or warn the
|
||||
user about staleness.
|
||||
- **Vague `knowledge_search` queries.** "auth" returns noise. Multi-word,
|
||||
specific queries return targeted snippets.
|
||||
- **Wrong `type` on `knowledge_ingest`.** Mis-typed pages land in the wrong
|
||||
section and break `index.md`. Pick from the five canonical types.
|
||||
|
||||
## When NOT to use
|
||||
|
||||
- The current project's own tasks — read `.tasks/STATUS.md`.
|
||||
- The current project's own wiki — read `.wiki/`.
|
||||
- Library / framework documentation — that's [`using-context7`](../using-context7/).
|
||||
- Repo-internal code search — that's `Glob` / `Grep`.
|
||||
- One-off git history questions — `git log`.
|
||||
|
||||
## Install
|
||||
|
||||
From the repo root:
|
||||
|
||||
```bash
|
||||
bash scripts/install.sh using-projects-meta
|
||||
```
|
||||
|
||||
Works on Windows under git-bash, Linux, macOS.
|
||||
|
||||
## See also
|
||||
|
||||
- [`setup-projects-meta`](../setup-projects-meta/) — companion, owns server
|
||||
install + MCP registration.
|
||||
- [`using-context7`](../using-context7/) — sister skill for library docs (same
|
||||
using-X structure).
|
||||
- [`using-tasks`](../using-tasks/), [`using-wiki`](../using-wiki/) —
|
||||
per-project policies for in-repo `.tasks/` and `.wiki/`. Orthogonal to this
|
||||
skill; together they cover both per-project and cross-project state.
|
||||
192
skills/using-projects-meta/SKILL.md
Normal file
192
skills/using-projects-meta/SKILL.md
Normal file
@@ -0,0 +1,192 @@
|
||||
---
|
||||
name: using-projects-meta
|
||||
version: 1.0.0
|
||||
description: 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. Mutation tools (`tasks_create`, `tasks_update`, `tasks_close`, `knowledge_ingest`, `knowledge_promote`) require two-step preview → confirm. Skip for the **current** project's tasks/wiki — those live on disk in `.tasks/` / `.wiki/` and are read directly.
|
||||
---
|
||||
|
||||
# Using the projects-meta MCP server
|
||||
|
||||
## Overview
|
||||
|
||||
`projects-meta-mcp` is a local stdio MCP server. Two responsibilities:
|
||||
|
||||
1. **Cross-project task aggregation** — parses `.tasks/STATUS.md` from 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.
|
||||
2. **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_get` for queries, `knowledge_ingest` + `knowledge_promote` for 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.md` from 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>.md` and `.wiki/<page>.md` are always closer.
|
||||
- One-off questions answered by `git log` or a single file.
|
||||
- Library / framework documentation — that's `using-context7`.
|
||||
- Code search — that's `Glob` / `Grep`.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Read (no confirmation needed)
|
||||
|
||||
```
|
||||
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)
|
||||
|
||||
```
|
||||
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` | If `age_seconds` > 3600 the cache may be behind reality. Either run `node dist/sync.js` or warn the user. |
|
||||
| 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" → check `meta_status.age_seconds`. If it's >3600s and the user is about to act on the data, sync first.
|
||||
- "I'll skip the wiki page" → if you're answering a cross-cutting question and there's no wiki page, that's a `knowledge_ingest` candidate. Surface it to the user.
|
||||
Reference in New Issue
Block a user