From 9d7d25223c257a3e4f175fa1e9fe4f4afac96630 Mon Sep 17 00:00:00 2001 From: vitya Date: Tue, 28 Apr 2026 11:56:22 +0300 Subject: [PATCH] feat: setup-context7 skill + using-context7 prerequisites pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split context7 concerns into two skills: - using-context7 (policy, every-time): when to call, how to query well - setup-context7 (infrastructure, one-time): install plugin, inject API key, clean manual MCP entries, with confirmation gates setup-context7 reuses an existing CONTEXT7_API_KEY by searching, in order: ~/.claude/settings.json → ~/.claude.json (top-level + project-scoped) → ~/.claude/settings.local.json → env. Asks the user only if nothing found. Cross-platform (paths identical on Win/Linux/macOS; only JSON validator differs). Phase-2 confirmation gate before any write; per-edit JSON validation; rollback procedure documented. using-context7 gets a small Prerequisites section pointing at setup-context7 when MCP tools are missing. Bonus fix: scripts/build.sh PS multi-arg bug. Comma-joined -Names didn't split into [string[]] when build.ps1 was invoked via -File. Now the bash side loops one PS invocation per skill. Wiki: extended .wiki/concepts/context7-setup.md with the design rationale (why split policy from setup) — template for future "X plugin + how to use X" pairs. index.md and log.md updated. Co-Authored-By: Claude Opus 4.7 (1M context) --- .tasks/STATUS.md | 10 ++ .wiki/concepts/context7-setup.md | 17 +++ .wiki/index.md | 2 +- .wiki/log.md | 1 + dist/setup-context7.skill | Bin 0 -> 4165 bytes dist/using-context7.skill | Bin 2421 -> 2603 bytes scripts/build.sh | 12 +- skills/setup-context7/SKILL.md | 192 +++++++++++++++++++++++++++++++ skills/using-context7/SKILL.md | 4 + 9 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 dist/setup-context7.skill create mode 100644 skills/setup-context7/SKILL.md diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 42cb3d3..fc5945d 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -3,6 +3,16 @@ _Updated: 2026-04-28_ ## Done +### Create `setup-context7` skill +- [x] Drafted `skills/setup-context7/SKILL.md` — 8 phases (discovery → plan → backup → install → inject → clean → smoke-test → restart) + rollback + cross-platform notes +- [x] API-key discovery in priority order: `settings.json` → `.claude.json` (top-level + project-scoped) → `settings.local.json` → env → ask +- [x] Phase 2 confirmation gate (no mutations without explicit "ok"); Phase 6 validates JSON after each edit +- [x] Documented `/plugin update` gotcha +- [x] Added Prerequisites section in `using-context7` pointing at `setup-context7` +- [x] Built + installed both skills (`setup-context7` already in `available_skills`) +- [x] Updated `.wiki/concepts/context7-setup.md` with "Now captured as a skill" section explaining the policy/setup split rationale +- [x] **Bonus fix:** `scripts/build.sh` PS multi-arg bug — comma-joined `-Names` wasn't splitting into `[string[]]` when called via `-File`. Now loops in bash, one PS invocation per skill. + ### Switch context7 from manual MCP config to official plugin - [x] Backup `~/.claude.json` and `~/.claude/settings.json` (suffix `.bak-20260428-114532`) - [x] User installed `context7@claude-plugins-official` diff --git a/.wiki/concepts/context7-setup.md b/.wiki/concepts/context7-setup.md index 99435be..dba136e 100644 --- a/.wiki/concepts/context7-setup.md +++ b/.wiki/concepts/context7-setup.md @@ -71,3 +71,20 @@ Manual MCP entries in `~/.claude.json` / `settings.json` are easy to: - drift from the canonical version The plugin centralizes the registration and gets versioned through the marketplace. The price is a single edit-after-update for the API key. + +## Now captured as a skill + +The procedure above is now formalized as the **`setup-context7`** skill ([`skills/setup-context7/SKILL.md`](../../skills/setup-context7/SKILL.md)). It runs the same algorithm with confirmation gates and key-discovery logic (search `settings.json` → `.claude.json` → env, reuse what's there, never invent). `using-context7` got a small **Prerequisites** section pointing at it. + +### Why split into two skills + +Two distinct concerns: + +- **Policy** (every-time, short-running): when to call resolve-library-id, query budget, how to phrase queries — this lives in `using-context7`. +- **Setup** (one-time, mutates user config): install plugin, inject key, clean manual entries — this lives in `setup-context7`. + +Mixing them would make the policy skill ~2× larger, dilute its description (worse triggering), and make every library question pull setup procedure into context. The split is also a template for future "X plugin + how-to-use-X" skill pairs. + +### Cross-platform + +The setup skill is platform-agnostic. Only the JSON validator differs (PowerShell on Windows, `jq` / Python on Linux/macOS). Paths (`~/.claude/...`) are identical. diff --git a/.wiki/index.md b/.wiki/index.md index f3f71f9..4faf16c 100644 --- a/.wiki/index.md +++ b/.wiki/index.md @@ -14,7 +14,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever - [active-platform-decision.md](concepts/active-platform-decision.md) — why `active-platform` is a skill (not a memory entry); why default = Windows; how it's wired into `project-bootstrap` - [build-notes.md](concepts/build-notes.md) — why `build.ps1` exists alongside `build.sh`; PS 5.1 backslash-in-zip gotcha; how to extract a `.skill` -- [context7-setup.md](concepts/context7-setup.md) — switched context7 from manual MCP entries to the official plugin; API key now lives in the plugin's `.mcp.json` as `--api-key`; re-apply after `/plugin update` +- [context7-setup.md](concepts/context7-setup.md) — switched context7 from manual MCP entries to the official plugin; API key in `.mcp.json` as `--api-key`; now also captured as `setup-context7` skill (one-time install/migrate flow with key discovery) - [repo-layout.md](concepts/repo-layout.md) — flat `skills/`, committed `dist/`, bash + PowerShell scripts; install model - [wiki-realignment.md](concepts/wiki-realignment.md) — fixing `project-bootstrap` to create the Karpathy-canonical wiki layout diff --git a/.wiki/log.md b/.wiki/log.md index dc97969..2d912d1 100644 --- a/.wiki/log.md +++ b/.wiki/log.md @@ -19,3 +19,4 @@ Parseable: `grep "^## \[" .wiki/log.md | tail -20`. ## [2026-04-28] refactor | wiki-realignment — fixed project-bootstrap Step 3 to create Karpathy-canonical layout ## [2026-04-28] refactor | this repo's `.wiki/` migrated to canonical layout (SUMMARY.md→index.md, source/→concepts/, added log.md/overview.md/CLAUDE.md schema, raw/README.md) ## [2026-04-28] decision | context7-setup — switched to official plugin; --api-key injected into plugin's .mcp.json; three manual MCP entries removed +## [2026-04-28] decision | setup-context7 skill — formalized the install/migrate algorithm; using-context7 gets a Prerequisites pointer; build.sh PS multi-arg bug fixed (loop instead of comma-joined -Names) diff --git a/dist/setup-context7.skill b/dist/setup-context7.skill new file mode 100644 index 0000000000000000000000000000000000000000..db6a3e271426fe924ab7580f10f3ac2daec664d4 GIT binary patch literal 4165 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 I2><{90JJge@&Et; delta 2363 zcmV-B3B>lR6!j7qP)h>@6aWAK2mp#yoLuz?@ATye004p%kr*F;%aYr;72WeIZgCb? z%Mum4JC#&Bm5I|HPgK+PIJOhVs}@8;6x<}i0YIr$dMJG_lqc#HZ`htN>`Wk2Pj(*{Ix~B73NuxSP>V8VjZKUe{V~#ZGB6qf+HYutj+1 z_7cXno2}Q`8a14h#%N;`dTWHLSbZj(AZ1B!91gP)@(Fc+@gM`^47^PnV`Swh(CsG@_u|XqZu!ED&c?Sv%-AawAfwIdC&tbEKuU^FrsaBa`bU&;1JI_$a%r z#9=H5#9b6ditNya-ulHZ_(?QJ{-UptAXXU8wFbYqdWDD@1OXeqqVMrzr{q40R^65r zdn>BZPDl`cjyBSzTWM)JZJnJ?+1;kZ&k$kun5!mh!>S|;%7%njwVaOZHa4Y-H5w%_gDiRut+DY2Jz|mkBL@H`vk3WgGcOU*Xd!l9O(IK>En9 zB_8DnD;uLrDrKq7VLF|W+{qBaA$SMfP<&hIee5xDU|Wq$fdeYV0TM}9lIz1Es-^gV z%H`5mRhIbdzVl_H0b&_NJzBXQ@Wzm^w>?g)11g-CuuE0rn&J1K!}v0a=Cll;q(uNJ z{*N$!IvgxZq{w2&l}9UWR3XW3MJ;Kvs+v2O1Q;jIu4c5V<)J6d(tGWPB%7A=au;?m&|`)5z?f$ToGYjidKp z$1MF-(E#lbR_d&Qu`<>6V4W-nN{yl`1Qu31qw*XUUsAl)dz3USQ6K+~XB6*&)CYkL zuxaaH+kq3s#S(HFU)bIk`7bU>dpOcClw^yixExM3ZMS*Y)dB2pDi@t6H1q(t;kI70Zvi9z>fjVzBy_<#SYrqZlUqE$ zY79tM(#Pl{CXxO>9Qbc~K6bT_FOhU^2HqZCc-c(@M-DHaC4L%3$5yF-0=84(N1sXj zl3U9M8wak4xzph3ETL1@jAw|!ie+}s21NXLkVyLFvO&?JFL&j}dZOzgR~&zV5;?Me zB9k0KI8Ui87F95Mb@n5fJbh$=rj?v0KUfKfLN zIIxWz&jU}uiy`|w7I)hOq06sH*_fEkA8#qJ`x zOYXQ?wFE(YZK%+E*;2d^WHsZl_YHIiLGm>sA7>?_7Lk8;{qjyUc_0aXaBU_98eI8tqi4WRPFyzsYA6qO#Q!GfGckwpIiP)h*<6aW+e h000ON0E$$cT=fX=^yLTu0D=^g>Ipjr8VLXZ007b$kZb?| diff --git a/scripts/build.sh b/scripts/build.sh index c4020ad..044cf44 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -36,14 +36,16 @@ if command -v zip >/dev/null 2>&1; then done elif command -v powershell.exe >/dev/null 2>&1; then # Windows fallback: delegate to build.ps1 (proper ZIP via .NET API). + # PS array binding via -File is fragile (commas don't always split into [string[]]), + # so call build.ps1 once per skill and let the bash loop do the work. ps1="$SCRIPT_DIR/build.ps1" + ps1_win="$(cygpath -w "$ps1" 2>/dev/null || echo "$ps1")" if [ "$#" -eq 0 ]; then - powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$(cygpath -w "$ps1" 2>/dev/null || echo "$ps1")" + powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$ps1_win" else - # PS array via -File: comma-separated, no extra quoting (bash arg becomes one PS token). - joined=$(printf ",%s" "$@") - joined="${joined:1}" - powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$(cygpath -w "$ps1" 2>/dev/null || echo "$ps1")" -Names "$joined" + for name in "$@"; do + powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$ps1_win" -Names "$name" + done fi else echo "error: need either 'zip' (Linux/macOS) or PowerShell (Windows) to build .skill archives" >&2 diff --git a/skills/setup-context7/SKILL.md b/skills/setup-context7/SKILL.md new file mode 100644 index 0000000..494b7b0 --- /dev/null +++ b/skills/setup-context7/SKILL.md @@ -0,0 +1,192 @@ +--- +name: setup-context7 +description: Installs and configures the official context7 MCP plugin (`context7@claude-plugins-official`), reuses the user's existing Context7 API key, and cleans out any manual `mcpServers.context7` entries from `~/.claude.json` and `~/.claude/settings.json`. Use this skill when the user says "install context7", "set up context7", "configure context7", "настрой context7", "установи context7", "context7 не работает", "context7 isn't working", or whenever the `mcp__context7__resolve-library-id` / `mcp__context7__query-docs` tools are missing in a session that needs library docs. Cross-platform — Windows / Linux / macOS. Mutates user-level config; pauses for confirmation before writing. +--- + +# setup-context7 + +> One-time skill that gets the official context7 plugin running with the user's existing API key, with manual MCP entries cleaned up. Stops at confirmation gates because the procedure modifies user-level config files. + +## When to use + +- User explicitly asks: install / set up / configure context7. +- A `using-context7`-driven task fails because `mcp__context7__*` tools aren't available. +- Migrating an existing manually-configured context7 to the official plugin. + +## Out of scope + +- Creating a *new* API key. This skill *reuses* a key the user already has; if there's no key, offer the OAuth flow (`npx ctx7 setup`) and stop. +- Rolling back from the official plugin to manual config. +- Any non-context7 MCP server. + +## Hard rule: don't auto-mutate config + +The procedure modifies `~/.claude.json` and `~/.claude/settings.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 overwrite config. + +## Procedure + +### Phase 0 — Environment sanity + +- Confirm Claude Code is the current harness (need `/plugin install` capability). +- Confirm `npx` is on `PATH` (the plugin spawns `npx -y @upstash/context7-mcp`). If missing, install Node.js first. +- Pick paths: `~/.claude/` works on all three OSes. In git-bash on Windows, `~` resolves correctly. + +### Phase 1 — Discovery (read-only) + +Search, in order. Stop reporting verbatim values for keys; report only "found at ". + +**Existing API key.** Look in priority order: + +1. `~/.claude/settings.json` → `mcpServers.context7.headers.CONTEXT7_API_KEY` +2. `~/.claude.json` → top-level `mcpServers.context7.headers.CONTEXT7_API_KEY` +3. `~/.claude.json` → `projects..mcpServers.context7.headers.CONTEXT7_API_KEY` +4. `~/.claude/settings.local.json` if present +5. Env var `CONTEXT7_API_KEY` + +The first hit wins. Capture the key value internally for Phase 5; **never echo it in chat**. + +**Manual context7 MCP entries.** Find every `mcpServers.context7` block in `~/.claude.json` and `~/.claude/settings.json` (top-level and project-scoped). Note all locations. + +**Plugin install state.** Read `~/.claude/plugins/installed_plugins.json` and check for `context7@claude-plugins-official`. + +**Plugin's `.mcp.json` state** (only if plugin is installed). Path: +``` +~/.claude/plugins/cache/claude-plugins-official/context7//.mcp.json +``` +`` is often `unknown` for un-tagged marketplace plugins. List the cache dir to find it. Check whether `--api-key` is already in `args`. + +### Phase 2 — Plan + confirm + +Present a single-block plan to the user: + +``` +API key: +Plugin: +Manual entries: +Backups: ~/.claude.json.bak-, ~/.claude/settings.json.bak- +``` + +Wait for explicit confirmation ("ok", "go", "поехали"). Anything else → stop. + +If no API key was found in Phase 1 — first ask: "Paste a Context7 API key, or run `npx ctx7 setup` to get one (OAuth)?" Don't proceed past Phase 2 without a key. + +### Phase 3 — Backup + +Copy each file we will modify to `.bak-YYYYMMDD-HHMMSS`: +```bash +TS=$(date +%Y%m%d-%H%M%S) +cp ~/.claude.json ~/.claude.json.bak-$TS +cp ~/.claude/settings.json ~/.claude/settings.json.bak-$TS +``` +Confirm both backups exist before any further edit. + +### Phase 4 — Plugin install (if needed) + +If the plugin is **not** in `installed_plugins.json`: +1. Ask the user to run `/plugin install context7@claude-plugins-official` in Claude Code (we can't run interactive slash commands). +2. Wait for "поставил" / "installed". +3. Verify by re-reading `installed_plugins.json`. + +If the plugin **is** already installed: skip this phase. + +### Phase 5 — Inject `--api-key` + +Find the live plugin file: +``` +~/.claude/plugins/cache/claude-plugins-official/context7//.mcp.json +``` + +If the file's `args` already contains `--api-key`, skip. Otherwise edit `args` to append `"--api-key", ""`. Final shape: + +```json +{ + "context7": { + "command": "npx", + "args": ["-y", "@upstash/context7-mcp", "--api-key", ""] + } +} +``` + +Per Upstash's client-config docs (), `--api-key` is the recommended form for stdio transport. Header form is for HTTP transport (which the plugin doesn't use). + +### Phase 6 — Clean manual entries + +For each manual entry found in Phase 1: + +- **Top-level `mcpServers.context7`** in `settings.json` or `.claude.json` → remove the `context7` key. Preserve sibling MCP servers and JSON validity (watch for trailing commas). +- **Project-scoped `projects..mcpServers.context7`** in `.claude.json` → remove. If the parent `mcpServers` becomes empty, leave it as `{}` (don't delete the key — Claude Code may rely on its presence). + +After each edit, validate JSON. On any platform: +```bash +# Windows (PowerShell) +powershell.exe -NoProfile -c "Get-Content '' -Raw | ConvertFrom-Json | Out-Null" +# Linux / macOS (jq) — install via brew/apt if missing +jq empty +# fallback: python (always available) +python -c "import json,sys; json.load(open(''))" +``` + +If validation fails → restore the just-edited file from its `.bak-*` and abort with a clear report. Do not continue editing. + +### Phase 7 — Smoke test (best-effort) + +Call `mcp__context7__resolve-library-id` with a benign query (e.g. `libraryName: "Nuxt"`, `query: "smoke test"`). If it returns library IDs — context7 is reachable in *this* session. + +**Important caveat to relay to the user:** in the *same* session that just ran setup, the MCP server is still the legacy connection bound at session start. So a passing smoke test only proves "context7 still works" — not "the plugin 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 to pick up the plugin's stdio transport. + +After restart: + • mcp__context7__* tools will be served by `npx @upstash/context7-mcp --api-key …` + • Manual entries are gone — single source of truth is the plugin's .mcp.json. + • Backups saved at ~/.claude.json.bak- and ~/.claude/settings.json.bak-. + +If something breaks after restart: + • Restore from .bak-* files 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 `~/.claude/settings.json`. +3. `cp .bak- ` for both. +4. Optional: `/plugin uninstall context7@claude-plugins-official`. +5. Restart Claude Code. +6. Confirm `mcp__context7__*` is back via the legacy HTTP path. +7. Report what went wrong so we can fix the procedure. + +## Plugin-update gotcha + +`/plugin update context7@claude-plugins-official` (or any reinstall) re-fetches the plugin's `.mcp.json` from the marketplace cache. That file is upstream-canonical and **does not** contain `--api-key` — the marketplace doesn't ship secrets. After any plugin update: + +- Run this skill again. Phase 1 will detect the missing flag, Phase 5 will re-inject. Phases 4 and 6 are no-ops. +- Or manually re-add `--api-key` to `args` in the live `.mcp.json`. + +The marketplace upstream is at `anthropics/claude-plugins-official/external_plugins/context7/.mcp.json`. It's two lines and rarely changes — the `--api-key` re-injection is the only ongoing maintenance cost. + +## Cross-platform notes + +The procedure is platform-agnostic. Only auxiliary tooling differs: + +| | JSON validate | Backup | +|---|---|---| +| Windows (git-bash) | `powershell.exe -NoProfile -c "Get-Content '' -Raw \| ConvertFrom-Json \| Out-Null"` | `cp` | +| Linux | `jq empty ` (or `python -c "import json; json.load(open(''))"`) | `cp` | +| macOS | same as Linux | `cp` | + +Path forms (`~/.claude/...`) are identical on all three. + +## Common mistakes + +- **Skipping Phase 1.** "User just said 'install context7' — let's go." No — find the existing key first; making the user paste a key when they already have one is rude. +- **Echoing the key.** It's a secret. The Edit / Write tool calls inevitably contain it (that's how it gets into the file), but no chat output should. +- **Mutating `.claude.json` without backup.** That file holds *all* of the user's per-project Claude Code state. Losing it is bad. +- **Treating in-session smoke test as proof.** It isn't — the active MCP connection is bound at session start. +- **Auto-running on every "use context7".** This skill is intrusive. Trigger only when explicitly invoked or when MCP tools are missing and the user is blocked. diff --git a/skills/using-context7/SKILL.md b/skills/using-context7/SKILL.md index 0e0e7fa..1f68fc0 100644 --- a/skills/using-context7/SKILL.md +++ b/skills/using-context7/SKILL.md @@ -11,6 +11,10 @@ description: Use when answering questions about a specific library, framework, S Your training data has a cutoff. Library APIs change. If a question names a library, **reach for context7 before answering from memory**, even for libraries you "know" — your recall may be one or two majors behind. +## Prerequisites + +This skill assumes `mcp__context7__resolve-library-id` and `mcp__context7__query-docs` are available. If they aren't (the tools are missing from the session, or calls fail with a connection error), the context7 MCP server isn't running for this session. Trigger the **`setup-context7`** skill to install/configure the official plugin (`context7@claude-plugins-official`) and inject the user's API key. It's a one-time procedure with confirmation gates. + ## When to use Use when the user asks about any of these in the context of a specific library: