open-design/packages
Xinmin Zeng 6ca4491294
fix(mcp): forward external MCP servers to OpenCode (#2174)
* fix(mcp): forward external MCP servers to OpenCode

OpenCode (and 5 other non-Claude/non-ACP runtimes) silently dropped
the user's `.od/mcp-config.json` entries at spawn time because
`server.ts` only branched on `def.id === 'claude'` and
`def.streamFormat === 'acp-json-rpc'`. The UI happily saved the
servers and the user never learned the agent process never received
them — the "ghost MCP" UX called out in #2142.

Replace the two hardcoded checks with a single `def.externalMcpInjection`
discriminator on `RuntimeAgentDef` (`claude-mcp-json` / `acp-merge` /
`opencode-env-content`). The Claude `.mcp.json` write and ACP
`mcpServers` merge paths keep their existing behavior; OpenCode now
gets its config layered in via `OPENCODE_CONFIG_CONTENT`, which
OpenCode merges on top of the user's saved `~/.config/opencode
/opencode.json` (verified against opencode-ai 1.15.5 — `opencode mcp
list` shows the injected server as `connected`).

Surface the same discriminator through `AgentInfo` so the Settings →
External MCP panel renders a banner naming the agents that DO receive
the servers and the ones that don't, with a hint to configure those
agents' own config files instead. Replaces the silent-failure UX with
explicit, actionable information.

Fixes #2142

* fix(web): scope external MCP banner to installed agents only

mrcfps's review on #2174 pointed out that `/api/agents` returns every
runtime def — including ones the user hasn't installed (those carry
`available: false`) — so the support banner was happily listing
Devin / Kimi / Kiro / Mistral Vibe under "Forwarded to" and DeepSeek /
Pi / Qoder / Qwen under "Not forwarded to" on a machine where none
of those CLIs were even present. Misleading at best, since the banner
copy reads as "agents on your system."

Filter the agents array by `available: true` before grouping by
`externalMcpInjection`. The "no enabled MCP servers" and "daemon
unreachable" short-circuits stay; add one more guard for "the user
hasn't installed a single supported CLI yet" so the banner just
disappears instead of showing two empty lines.

Verified against the local dev runtime: on a host with 7 of the 16
known agents installed, the banner now shows the actual 3+4 split
(Claude Code · Hermes · OpenCode forwarded; Codex CLI · Cursor Agent ·
Gemini CLI · GitHub Copilot CLI not), down from the previous 8+8 that
included CLIs that don't exist on the machine.

* fix(web): mark ACP runtimes as stdio-only in MCP support banner

Second review pass on #2174 (mrcfps) caught that banner was treating
every `acp-merge` runtime as fully forwarded, even though
`buildAcpMcpServers()` in `apps/daemon/src/mcp-config.ts:386` drops
every non-stdio server before spawn. Save a Higgsfield HTTP MCP and
pick Hermes — daemon hands Hermes nothing, but banner still listed
Hermes under "Forwarded to". The exact silent-failure UX the banner
was supposed to remove.

Tag ACP runtimes inline with `(stdio only)` in `renderNames`, and
when at least one ACP adapter shows up in the supported group, add a
one-sentence sibling explaining the limit. Pure presentation change
in `McpAgentSupportBanner` — no new state, no transport-aware
filtering, no contract change. Dropping the warning will be cheap to
do later if ACP grows HTTP support.

Verified against the local dev runtime with both a stdio
(`basic-memory`) and an HTTP server (Higgsfield) saved: banner now
renders "Forwarded to: Claude Code · Hermes (stdio only) · OpenCode.
ACP adapters marked stdio only receive stdio MCP servers from this
list; HTTP and SSE entries are dropped at spawn time."
2026-05-20 15:22:09 +08:00
..
agui-adapter chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
contracts fix(mcp): forward external MCP servers to OpenCode (#2174) 2026-05-20 15:22:09 +08:00
diagnostics feat(diagnostics): add one-click log export from Settings → About (#798) 2026-05-20 09:10:51 +08:00
host Add desktop updater UI flow (#2270) 2026-05-19 21:36:51 +08:00
platform chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
plugin-runtime chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
registry-protocol chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
sidecar chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
sidecar-proto Add desktop updater UI flow (#2270) 2026-05-19 21:36:51 +08:00
AGENTS.md refactor desktop host bridge (#2246) 2026-05-19 18:27:05 +08:00