Skip to content

feat(asm/mhp): wire MCP into Claude CLI subprocess + bootstrap mcp-host-side-proposals#431

Open
Luis85 wants to merge 21 commits into
developfrom
fix/asm-mcp-config-wiring
Open

feat(asm/mhp): wire MCP into Claude CLI subprocess + bootstrap mcp-host-side-proposals#431
Luis85 wants to merge 21 commits into
developfrom
fix/asm-mcp-config-wiring

Conversation

@Luis85
Copy link
Copy Markdown
Owner

@Luis85 Luis85 commented May 24, 2026

Summary

Two bundled changes (per /spec:start direction to bundle code + spec scaffold):

1. MCP wiring fix (ASM)

The in-process MCP server (ADR-013/ADR-018) ran on a loopback port but the Claude CLI subprocess was never told about it. The embedded sidepanel agent reported "no MCP servers" and a terminal claude launched inside the vault saw nothing either.

  • buildSubprocessArgs gains INV-7: emit --mcp-config <json> when caller supplies a non-empty payload.
  • ClaudeSubprocessAdapter + runSubprocessStructured accept a getMcpConfigJson dep, read on every spawn so toggling mcpServerEnabled takes effect on the next turn.
  • PluginCore gains optional onMcpServerStarted / onMcpServerStopped lifecycle hooks (mirrors isMcpServerEnabled).
  • Plugin mirrors the loopback URL to .mcp.json at the vault root via the low-level vault adapter (so dotfiles overwrite cleanly across restarts). Opt-out via new writeProjectMcpConfig setting + UI toggle.
  • Result: terminal-CLI parity. A claude session launched inside the vault picks up the same MCP server as the embedded Specorator sidepanel.

2. mcp-host-side-proposals feature bootstrap (MHP)

Closes #430 (eventually). The MCP ProposalStore is currently orphaned — no UI calls acceptProposal / rejectProposal, so writes from any client (sidepanel, Claude Desktop, terminal claude, Cursor) queue and never commit. This PR lays the scaffolding:

  • specs/mcp-host-side-proposals/workflow-state.md (stage: idea, area: MHP)
  • issues/430-mcp-host-side-proposals.md (local PRD shadow)
  • discovery/obsidian-cli-mcp-expansion/ — 7 cross-perspective research artifacts + SYNTHESIS.md with the phased recommendation that drives the feature's scope

The feature itself follows the standard /spec:idea → /spec:research → … pipeline starting from this commit.

Test plan

  • npm run typecheck clean
  • npm run lint 0 errors (warnings unchanged)
  • npm run test 2613/2613 pass (+13 new)
  • Deployed to D:\TestVault via build:deploy
  • Verified embedded sidepanel agent sees specorator MCP
  • Verified terminal claude inside vault picks up .mcp.json
  • Verified .mcp.json cleanly overwrites on restart (dotfile-adapter path)
  • Reviewer: confirm INV-7 emits --mcp-config only when payload non-empty
  • Reviewer: confirm onMcpServerStopped removes .mcp.json when toggle flipped off

Related

Symprowire added 11 commits May 24, 2026 11:15
…irror to .mcp.json

Previously the in-process MCP server (ADR-013/ADR-018) ran on a loopback
port but the Claude CLI subprocess was never told about it. The embedded
agent reported no available MCP servers, and a `claude` session launched
from a terminal inside the vault saw nothing either.

This change:

- Adds INV-7 to `buildSubprocessArgs`: when a non-empty `mcpConfigJson`
  payload is supplied, the assembler emits `--mcp-config <json>` so the
  Claude CLI loads it as a per-invocation MCP server map.
- Threads `getMcpConfigJson` through `ClaudeSubprocessAdapter` and
  `runSubprocessStructured`. Adapter reads it on every spawn so toggling
  `mcpServerEnabled` or restarting the loopback server takes effect on
  the next turn without reinstantiating the transport.
- Adds optional `onMcpServerStarted` / `onMcpServerStopped` hooks to
  `PluginCore` so the host plugin can react to MCP lifecycle changes
  without leaking the adapter reference.
- Plugin wires the hooks to mirror the loopback URL into
  `.mcp.json` at the vault root (opt-out via the new
  `writeProjectMcpConfig` setting + UI toggle). Uses the low-level vault
  adapter so dotfiles overwrite cleanly across restarts.

The result is terminal-CLI parity: a `claude` session launched inside
the vault picks up the same MCP server as the embedded Specorator
sidepanel, automatically.
…facts

Closes the gap between the orphaned MCP `ProposalStore` and any client
(Specorator sidepanel, Claude Desktop, terminal `claude`, Cursor):

- Adds `specs/mcp-host-side-proposals/workflow-state.md` (stage: idea,
  area: MHP) tracking GitHub issue #430.
- Adds `issues/430-mcp-host-side-proposals.md` as the local PRD shadow
  of the GitHub issue.
- Lands `discovery/obsidian-cli-mcp-expansion/` — 7 cross-perspective
  research artifacts (analyst, critic, divergent-thinker, ux-designer,
  product-strategist, game-designer, user-researcher) plus SYNTHESIS.md
  with the phased recommendation that drives this feature's scope.

The feature itself (proposal_list/get/accept/reject tools, Tier-A read
expansion, DevTools opt-in surface, ADR-019 tier policy) follows the
standard /spec:idea → /spec:research → … pipeline starting from this
commit.
…opt-in)

- Part A (ux-designer): 7 flows F1-F7, IA, states, accessibility
- Part B (ui-designer): 3 new components + 1 modification; 7 NFR-MHP-011
  contrast assertions; ~40 microcopy strings authored
- Part C (architect): 12 components, 8 data types, 4 MCP tool contracts,
  8 key decisions, 9 rejected alternatives, 15 risks (5 new)
- Cross-cutting requirements coverage: 60 rows, no orphan REQs
- requirements.md amended: 7 reworded (REQ-MHP-013/-027/-030/-031/-034/-038
  + NFR-MHP-003) + 6 new (REQ-MHP-041..046)
- ADR-019 authored (Proposed, ~3150 words): tier policy, permanent
  deny-list, DevTools opt-in matrix, per-tool threat paragraphs verbatim

Gate: PASS. Handoff to architect for /spec:specify.
@Luis85 Luis85 marked this pull request as ready for review May 24, 2026 11:46
Symprowire added 10 commits May 24, 2026 13:51
…lient)

Uses @modelcontextprotocol/sdk Client + StreamableHTTPClientTransport
to drive the real ObsidianMcpServerAdapter — same wire protocol any
external client (Claude Desktop, Cline, Cursor, MCP Inspector) uses.

Exercises full proposal lifecycle: tools/list, write→pending, list,
get, accept→vault mutation, double-accept→already_decided, reject,
unknown id→proposal_not_found.

Validates the user-facing goal: "you can use the mcp in whatever client
I use".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Host-side MCP proposal queue + Tier-A read expansion + tier-policy UX

2 participants