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:
98
skills/setup-projects-meta/README.md
Normal file
98
skills/setup-projects-meta/README.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# setup-projects-meta
|
||||
|
||||
One-time skill that brings up the local `projects-meta-mcp` stdio server on a
|
||||
new (or freshly broken) machine. Clones the server repo, builds it, writes
|
||||
`~/.config/projects-mcp/auth.toml` with the user's Gitea token, clones the
|
||||
shared wiki to `~/projects/projects-wiki/.wiki`, and registers `mcpServers.projects-meta`
|
||||
in `~/.claude.json`.
|
||||
|
||||
The runtime policy for *using* the resulting tools lives in
|
||||
[`using-projects-meta`](../using-projects-meta/) — `setup-projects-meta` is the
|
||||
only place that touches user-level config or installs the server.
|
||||
|
||||
`projects-meta-mcp` reference (full):
|
||||
`mcp__projects-meta__knowledge_get slug=packages/projects-meta-mcp`
|
||||
|
||||
## When it triggers
|
||||
|
||||
- User says: "install projects-meta", "set up projects-meta", "configure projects-meta",
|
||||
"настрой projects-meta", "установи projects-meta", "projects-meta не работает",
|
||||
"projects-meta isn't working".
|
||||
- [`using-projects-meta`](../using-projects-meta/) detects missing
|
||||
`mcp__projects-meta__*` tools and delegates here via its Prerequisites
|
||||
section.
|
||||
- A new machine in the multi-machine fleet — install once per machine.
|
||||
|
||||
## What it installs
|
||||
|
||||
| Path | Role |
|
||||
|---|---|
|
||||
| `~/.local/projects-meta-mcp/` | server repo (cloned from Gitea) |
|
||||
| `~/.local/projects-meta-mcp/dist/server.js` | built stdio entry point |
|
||||
| `~/.config/projects-mcp/auth.toml` | Gitea credentials (token-bearing) |
|
||||
| `~/.cache/projects-mcp/tasks.json` | aggregated tasks cache |
|
||||
| `~/projects/projects-wiki/` | shared wiki clone root (Gitea repo `projects-wiki`) |
|
||||
| `~/projects/projects-wiki/.wiki/` | wiki content root (read by MCP server) |
|
||||
| `~/.claude.json` (`mcpServers.projects-meta`) | MCP registration |
|
||||
|
||||
## Hard rules
|
||||
|
||||
- **Never auto-mutate.** Phase 1 (discovery) and Phase 2 (plan) always pause
|
||||
for explicit confirmation. A trigger phrase grants permission to inspect,
|
||||
not to clone or write secrets.
|
||||
- **Never echo the Gitea token in chat.** Edit / Write tool calls inevitably
|
||||
contain it (that's how it lands in `auth.toml`); chat output must not.
|
||||
- **Never clone over an unrelated `~/projects/projects-wiki/` (or legacy `~/projects/.wiki`).**
|
||||
If either path exists with a non-matching `origin`, stop and ask — the user
|
||||
may have an unrelated wiki there.
|
||||
- **Don't use the legacy `~/projects/.wiki` path.** It's deprecated — the MCP
|
||||
server's `loadWiki` reads from `~/projects/projects-wiki/.wiki/<type>/...`,
|
||||
while writes to `~/projects/.wiki/.wiki/...` would be invisible. Phase 4
|
||||
detects a legacy clone and migrates to the canon path.
|
||||
- **Always `chmod 600` `auth.toml` on Linux / macOS.** Token leak otherwise.
|
||||
|
||||
## Procedure (high-level)
|
||||
|
||||
1. **Phase 0** — environment sanity (Node ≥ 18, git, npm, network to Gitea).
|
||||
2. **Phase 1** — discovery (token / repo / wiki clone / MCP registration / cache).
|
||||
3. **Phase 2** — plan + confirm. Wait for explicit "ok"/"go"/"поехали".
|
||||
4. **Phase 3** — backup (`~/.claude.json`, existing `auth.toml`).
|
||||
5. **Phase 4** — clone / pull repo + `npm install && npm run build`; clone
|
||||
shared wiki if absent.
|
||||
6. **Phase 5** — write `~/.config/projects-mcp/auth.toml` with `gitea_token`.
|
||||
7. **Phase 6** — register `mcpServers.projects-meta` in `~/.claude.json` with
|
||||
absolute path to `dist/server.js`.
|
||||
8. **Phase 7** — smoke test (`mcp__projects-meta__meta_status`) + `node dist/sync.js`
|
||||
to populate the cache.
|
||||
9. **Phase 8** — restart guidance + final report.
|
||||
|
||||
Full procedure with shell snippets and templates lives in [`SKILL.md`](SKILL.md).
|
||||
|
||||
## Rollback
|
||||
|
||||
1. Stop. Don't fix forward.
|
||||
2. `cp <file>.bak-<ts> <file>` for `~/.claude.json` and `~/.config/projects-mcp/auth.toml`.
|
||||
3. Optional: `rm -rf ~/.local/projects-meta-mcp` and `rm -rf ~/.cache/projects-mcp`.
|
||||
Keep `~/projects/projects-wiki/` — it's a useful clone regardless of MCP state.
|
||||
4. Restart Claude Code.
|
||||
5. Confirm `mcp__projects-meta__*` tools are gone (or back to the prior version).
|
||||
|
||||
## Install
|
||||
|
||||
From the repo root:
|
||||
|
||||
```bash
|
||||
bash scripts/install.sh setup-projects-meta
|
||||
```
|
||||
|
||||
Works on Windows under git-bash, Linux, macOS.
|
||||
|
||||
## See also
|
||||
|
||||
- [`using-projects-meta`](../using-projects-meta/) — runtime policy for
|
||||
cross-project task aggregation and shared-wiki query / ingest.
|
||||
- [`setup-context7`](../setup-context7/) — companion pattern for the context7
|
||||
MCP plugin (similar 8-phase shape).
|
||||
- [`setup-wiki`](../setup-wiki/), [`setup-tasks`](../setup-tasks/) —
|
||||
per-project setup skills (in-repo `.wiki/` and `.tasks/`); orthogonal to
|
||||
this skill, which sets up the cross-project layer.
|
||||
247
skills/setup-projects-meta/SKILL.md
Normal file
247
skills/setup-projects-meta/SKILL.md
Normal file
@@ -0,0 +1,247 @@
|
||||
---
|
||||
name: setup-projects-meta
|
||||
version: 1.0.0
|
||||
description: Installs and configures the local `projects-meta-mcp` stdio server — clones the repo to `~/.local/projects-meta-mcp`, builds it, writes `~/.config/projects-mcp/auth.toml` with the user's Gitea token, clones the shared wiki to `~/projects/projects-wiki/` (content lives at `~/projects/projects-wiki/.wiki/`), and registers `mcpServers.projects-meta` in `~/.claude.json`. Use this skill when the user says "install projects-meta", "set up projects-meta", "configure projects-meta", "настрой projects-meta", "установи projects-meta", "projects-meta не работает", "projects-meta isn't working", or whenever the `mcp__projects-meta__*` tools are missing in a session that needs cross-project task aggregation or the shared Gitea wiki. Cross-platform — Windows / Linux / macOS. Mutates user-level config and writes secrets; pauses for confirmation before every write. Includes a migration step for machines with an old `~/projects/.wiki` clone (deprecated path that caused the wiki-path-mismatch bug).
|
||||
---
|
||||
|
||||
# setup-projects-meta
|
||||
|
||||
> One-time skill that gets the local `projects-meta-mcp` server running with the user's Gitea credentials. Stops at confirmation gates because the procedure clones a repo, writes a secret-bearing TOML file, and edits `~/.claude.json`.
|
||||
|
||||
Reference: full `projects-meta-mcp` docs live in the shared wiki at `packages/projects-meta-mcp` (fetch via `mcp__projects-meta__knowledge_get` once the server is up).
|
||||
|
||||
## When to use
|
||||
|
||||
- User explicitly asks: install / set up / configure projects-meta.
|
||||
- A `using-projects-meta`-driven task fails because `mcp__projects-meta__*` tools aren't available.
|
||||
- Migrating a stale install (token expired, repo moved, broken cache) — same procedure, Phase 1 detects what's already in place.
|
||||
- New machine in the user's multi-machine fleet (recall: this is a cross-machine workflow).
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Issuing or rotating Gitea tokens. This skill *uses* a token the user already has; if there's no token, point them at Gitea's settings page (`https://git.kzntsv.site/user/settings/applications`) and stop until they paste one.
|
||||
- Running `projects-meta-mcp` itself (the MCP harness spawns it).
|
||||
- Editing `.tasks/STATUS.md` or wiki content — that's `using-projects-meta` / `using-tasks` / `using-wiki`.
|
||||
- Any other MCP server.
|
||||
|
||||
## Hard rule: don't auto-mutate config
|
||||
|
||||
The procedure clones a repo, writes `~/.config/projects-mcp/auth.toml` (carries the Gitea token), and edits `~/.claude.json`. **Always pause for explicit confirmation between Phase 1 (discovery, read-only) and Phase 2 (plan), and again before Phase 3 (backup + writes).** A trigger phrase is permission to run discovery, not permission to clone or write secrets.
|
||||
|
||||
## Procedure
|
||||
|
||||
### Phase 0 — Environment sanity
|
||||
|
||||
- Confirm Claude Code is the current harness (need `mcpServers` registration in `~/.claude.json`).
|
||||
- Confirm `git`, `node`, `npm` are on `PATH`. Node ≥ 18 (the server uses ES modules).
|
||||
- Confirm network reachability to `https://git.kzntsv.site` (the Gitea host). On HTTP 401/403 later, the token is dead — stop and ask for a new one.
|
||||
- Pick paths: `~/.local/projects-meta-mcp`, `~/.config/projects-mcp/`, `~/.cache/projects-mcp/`, `~/projects/projects-wiki/` (clone root; content at `~/projects/projects-wiki/.wiki/`). POSIX-style `~/...` resolves correctly under git-bash on Windows.
|
||||
|
||||
**Path note (canon vs legacy).** The shared wiki clone target is `~/projects/projects-wiki/` (content under `.wiki/`). Earlier README versions said `git clone … ~/projects/.wiki` — that path is **deprecated** because it caused a write/read mismatch (writer wrote to `<clone>/.wiki/<type>/<slug>.md`, reader walked `<clone>/<type>/...`). Phase 1 detects the legacy path and Phase 4 migrates.
|
||||
|
||||
### Phase 1 — Discovery (read-only)
|
||||
|
||||
Search, in order. Report only "found at <path>", never echo token values.
|
||||
|
||||
**Existing Gitea token.** Look in priority order:
|
||||
|
||||
1. `~/.config/projects-mcp/auth.toml` → `gitea_token = "..."`
|
||||
2. Env var `PROJECTS_META_GITEA_TOKEN`
|
||||
3. Existing `~/.claude.json` → `mcpServers.projects-meta` block (rare; legacy installs sometimes inline `env.GITEA_TOKEN`)
|
||||
|
||||
The first hit wins. Capture internally for Phase 5; **never echo it in chat**.
|
||||
|
||||
**Repo install state.** Check whether `~/.local/projects-meta-mcp/.git` exists. If yes, `git -C ~/.local/projects-meta-mcp rev-parse HEAD` → record the SHA so Phase 4 can decide *clone* vs *pull*.
|
||||
|
||||
**Build artifact.** Check `~/.local/projects-meta-mcp/dist/server.js`. If absent, Phase 4 will run `npm install && npm run build`.
|
||||
|
||||
**Shared wiki clone.** Three states to detect:
|
||||
|
||||
1. **Canon clone present** — `~/projects/projects-wiki/.git` exists, `git -C ~/projects/projects-wiki remote get-url origin` matches `https://git.kzntsv.site/OpeItcLoc03/projects-wiki(.git)?`. Phase 4 just `git pull`s.
|
||||
2. **Legacy clone present** — `~/projects/.wiki/.git` exists with the right `origin`. The path is deprecated (caused the wiki-path-mismatch bug). Phase 4 will migrate: re-clone to `~/projects/projects-wiki/`, then offer to `rm -rf ~/projects/.wiki` once the user confirms there are no local commits or scratch files in there.
|
||||
3. **Either path exists with a non-matching `origin`** — stop and ask. The user may have an unrelated wiki there.
|
||||
|
||||
If neither path exists — Phase 4 clones fresh into `~/projects/projects-wiki/`.
|
||||
|
||||
**MCP registration.** Read `~/.claude.json` and check `mcpServers.projects-meta`. Note the command + args. If args point at a stale path, Phase 6 will fix it.
|
||||
|
||||
**Cache state.** List `~/.cache/projects-mcp/` (if it exists). Just for the report — don't rely on it.
|
||||
|
||||
### Phase 2 — Plan + confirm
|
||||
|
||||
Present a single-block plan to the user:
|
||||
|
||||
```
|
||||
Token: <found at <path> | NOT FOUND — will ask>
|
||||
Repo: <installed at ~/.local/projects-meta-mcp@<sha> | will clone>
|
||||
Build artifact: <present | will run npm install && npm run build>
|
||||
Wiki clone: <canon at ~/projects/projects-wiki | LEGACY at ~/projects/.wiki — will migrate | will clone | wrong remote — STOP>
|
||||
MCP entry: <present in ~/.claude.json | will add | will fix path>
|
||||
Backups: ~/.claude.json.bak-<ts>, ~/.config/projects-mcp/auth.toml.bak-<ts> (if exists)
|
||||
```
|
||||
|
||||
Wait for explicit confirmation ("ok", "go", "поехали"). Anything else → stop.
|
||||
|
||||
If no token was found in Phase 1 — first ask: "Paste a Gitea personal access token (scope: `read:repository` for read-only, `write:repository` to enable mutations), or open `https://git.kzntsv.site/user/settings/applications` to create one." Don't proceed past Phase 2 without a token.
|
||||
|
||||
### Phase 3 — Backup
|
||||
|
||||
Copy each file we will modify to `<file>.bak-YYYYMMDD-HHMMSS`:
|
||||
|
||||
```bash
|
||||
TS=$(date +%Y%m%d-%H%M%S)
|
||||
[ -f ~/.claude.json ] && cp ~/.claude.json ~/.claude.json.bak-$TS
|
||||
[ -f ~/.config/projects-mcp/auth.toml ] && cp ~/.config/projects-mcp/auth.toml ~/.config/projects-mcp/auth.toml.bak-$TS
|
||||
```
|
||||
|
||||
Confirm both backups exist (when their source existed) before any further edit. The repo and wiki clones don't need backup — git is the backup.
|
||||
|
||||
### Phase 4 — Clone + build
|
||||
|
||||
```bash
|
||||
# Server
|
||||
if [ -d ~/.local/projects-meta-mcp/.git ]; then
|
||||
git -C ~/.local/projects-meta-mcp pull --ff-only
|
||||
else
|
||||
git clone https://git.kzntsv.site/OpeItcLoc03/projects-meta-mcp ~/.local/projects-meta-mcp
|
||||
fi
|
||||
cd ~/.local/projects-meta-mcp
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# Shared wiki — canon path is ~/projects/projects-wiki/ (content under .wiki/)
|
||||
mkdir -p ~/projects
|
||||
if [ -d ~/projects/projects-wiki/.git ]; then
|
||||
git -C ~/projects/projects-wiki pull --ff-only
|
||||
elif [ -d ~/projects/.wiki/.git ]; then
|
||||
# Legacy path — re-clone to canon and let the user decide what to do with the old dir.
|
||||
git clone https://git.kzntsv.site/OpeItcLoc03/projects-wiki ~/projects/projects-wiki
|
||||
echo "Legacy clone at ~/projects/.wiki kept in place. Inspect for local changes; if clean, rm -rf it."
|
||||
else
|
||||
git clone https://git.kzntsv.site/OpeItcLoc03/projects-wiki ~/projects/projects-wiki
|
||||
fi
|
||||
```
|
||||
|
||||
Verify `~/.local/projects-meta-mcp/dist/server.js` exists after build. If not — abort, the build failed; ask the user to run `npm run build` manually and paste the output.
|
||||
|
||||
### Phase 5 — Write `auth.toml`
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.config/projects-mcp
|
||||
```
|
||||
|
||||
If `~/.config/projects-mcp/auth.toml` already exists and Phase 1 found a valid `gitea_token` line — skip the write. Otherwise, write the file with the token captured in Phase 1 (or freshly pasted in Phase 2):
|
||||
|
||||
```toml
|
||||
gitea_url = "https://git.kzntsv.site"
|
||||
gitea_user = "OpeItcLoc03"
|
||||
gitea_token = "<TOKEN>"
|
||||
# meta_tasks_repo = "projects-tasks" # uncomment to override default
|
||||
# meta_wiki_repo = "projects-wiki" # uncomment to override default
|
||||
```
|
||||
|
||||
Permissions: on Linux / macOS run `chmod 600 ~/.config/projects-mcp/auth.toml`. On Windows the default ACL is per-user, no extra step.
|
||||
|
||||
### Phase 6 — Register in `~/.claude.json`
|
||||
|
||||
Edit `~/.claude.json`. Add or update the `mcpServers.projects-meta` block:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"projects-meta": {
|
||||
"command": "node",
|
||||
"args": ["<ABSOLUTE_PATH_TO>/dist/server.js"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Absolute path resolution:
|
||||
|
||||
| Platform | `<ABSOLUTE_PATH_TO>` |
|
||||
|---|---|
|
||||
| Windows | `C:/Users/<USER>/.local/projects-meta-mcp` (forward slashes; works in JSON without escaping) |
|
||||
| Linux | `/home/<USER>/.local/projects-meta-mcp` |
|
||||
| macOS | `/Users/<USER>/.local/projects-meta-mcp` |
|
||||
|
||||
After each edit, validate JSON:
|
||||
|
||||
```bash
|
||||
# Windows (git-bash)
|
||||
powershell.exe -NoProfile -c "Get-Content '<file>' -Raw | ConvertFrom-Json | Out-Null"
|
||||
# Linux / macOS
|
||||
jq empty <file>
|
||||
# fallback
|
||||
python -c "import json; json.load(open('<file>'))"
|
||||
```
|
||||
|
||||
If validation fails → restore from `.bak-*` and abort.
|
||||
|
||||
### Phase 7 — Smoke test (best-effort) + run initial sync
|
||||
|
||||
Best-effort: call `mcp__projects-meta__meta_status`. If it returns a JSON blob with `synced_at` / `wiki_pages_count` — the server is reachable in *this* session.
|
||||
|
||||
Then run a one-shot sync to populate the cache:
|
||||
|
||||
```bash
|
||||
cd ~/.local/projects-meta-mcp
|
||||
node dist/sync.js
|
||||
```
|
||||
|
||||
Expect a non-zero `projects_count` and a fresh `~/.cache/projects-mcp/tasks.json`. On 401 / 403 → token is wrong scope or expired; rotate via `https://git.kzntsv.site/user/settings/applications` and re-edit `auth.toml`.
|
||||
|
||||
**Important caveat to relay to the user:** in the *same* session that just ran setup, the MCP server you're talking to is whatever was bound at session start. So a passing `meta_status` only proves "some projects-meta is alive" — not "the registration we just wrote is what's serving it". The real test is after Claude Code restart.
|
||||
|
||||
### Phase 8 — Restart guidance + final report
|
||||
|
||||
Tell the user:
|
||||
|
||||
```
|
||||
✅ Setup complete. Restart Claude Code so the new mcpServers.projects-meta
|
||||
registration binds to a fresh stdio session.
|
||||
|
||||
After restart:
|
||||
• mcp__projects-meta__* tools serve from ~/.local/projects-meta-mcp/dist/server.js
|
||||
• Cache lives at ~/.cache/projects-mcp/tasks.json (refresh: node dist/sync.js)
|
||||
• Shared wiki clone at ~/projects/projects-wiki/ (content at .wiki/) — `git -C ~/projects/projects-wiki pull --ff-only` for fresh anchors
|
||||
• Backups saved at ~/.claude.json.bak-<ts> (and auth.toml.bak-<ts> if it existed before)
|
||||
|
||||
If something breaks after restart:
|
||||
• Restore from .bak-* and tell me — we'll roll back together.
|
||||
```
|
||||
|
||||
## Rollback procedure
|
||||
|
||||
If a problem surfaces (now or after restart):
|
||||
|
||||
1. Stop. Don't try to fix forward.
|
||||
2. Find the most recent `.bak-YYYYMMDD-HHMMSS` next to `~/.claude.json` (and `~/.config/projects-mcp/auth.toml` if applicable).
|
||||
3. `cp <file>.bak-<ts> <file>` for each.
|
||||
4. Optional: `rm -rf ~/.local/projects-meta-mcp` and `rm -rf ~/.cache/projects-mcp`. Keep `~/projects/projects-wiki/` — it's a useful clone regardless of MCP state.
|
||||
5. Restart Claude Code.
|
||||
6. Confirm `mcp__projects-meta__*` is gone (or back to the pre-existing version).
|
||||
7. Report what went wrong so we can fix the procedure.
|
||||
|
||||
## Cross-platform notes
|
||||
|
||||
The procedure is platform-agnostic. Only auxiliary tooling differs:
|
||||
|
||||
| | JSON validate | Backup | Permissions on auth.toml |
|
||||
|---|---|---|---|
|
||||
| Windows (git-bash) | `powershell.exe -NoProfile -c "Get-Content '<f>' -Raw \| ConvertFrom-Json \| Out-Null"` | `cp` | per-user ACL by default |
|
||||
| Linux | `jq empty <f>` (or `python -c "import json; json.load(open('<f>'))"`) | `cp` | `chmod 600` |
|
||||
| macOS | same as Linux | `cp` | `chmod 600` |
|
||||
|
||||
Path forms (`~/.local/...`, `~/.config/...`, `~/projects/...`) are identical on all three.
|
||||
|
||||
## Common mistakes
|
||||
|
||||
- **Skipping Phase 1.** "User just said 'install projects-meta' — let's go." No — find existing token / repo / wiki first; re-cloning over an existing install loses any local commits in the wiki.
|
||||
- **Echoing the token.** It's a secret. Edit / Write tool calls inevitably contain it (that's how it gets into `auth.toml`), but no chat output should.
|
||||
- **Cloning over an unrelated `~/projects/projects-wiki/` (or legacy `~/projects/.wiki`).** If either path exists with a different `origin`, stop. The user may have an unrelated wiki there.
|
||||
- **Cloning to the legacy path `~/projects/.wiki`.** Path is deprecated — write/read mismatch bug. Always clone to `~/projects/projects-wiki/`. Phase 4 enforces this.
|
||||
- **Writing `auth.toml` with `0644` perms on Linux/macOS.** Token leak. Always `chmod 600` after write.
|
||||
- **Treating in-session `meta_status` as proof.** Same as the context7 caveat — the active MCP connection was bound at session start.
|
||||
- **Auto-running on every "use projects-meta".** This skill is intrusive. Trigger only on explicit "install/setup/configure projects-meta", or when MCP tools are missing and the user is blocked.
|
||||
- **Forgetting `node dist/sync.js`.** Without an initial sync, the cache is empty and `tasks_aggregate` returns nothing — the user thinks setup failed.
|
||||
Reference in New Issue
Block a user