Repository navigation
Description
Summary
Desktop app MCP tab and status popover show "No MCPs configured" even though opencode mcp list shows all MCPs as connected and the agent can call MCP tools successfully.
Steps to reproduce
- Configure 6 MCPs in
~/.config/opencode/opencode.json(3 local, 3 remote with OAuth) - Launch desktop app (v1.15.13, macOS arm64)
- Open status popover → MCP tab → shows "No MCPs configured"
- Open MCP selection dialog → same
- Run
opencode mcp listin terminal → all 6 showconnected
Root cause
The sidecar server lazily initializes MCP state on the first /mcp HTTP request. The state factory iterates all configured MCPs with { concurrency: "unbounded" } calling create72() on each. Remote MCPs try 2 transports (StreamableHTTP + SSE) with 30s timeouts each. If any transport stalls, the entire state init blocks forever.
Code evidence (from app.asar bundle)
Lazy state init — state factory only runs on first /mcp call:
const state22 = yield* exports_instance_state.make(
exports_Effect.fn("MCP.state")(function* () { ... })
);Unbounded concurrent connections — single stalled MCP blocks everything:
yield* exports_Effect.forEach(
Object.entries(config42),
([key2, mcp2]) => exports_Effect.gen(function* () {
const result4 = yield* create72(key2, mcp2)
.pipe(exports_Effect.catch(() => exports_Effect.void));
}),
{ concurrency: "unbounded" }
);Render shows empty during loading — UI never sees partial or loading state:
get mcp() {
return mcpQuery.isLoading ? {} : mcpQuery.data ?? {};
}MCP query disabled by default — enabled lazily via enableMcp():
const [mcpEnabled, setMcpEnabled] = createSignal(false);
// ...
{ ...input2.queryOptions.mcp(key2), enabled: mcpEnabled() },Logs confirm
- No MCP-related messages in
server.log - No MCP-related network activity in
network.log - No MCP errors in
renderer.log
The MCP service never reaches its log18.info("found", ...) log line (emitted when create72 processes each config entry), confirming state init is never entered or never completes.
Expected behavior
The status() handler should return the list of configured MCPs from config directly (showing "disabled" or "unknown") without requiring a live connection to each server. Connection should be lazy (triggered on toggle/use).
Alternatively: eager init on server boot with a global timeout so one stalled MCP cannot block the entire status endpoint.
Environment
- OpenCode Desktop 1.15.13 (packaged)
- Homebrew opencode 1.15.13
- macOS 15.x arm64
- 6 MCPs: openplan, quillby, notion (local stdio) + sanity, better-auth, context7 (remote with OAuth)
- Config:
~/.config/opencode/opencode.json(no project-level override)
Workaround
None for the desktop app. The standalone opencode serve works because its MCP state completed init in a prior session.
Activity
github-actions commentedon Jun 1, 2026
This issue might be a duplicate of existing issues. Please check:
Several of these cover the same symptom (Desktop UI showing no MCPs while CLI works correctly on v1.15.13). You may want to consolidate or cross-reference with those issues.
Hona commentedon Jun 2, 2026
Fixed by #30220