Repository navigation
[AI-1225] MCP auto-config foundation: canonical server list + generic MCP config writer - #282
Conversation
IMcpMarker + McpMarker: records which kcap-* server names kcap wrote into a given MCP config, stored outside the host file itself (sidecar next to user-scope configs, hashed path under ~/.kcap/mcp-markers for project-scope/central configs). Owns() gates overwrite/unregister on both a recorded name AND command == "kcap", so a user-authored look-alike entry is never touched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… (idempotent when identical)
PR Summary by QodoMCP auto-config foundation: canonical server list + JSON config writer + ownership marker
AI Description
Diagram
High-Level Assessment
Files changed (9)
|
Code Review by Qodo
1.
|
…on-object, detect .git worktrees Three robustness fixes from code review: - Record now stamps `harness` alongside `config`; ReadNames only trusts a marker whose stored harness AND config match the request, so a per-directory user-scope sidecar can no longer leak ownership across configs/harnesses that happen to share a directory. - Owns guards against a non-JsonObject entry (array/scalar) before indexing "command", returning false instead of throwing. - IsInsideRepo now treats `.git` as either a directory or a file, since worktrees and submodules use a `.git` file pointing at the real gitdir. Adds two tests: Owns_false_and_no_throw_for_nonobject_entry and Owned_ignores_marker_recorded_for_a_different_config.
McpMarker stored/compared the raw configPath while MarkerPath resolved via Path.GetFullPath, so equivalent path forms (relative vs absolute, ./x vs x) for the same config file failed the "config" match and made owned entries invisible to self-heal/unregister.
…llision) Include the config file name in the user-scope sidecar path so two config files in the same directory get independent ownership markers instead of overwriting each other's record (which orphaned kcap entries).
Codex code-review flow — CLEAN ✅ (4 rounds)Ran an independent hosted-Codex code review on this diff (context-only). It found and I fixed 4 robustness bugs, all in
Commits: Follow-up (non-blocking): make |
Foundation for the MCP auto-config epic (AI-1224) — the shared config-writing layer every per-harness registration issue builds on.
What
KcapMcpServers— single canonical source of truth for the 4 kcap MCP servers (review/sessions/flows/memory);.ForCodex= the 3-server subset (flows excluded, AI-1056).CodexConfigTomlrefactored to consume it (no behavior change for Claude/Codex).JsonMcpConfigWriter— generic non-destructive JSON MCP-config writer mirroring theCodexConfigTomlengine: fail-closed on malformed / wrong-type (never clobbers), non-destructive merge (preserves user servers + surrounding config), idempotent, atomic temp+rename, and self-heals stale owned entries viaJsonNode.DeepEquals. Renders Standard / Copilot (type:"stdio") / OpenCode (mcpblock,type:"local", command-as-array,enabled:true) shapes.McpMarker— ownership sidecar (.kcap-mcp-versionnext to user-scope config, else~/.kcap/mcp-markers/<harness>-<hash>.json); identifies kcap-owned entries so unregister/heal never touch a user look-alike.McpConfigShape— per-harness render descriptor.kcap/.mcp.json(4) /.codex-mcp.json(3) must match the canonical list.The new writer/marker/shape are intentionally unwired (no production callers yet) — per-harness wiring is deferred to the epic's per-harness issues.
Tests
Deferred (Minor, non-blocking)
KcapMcpServers.ForCodexrecomputes its filtered array (trivial; called twice per setup).Register_does_not_clobber_user_authored_kcap_lookaliketest is tautological (real coverage lives inRegister_preserves_unrecorded_kcap_named_user_server).McpMarker.Recordadditive-merge semantics not pinned by a test.Part of AI-1224. Follow-ons: AI-1233 (server-side cross-harness readiness), per-harness issues (AI-699 / AI-1226–1230), AI-1231 (Pi spike).
🤖 Generated with Claude Code