Skip to content

Desktop app shows 'No MCPs configured' — sidecar MCP state init hangs on concurrent remote connections #30159

Closed

Description

@vncsleal

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

  1. Configure 6 MCPs in ~/.config/opencode/opencode.json (3 local, 3 remote with OAuth)
  2. Launch desktop app (v1.15.13, macOS arm64)
  3. Open status popover → MCP tab → shows "No MCPs configured"
  4. Open MCP selection dialog → same
  5. Run opencode mcp list in terminal → all 6 show connected

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

  1. github-actions commented on Jun 1, 2026

    @github-actions
    Contributor

    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.

  2. Hona commented on Jun 2, 2026

    @Hona
    Member

    Fixed by #30220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions