feat(mcp): generate config packs for MCP clients#726
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new contextweaver mcp generate-configs CLI subcommand that generates multiple MCP client configuration files (Copilot, Cursor, Claude Desktop, Claude Code) from a single canonical mcp serve --config source, aiming to reduce manual translation drift while keeping outputs deterministic and commit-friendly.
Changes:
- Added
mcp generate-configsto render target-specific config payloads and emit compatibility warnings. - Added subprocess-driven CLI tests that pin generated artifacts against the shipped recipe fixtures.
- Updated docs, changelog, and agent-facing module map notes to reflect the new subcommand.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/contextweaver/_mcp_cli.py |
Adds the generate-configs command, target enums, path rendering helpers, and per-target payload/warning emission. |
tests/test_mcp_generate_configs_cli.py |
Adds focused CLI tests for help output, overwrite semantics, validation-before-write, and fixture pinning. |
docs/recipes/index.md |
Documents how to generate multi-client config packs and key CLI flags/behavior. |
CHANGELOG.md |
Records the new config-pack generator feature under “Added”. |
AGENTS.md |
Updates the module map note to include the new mcp generate-configs subcommand. |
f149991 to
d33d12f
Compare
Add mcp generate-configs to render Copilot, Cursor, Claude Desktop, and Claude Code files from one serve config. Reuse serve config validation, emit target warnings, and block overwrite unless --force. Keep output deterministic and fixture-compatible. Update recipe docs, changelog, and AGENTS module-map entry. Add focused CLI tests for command surface and generated shape.
d33d12f to
450d216
Compare
_absolute_placeholder() baked Path.cwd().name into the generated Claude Desktop placeholder, so `mcp generate-configs` output varied by checkout directory name and the fixture-pinning test failed when the repo was not in a folder named "contextweaver". Derive the slug from the top-level package name instead, keeping output deterministic and fixture-identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AmsfKnjsxEEhpecTyZqFcN
The committed api/public_api.txt listed the full FuzzyScorer class, which only exists when the optional rapidfuzz dependency (contextweaver[retrieval]) is installed. The canonical CI environment installs ".[dev,langchain]" (no rapidfuzz), so its generator emits "FuzzyScorer: NoneType", and the manifest drift gate (gen_api_manifest --check / drift_check --check) failed across the test matrix. Regenerate the manifest in the rapidfuzz-less environment so it matches main and the CI generator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AmsfKnjsxEEhpecTyZqFcN
Benchmark delta (vs
|
| size | recall@k (head Δ vs base) | MRR (head Δ vs base) | p99 (ms) |
|---|---|---|---|
| 50 | ✅ 0.5649 (+0.0000) | ✅ 0.4978 (+0.0000) | ✅ 0.821 (base 0.759) |
| 83 | ✅ 0.3825 (+0.0000) | ✅ 0.3242 (+0.0000) | ✅ 0.659 (base 1.134) |
| 1000 | ✅ 0.1475 (+0.0000) | ✅ 0.1456 (+0.0000) | ✅ 36.365 (base 41.711) |
Per-backend × per-size matrix
| backend | size | recall@k (Δ) | MRR (Δ) | p99 (ms) |
|---|---|---|---|---|
| bm25 | 100 | ✅ 0.3825 (+0.0000) | ✅ 0.3399 (+0.0000) | ✅ 6.052 (base 8.140) |
| bm25 | 500 | ✅ 0.2250 (+0.0000) | ✅ 0.2165 (+0.0000) | ✅ 28.740 (base 38.989) |
| bm25 | 1000 | ✅ 0.1575 (+0.0000) | ✅ 0.1525 (+0.0000) | ✅ 82.643 (base 111.716) |
| embedding_hashing | 100 | ✅ 0.5175 (+0.0000) | ✅ 0.4360 (+0.0000) | ✅ 7.935 (base 7.225) |
| embedding_hashing | 500 | ✅ 0.2700 (+0.0000) | ✅ 0.2674 (+0.0000) | ✅ 42.403 (base 44.182) |
| embedding_hashing | 1000 | ✅ 0.2000 (+0.0000) | ✅ 0.1931 (+0.0000) | ✅ 97.430 (base 98.277) |
| embedding_st | 100 | skipped (skipped: missing sentence-transformers) | — | — |
| embedding_st | 500 | skipped (skipped: missing sentence-transformers) | — | — |
| embedding_st | 1000 | skipped (skipped: missing sentence-transformers) | — | — |
| fuzzy | 100 | skipped (skipped: missing rapidfuzz) | — | — |
| fuzzy | 500 | skipped (skipped: missing rapidfuzz) | — | — |
| fuzzy | 1000 | skipped (skipped: missing rapidfuzz) | — | — |
| tfidf | 100 | ✅ 0.3825 (+0.0000) | ✅ 0.3220 (+0.0000) | ✅ 1.005 (base 1.102) |
| tfidf | 500 | ✅ 0.2325 (+0.0000) | ✅ 0.2314 (+0.0000) | ✅ 9.534 (base 11.492) |
| tfidf | 1000 | ✅ 0.1475 (+0.0000) | ✅ 0.1456 (+0.0000) | ✅ 33.849 (base 50.755) |
Context pipeline (per scenario)
| scenario | tokens | dropped | dedup |
|---|---|---|---|
| large_catalog | 1480 (base 1514, Δ-34) | 0 (base 0, Δ+0) | 0 (base 0, Δ+0) |
| long_conversation | 2500 (base 2548, Δ-48) | 0 (base 0, Δ+0) | 0 (base 0, Δ+0) |
| mixed_payload | 488 (base 497, Δ-9) | 0 (base 0, Δ+0) | 0 (base 0, Δ+0) |
| short_conversation | 487 (base 496, Δ-9) | 0 (base 0, Δ+0) | 0 (base 0, Δ+0) |
| stress_conversation | 6590 (base 6651, Δ-61) | 11 (base 7, Δ+4) | 4 (base 4, Δ+0) |
| tiny_payload | 256 (base 267, Δ-11) | 0 (base 0, Δ+0) | 0 (base 0, Δ+0) |
Numbers come from make benchmark / make benchmark-matrix.
Latency is hardware-dependent — treat the markers as a rough guide.
See benchmarks/scorecard.md for the full picture.
Audit-grade review flagged two untested branches of `mcp generate-configs`: - `--force` overwrite-success (only the refuse-without-force path was covered) - the outside-workspace fallback in _workspace_path/_absolute_placeholder (absolute-path emission + compatibility warning) Add focused CLI tests for both so the warning path and overwrite semantics are pinned. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AmsfKnjsxEEhpecTyZqFcN
Summary
mcp generate-configsto render client configs from onemcp serve --configsource.What changed
generate-configscommand and target renderers insrc/contextweaver/_mcp_cli.py.tests/test_mcp_generate_configs_cli.py.docs/recipes/index.md.CHANGELOG.md.AGENTS.mdfor new subcommand.Why
Test plan
python -m ruff check src tests examples scriptspassed.python -m pytest tests/test_mcp_generate_configs_cli.py tests/test_recipes_configs.py tests/test_mcp_serve_cli.py -qpassed (63 tests).make cicould not run:makeis unavailable in this Windows shell.Risks
--force.References
src/contextweaver/_mcp_cli.pytests/test_mcp_generate_configs_cli.pydocs/recipes/index.md,CHANGELOG.mdAGENTS.md