Commit 6b19ec4
fix(mcp): ${CLAUDE_PLUGIN_ROOT} substitution + cortex-doctor mcp diagnostic (#22)
* fix(mcp): robust .mcp.json + cortex-doctor mcp diagnostic (v3.15.2)
Discord user reported MCP server "✘ failed" with no actionable error.
Root cause: .mcp.json used a fragile Python -c one-liner that swallowed
launcher startup errors and depended on installed_plugins.json having a
specific key shape that breaks across plugin upgrades, custom marketplace
names, and missing python3 symlinks.
Fixes:
- .mcp.json now uses ${CLAUDE_PLUGIN_ROOT}/scripts/launcher.py — Anthropic's
documented plugin substitution variable, already used by every hook in
this repo (.claude/hooks/hooks.json). The launcher self-orients via
__file__ so manual installs continue to work (backward compatible).
- New `cortex-doctor mcp` subcommand: end-to-end MCP startup diagnostics.
Tells the user exactly which check failed, what command/path was tried,
and the actual error string — no more silent failures. Use --json for
Discord-paste-friendly output.
- 36 new tests (test_doctor_mcp.py + scripts/test_launcher_resolution.py)
cover happy path + every named failure mode (missing plugins.json,
missing key, stale installPath, missing launcher, broken launcher,
unset DATABASE_URL). Plus 6 contract tests guarding .mcp.json shape
against regression to the inline `-c` wrapper.
Backward compatible:
- `cortex-doctor` (no args) preserves legacy full-setup verification.
- launcher.py still self-orients via __file__ for manual installs.
Platform-agnostic: no Windows/Mac-specific code paths.
Bumps: pyproject.toml + .claude-plugin/marketplace.json → 3.15.2;
CHANGELOG entry added.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(mcp): add cortex-doctor mcp + launcher tests + v3.15.2 bump
Completes the v3.15.2 release started in fbf9354 (which only captured
.mcp.json + the contract test due to a staging hiccup):
- mcp_server/doctor_mcp.py — new module implementing `cortex-doctor mcp`
end-to-end MCP startup diagnostics. Each check reports the exact
command/path attempted and the actual error string; supports --json
for Discord-paste-friendly output. Covers: python interpreter on PATH,
installed_plugins.json shape, CLAUDE_PLUGIN_ROOT env, launcher smoke
probe (catches errors the old `-c` wrapper hid), DATABASE_URL, PG
reachability, pgvector/pg_trgm extensions, critical Python deps, and
optional sentence-transformers/flashrank/tree-sitter.
- mcp_server/doctor.py — adds subcommand dispatch. `cortex-doctor` (no
args) preserves legacy full-setup verification; `cortex-doctor mcp`
routes to doctor_mcp.run_mcp.
- tests_py/test_doctor_mcp.py + tests_py/scripts/test_launcher_resolution.py
— 49 new tests covering happy path + every named failure mode (missing
plugins.json, missing key, stale installPath, missing/broken launcher,
unset/invalid DATABASE_URL, env-var-set/unset/invalid for launcher
resolution).
- pyproject.toml + .claude-plugin/marketplace.json → 3.15.2.
- CHANGELOG.md — entry documenting the Discord report and the fix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(deps): pin tree-sitter-language-pack <1.7 + ruff format CI fix
Two CI gates failing on PR #22 — both are latent / dep-drift issues, not introduced by the v3.15.2 fixes themselves.
tree-sitter-language-pack 1.7.0+ changed Parser API; pip resolves >=0.24.0 to the latest (1.8.0 on CI right now), breaking 'parser.parse(...)' calls in tests_py/core/test_ast_*.py and tests_py/benchmarks/test_codebase_alteration.py with 'builtins.Parser has no attribute parse'. Pinning <1.7 keeps the contract that v3.15.2 was tested against. The latent break would also hit main on its next CI run; this commit protects both.
Lint failure on tests_py/scripts/test_mcp_json_contract.py was a stale ruff format from the parallel-agent merge.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 308ed41 commit 6b19ec4
10 files changed
Lines changed: 1407 additions & 12 deletions
File tree
- .claude-plugin
- mcp_server
- tests_py
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
| 6 | + | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
9 | 40 | | |
10 | 41 | | |
11 | 42 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
279 | 283 | | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
280 | 297 | | |
281 | 298 | | |
282 | 299 | | |
| |||
0 commit comments