feat: add context7 plugin - #54
Conversation
Migrates the context7 library-documentation lookup skill into a repo-agnostic plugin: two-step resolve-then-query workflow over the ctx7 CLI or the consumer-configured Context7 MCP server, configure action (auth, Windows Git Bash gotcha), and an advisory update action that checks CLI version drift and diffs Upstash upstream reference skills against bundled vendor baselines. Ships no MCP server and no userConfig; CONTEXT7_API_KEY stays a consumer env var. Vendor baselines are byte-exact upstream snapshots — rules off via a directory-scoped markdownlint config and a root .lycheeignore vendor pattern. Co-Authored-By: Claude <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_0efb1dfb-3ef5-44f6-8e5e-a24ec7ad8078) |
|
Claude finished @kyle-sexton's task in 4m 13s —— View job PR Review: feat: add context7 plugin
Overall: This is a well-crafted migration. The plugin structure is clean, the security posture is solid, and the layered progressive-disclosure pattern ( Findings1.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6682d19d0f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Prereq checks before mkdir, diff-truncation warning, serialization claim reworded as observed behavior, CLI version floor wording. Co-Authored-By: Claude <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_bf6bb59a-23f2-4ad6-baff-7de1b3a99aa5) |
|
Claude finished @kyle-sexton's task in 1m 58s —— View job PR Review: feat: add context7 plugin
Previous findings — all addressed cleanlyCommit
The diff for each is clean and minimal — no drift beyond the targeted fixes. Remaining open item — Codex finding (not yet addressed)Anonymous MCP config is missing;
|
There was a problem hiding this comment.
Stale comment
Risk: medium. Not approving: Cursor Bugbot completed with a skipped status (usage limit reached) and did not produce a clean review signal. Human review is needed; no reviewers were assigned because no suitable non-author maintainers were identified in this repository.
Sent by Cursor Approval Agent: Pull Request Router and Approver
Unset ${CONTEXT7_API_KEY} in headers fails .mcp.json parsing (per MCP docs), which would break the documented anonymous path. Addresses Codex P2 review finding.
Co-Authored-By: Claude <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_43afb1b8-654b-4d3e-8cf5-f4ccda175411) |
|
Claude finished @kyle-sexton's task in 1m 12s —— View job PR Review: feat: add context7 plugin
Latest commit (
|
| Round | Finding | Status |
|---|---|---|
| 1 | head -60 silent truncation in update.sh |
✅ Fixed (5c9e4cb) |
| 1 | mkdir -p before prereq checks |
✅ Fixed (5c9e4cb) |
| 1 | Unverified MCP serialization claim | ✅ Fixed (5c9e4cb) |
| 1 | Pinned version string aging in cli.md |
✅ Fixed (5c9e4cb) |
| 2 | Anonymous MCP config breaks unset-var consumers (Codex P2 / Claude medium) | ✅ Fixed (dd8af33) |
No new issues introduced in dd8af33 — the change is a two-block doc addition touching only mcp.md, with no script, manifest, or vendor changes.
What's solid (unchanged from prior review)
The full plugin holds up across all review dimensions:
- Security: No
eval, nocurl | sh, no../escapes;--fix/--refresh-baselineprivilege separation is correct;allowed-toolsis minimal (ctx7 --versiononly) - MCP graceful degradation: No MCP server shipped; CLI fallback is complete; the
mcp.mdtwo-config pattern now covers both anonymous and authenticated paths safely update.sh:set -uo pipefail(no-e) is intentional; diff truncation warning, line-ending normalization,${CLI_DRIFT:-0}guard, andRETURNtrap for temp-file cleanup are all correct- Plugin structure:
plugin.jsonminimal and correct; skills auto-discovered; catalog and README updated;.lycheeignoreandvendor/.markdownlint-cli2.jsonccorrectly scope linting exclusions - No PII / secrets / hardcoded paths: Consumer context flows through
${CLAUDE_PROJECT_DIR}anduserConfig;CONTEXT7_API_KEYis a consumer env var, never stored
This PR is ready to merge.
There was a problem hiding this comment.
Stale comment
Risk: medium. Not approving because Cursor Bugbot skipped (usage limit reached) and did not provide a clean automated review signal. Human review is needed; no reviewers were assigned because no suitable non-author maintainers were identified in this repository.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd8af339fa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Wrap both .mcp.json snippets in the top-level mcpServers object Claude Code requires (per code.claude.com/docs/en/mcp), and send the API key in the CONTEXT7_API_KEY request header Context7's server expects (per github.com/upstash/context7 README) instead of x-api-key. Addresses the two Codex P2 review findings on dd8af33.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_7c20b3f4-b67d-413e-9edb-2439d2d474f4) |
|
Claude finished @kyle-sexton's task in 2m 9s —— View job PR Review: feat: add context7 plugin
Latest commit (
|
| Round | Finding | Commit |
|---|---|---|
| 1 | head -60 silent truncation with no signal in update.sh |
✅ 5c9e4cb |
| 1 | mkdir -p runs before prerequisite checks |
✅ 5c9e4cb |
| 1 | Unverified MCP serialization claim presented as documented fact | ✅ 5c9e4cb |
| 1 | Pinned version string in cli.md will age |
✅ 5c9e4cb |
| 2 | Anonymous MCP config broken when CONTEXT7_API_KEY is unset |
✅ dd8af33 |
| 3 | MCP snippets not wrapped in mcpServers |
✅ 169ce85 |
| 3 | Wrong API-key header name (x-api-key → CONTEXT7_API_KEY) |
✅ 169ce85 |
No new issues introduced in 169ce85. The change is minimal and exclusively targets the Codex findings.
What's solid (unchanged)
All prior green-flags from earlier review rounds remain intact:
- Security: No
eval, nocurl | sh, no../escapes;--fix/--refresh-baselineprivilege separation correct;allowed-toolsscoped toctx7 --versiononly. update.sh:set -uo pipefail(no-e) is intentional; diff truncation warning, RETURN trap for temp cleanup, line-ending normalization (tr -d '\r'), and${CLI_DRIFT:-0}unset-var guard all correct.- MCP graceful degradation: No MCP server shipped; CLI fallback is complete;
mcp.mdtwo-config pattern now covers both anonymous and authenticated paths safely and correctly. - Plugin structure:
plugin.jsonminimal and valid; skills auto-discovered; catalog, README,.lycheeignore, andvendor/.markdownlint-cli2.jsoncall correctly structured. - Repo-agnostic design: No hardcoded paths; consumer context flows through
${CLAUDE_PROJECT_DIR};CONTEXT7_API_KEYis a consumer env var, never stored.
This PR is ready to merge.
There was a problem hiding this comment.
Stale comment
Risk: medium. Not approving because Cursor Bugbot skipped (usage limit reached) and did not provide a clean automated review signal. Human review is needed; no reviewers were assigned because no suitable non-author maintainers were identified in this repository.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 169ce85b8a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
lookup.md told the model to use the user's full question/intent as the Context7 query, which would forward pasted stack traces, proprietary code, and internal endpoints/identifiers to Context7's backend when only a distilled library/topic query is needed. Rework the query guidance to build a minimal query and broaden the do-not-send list beyond credentials. Addresses Codex P2 review finding on 169ce85.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_d6ca34e1-9323-4fa9-9523-03ba687d8bf0) |
|
Claude finished @kyle-sexton's task in 1m 25s —— View job PR Review: feat: add context7 plugin
Latest commit (
|
| Round | Finding | Commit |
|---|---|---|
| 1 | head -60 silent truncation with no signal in update.sh |
✅ 5c9e4cb |
| 1 | mkdir -p runs before prerequisite checks |
✅ 5c9e4cb |
| 1 | Unverified MCP serialization claim presented as documented fact | ✅ 5c9e4cb |
| 1 | Pinned version string in cli.md will age |
✅ 5c9e4cb |
| 2 | Anonymous MCP config broken when CONTEXT7_API_KEY is unset |
✅ dd8af33 |
| 3 | MCP snippets missing mcpServers wrapper |
✅ 169ce85 |
| 3 | Wrong API-key header name (x-api-key → CONTEXT7_API_KEY) |
✅ 169ce85 |
| 4 | Raw user prompts (stack traces, proprietary code) forwarded to Context7 | ✅ f4068d2 |
No new issues introduced in f4068d2. The change is minimal and exclusively targets the Codex P2 query-distillation finding.
What's solid (unchanged from prior reviews)
All prior green-flags remain intact:
- Security: No
eval, nocurl | sh, no../escapes;--fix/--refresh-baselineprivilege separation correct;allowed-toolsscoped toctx7 --versiononly - Data minimization: Query guidance now consistently instructs the model to distill — secrets, stack traces, proprietary code, and internal identifiers are explicitly excluded at three points in
lookup.md update.sh:set -uo pipefail(no-e) intentional; diff truncation warning, RETURN trap, line-ending normalization, and${CLI_DRIFT:-0}guard all correct- MCP graceful degradation: No MCP server shipped; CLI fallback complete;
mcp.mdcovers both anonymous and authenticated paths safely with correctmcpServerswrapping and header name - Plugin structure:
plugin.jsonminimal and valid; catalog, README,.lycheeignore, andvendor/.markdownlint-cli2.jsoncall correctly structured
This PR is ready to merge.
There was a problem hiding this comment.
Stale comment
Risk: medium. Not approving because Cursor Bugbot skipped (usage limit reached) and did not provide a clean automated review signal. Human review is needed; no reviewers were assigned because no suitable non-author maintainers were identified in this repository.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f4068d2930
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
cli.md claimed the CLI reads no env vars beyond CONTEXT7_API_KEY, but Context7's CLI docs (context7.com/docs/clients/cli, Telemetry section) document CTX7_TELEMETRY_DISABLED=1 as the opt-out for the CLI's anonymous usage telemetry. List it in the env-var table, state the on-by-default behavior, and surface it in the README data-egress note. Lookup guidance let independent topics share one query; per the ctx7@0.5.4 release notes (github.com/upstash/context7/releases/tag/ctx7@0.5.4), query-docs wants a single concept per query, with distinct topics split into separate queries unless the question is about how they interact. Add the split rule to SKILL.md and lookup.md, and scope the 3-lookup cap per topic so it does not contradict splitting. Addresses the two Codex P2 review findings on f4068d2.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_c4a27c8f-e146-4172-94d5-c66c8230d096) |
|
Claude finished @kyle-sexton's task in 1m 28s —— View job PR Review: feat: add context7 plugin
Latest commit (
|
| Location | Change |
|---|---|
SKILL.md:54 |
"One concept per query — when a question spans several independent topics, run a separate lookup per topic." + cap changed from "per question" → "per topic" |
context/lookup.md:81 |
New paragraph in "Writing good queries": single-concept rule, example of when to combine (interaction questions: "Next.js middleware with NextAuth session validation") vs. split |
context/lookup.md:108 |
New "Common mistakes" bullet: "Do not combine independent topics into one query — one concept per lookup" + cap bullet changed to "per topic" |
The interaction-vs-independent distinction in lookup.md ("Combine concepts in one query only when the question is about how they interact") is exactly the right nuance — it prevents both the anti-pattern (combined query diluting ranking) and over-splitting (a question about how two things interact genuinely needs both terms in scope).
All findings across all five review rounds — resolved
| Round | Finding | Commit |
|---|---|---|
| 1 | head -60 silent truncation with no signal in update.sh |
✅ 5c9e4cb |
| 1 | mkdir -p runs before prerequisite checks |
✅ 5c9e4cb |
| 1 | Unverified MCP serialization claim presented as documented fact | ✅ 5c9e4cb |
| 1 | Pinned version string in cli.md will age |
✅ 5c9e4cb |
| 2 | Anonymous MCP config broken when CONTEXT7_API_KEY is unset |
✅ dd8af33 |
| 3 | MCP snippets missing mcpServers wrapper |
✅ 169ce85 |
| 3 | Wrong API-key header name (x-api-key → CONTEXT7_API_KEY) |
✅ 169ce85 |
| 4 | Raw user prompts (stack traces, proprietary code) forwarded to Context7 | ✅ f4068d2 |
| 5 | Telemetry opt-out (CTX7_TELEMETRY_DISABLED=1) not documented |
✅ 55ab313 |
| 5 | Independent topics should split into separate queries, not share one | ✅ 55ab313 |
No new issues introduced in 55ab313. The change is minimal and exclusively targets the Codex P2 findings.
What's solid (unchanged from prior reviews)
All prior green-flags remain intact. The full security, MCP, and script posture is unchanged from the prior review sign-off. The query guidance is now complete: distillation (no secrets/code/traces), one-concept-per-query (split independent topics), and the 3-lookup cap is correctly scoped to "per topic" at all three enforcement points.
This PR is ready to merge.
There was a problem hiding this comment.
Risk: medium. Not approving because Cursor Bugbot skipped (usage limit reached) and did not provide a clean automated review signal. Human review is needed; no reviewers were assigned because no suitable non-author maintainers were identified in this repository.
Sent by Cursor Approval Agent: Pull Request Router and Approver
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 55ab31300c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… machinery The cross-vendor review's fourth gap: the gate re-asked the proportionality question of the catalog and never of the run contract after the payload shrank to one detector. Applied per mechanism rather than to the contract as a whole, because an aggregate verdict can only come back "necessary" — the same unfalsifiable shape the blind pass already recorded against this gate's escalation clause. The test fired on two of four. The state key's repo-identity half is legibility standing in a correctness slot; the worktree hash alone carries every property. Per-lane input digests are deferred with a Phase 10 trigger, because a single tree-wide refuse-to-resume check closes the P1 hole completely and partial resume is an unmeasured ergonomic gain on top. The advisory lock and the versioned anchor survive on reasons that do not depend on solo-machine scope. Three consistency defects found by re-grepping with multiline enabled — these documents hard-wrap near 100 characters, so every prior multi-word grep was unreliable: - The report's finding sections were still named for the superseded two-tier vocabulary, so a consumer would have diffed a section no property mentions. - Shadowed-definition findings were filed in the host catalog's "mechanical" tier rather than the sweep's derived tier. The two vocabularies measure different axes and are now stated as such. - T2's suppression blast-radius bullet cited the replaced identity tuple and claimed a bound of one excerpt in one file. Under a sorted sites set a pairwise suppression spans two surfaces — one site wider than advertised, for exactly the finding class D1 exists to produce. Also from task #54's empirical record: liveness is three-valued, because a one-shot run observes the launch set only and a nested CLAUDE.md fired no event at session start. Classifying a conditionally-live surface as dead yields a finding that is perfectly deterministic and perfectly wrong. Ground truth must be both InstructionsLoaded and /context — the hook sees only CLAUDE.md and rules files, which is most of D1's comparison set missing. The suppression record stores identity constituents rather than a bare hash, or versioned-anchor matching has nothing to recompute from and cancels itself out. And the /doctor TTY claim is falsified as written rather than merely unverified: slash commands resolve headlessly by counter-example on 2.1.220. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>


Migrates the
context7library-documentation lookup skill into a repo-agnostic plugin perdocs/MIGRATION-PLAYBOOK.md. Closes melodic-software/medley#1297.What ships
One skill,
/context7:context7, with three actions:ctx7CLI or the consumer's own Context7 MCP server (graceful CLI fallback when no MCP is configured).CONTEXT7_API_KEYenv-var auth, Windows Git BashMSYS_NO_PATHCONV=1gotcha.ctx7(npm), plus a diff of Upstash's upstream reference skills against bundledvendor/baselines. Never auto-rewrites the skill;--refresh-baselineis maintainer-only (documented).De-coupling from the source repo
settings.local.json,.claude/rules/*,/research,/machine-health); replaced with generic consumer guidance.scripts/update.shresolves paths from its own location (BASH_SOURCE) — works in the installed cache and in a working clone; nogit rev-parsedependency.ctx7 --versionvia frontmatterallowed-tools); the formerclaude mcp list | grep | sedpipeline failed per-operation permission preflight in a clean repo and was replaced by a tool-list self-check instruction.Gate evidence (speed-adjusted per issue)
claude plugin validate ./plugins/context7 --strict— PASS;claude plugin validate --strict .(catalog) — PASS.claude plugin details— always-on ~165 tokens, on-invoke ~2.3k.--plugin-dirsmoke test in a clean non-source scratch repo (headlessclaude -p): skill invoked ascontext7:context7, content loaded with no permission prompts, pre-computed context executed (Installed CLI version: not installed (…)— correct for that machine).lychee --offline0 errors.Security review (playbook plugin-acceptance)
scripts/update.sh), user-invoked only (no hooks). Spawnsnpm,curl,diff; writes only with--fix(npm global install) or--refresh-baseline(maintainer-only, writes beside itself). Noeval, nocurl | sh..mcp.jsonsnippet formcp.context7.comand degrades to the CLI when absent.CONTEXT7_API_KEYstays a consumer env var; never stored by the plugin.../reach-outs; no state writes (the skill explicitly does not cache docs).context7.com/mcp.context7.com) — that is the plugin's purpose; skill and README both warn against secrets in queries.updatereads npm registry + two public raw.githubusercontent.com files, read-only.Vendor baselines vs managed lint configs
vendor/holds byte-exact upstream snapshots (drift-diff baselines) that must not be edited to satisfy linters. Managed materializations (.markdownlint-cli2.jsonc,_typos.toml,lychee.toml,.editorconfig-checker.json) are untouched; instead:vendor/.markdownlint-cli2.jsonc(default: false) silences rules for the snapshots only (typos/editorconfig pass on them as-is);.lycheeignoreexcludes links resolving intoplugins/*/skills/*/vendor/(upstream files reference siblings that are deliberately not vendored).No contract test ships: the script's behavior is network-bound (npm registry + GitHub fetch), and no existing skill-plugin script carries a
*.test.sh— matching precedent rather than adding a flaky lane.Note
Medium Risk
Lookup sends user query text to Context7;
update.sh --fixrunsnpm install -g ctx7. No hooks or bundled MCP, but third-party network egress and global npm install warrant awareness.Overview
Adds a new
context7marketplace plugin so consumers can resolve library names and query live Context7 documentation via/context7:context7, using either thectx7CLI or an optional consumer-configured Context7 MCP server (CLI fallback when MCP is absent).The skill exposes three actions: lookup (default two-step resolve-then-query), configure (install,
CONTEXT7_API_KEY, WindowsMSYS_NO_PATHCONV=1), and update (advisory drift check). Progressive-disclosure docs live undercontext/*.md;scripts/update.shcompares installed vs latestctx7, fetches Upstash reference skills, diffs against bundledvendor/baselines, and only upgrades the CLI with--fix(never auto-merges skill content).--refresh-baselineis maintainer-only.Catalog and docs are wired in
.claude-plugin/marketplace.jsonandREADME.md. Repo hygiene adds.lycheeignorefor vendor snapshot links andvendor/.markdownlint-cli2.jsoncso upstream baselines stay byte-exact for drift diffing.Reviewed by Cursor Bugbot for commit 55ab313. Bugbot is set up for automated code reviews on this repo. Configure here.