[Feature] Reconnect/restart MCP servers from Claude Code in Claude Desktop without Cmd+Q (expose /mcp UI or auto-reconnect)

Status Fixed / completed
Maintainer reply None cached
Activity 6 comments · opened Apr 28, 2026 · closed Aug 25, 2026

Setup

Claude Code now runs embedded inside the new Claude Desktop. When an MCP server dies, hangs, or needs to pick up a config change, there is no in-session way to recover from the Desktop UI:

  • The CLI's /mcp slash command (which exposes per-server reconnect / status / OAuth re-auth) isn't reachable from the Desktop CC pane. The general missing-slash-commands gap is tracked in #45399, but /mcp deserves a specific call-out because it's not just a convenience — it's the only recovery affordance.
  • Auto-reconnect is broken for stdio (#43177) and there's no reload-on-config-change anywhere (#40059), so even waiting it out doesn't help.
  • The current workaround is Cmd+Q + reopen Claude Desktop, which kills every session in the app, not just the broken one. Users with multiple Desktop CC sessions, or with Desktop sessions sharing context with mobile / Cowork, lose all of that to recover one stuck MCP.

What I'm asking for

Any one of the following would close the gap. They're listed in increasing scope; even (1) alone would unblock most users:

  1. Expose /mcp (or an equivalent affordance) inside the Desktop CC pane. A right-click on a server name, a status-bar icon, a button in a settings drawer — anything clickable that triggers the same reconnect path the CLI's /mcp already supports.
  2. Auto-reconnect on idle-disconnect for stdio MCP servers in Desktop. The pattern reported repeatedly in #43177 (transport closed after ~60s idle, server process still healthy, next call hangs 4 min) is especially painful in Desktop because the Cmd+Q reset is so heavy. The one-line fix proposed in #43177 would carry over.
  3. A "Restart MCP servers" menu item in Desktop's app menu that re-reads .mcp.json / ~/.claude.json and reconnects without tearing down the rest of the app — essentially #40059's /mcp-reload but exposed as a Desktop UI action.

Bonus: surface a status indicator (green/red dot) per MCP server in the Desktop CC pane so users can see which one is broken without opening the CLI to find out.

Repro

  1. Open Claude Desktop with Claude Code integration enabled.
  2. Configure any stdio MCP server in .mcp.json or via claude mcp add.
  3. Use it for a few tool calls, then idle the chat for ~60+ seconds.
  4. Next tool call hangs, eventually fails with a transport error.
  5. There is no UI in Desktop to reconnect just that server. The only path back to a working MCP is Cmd+Q + reopen Claude Desktop, which terminates every other open session.

Same flow happens after editing .mcp.json to add a new server, or after an OAuth token expires (#43789) — none of these have a Desktop-side recovery affordance.

Environment

  • Claude Desktop with Claude Code integration (latest)
  • macOS (also reported on Windows in adjacent issues)
  • Multiple stdio MCP servers configured

Related issues

These are adjacent but none of them, alone or together, close the specific Desktop-UI gap:

  • #43177 — stdio MCP servers never auto-reconnect (root cause + 1-line fix identified)
  • #40059 — Allow reloading MCP servers without restarting the session (CLI-focused)
  • #45933 — Add McpReconnect tool so the model can reconnect failed MCP servers
  • #51561 — Bulk MCP server reconnection for multi-server disconnect scenarios
  • #42627 — Programmatic MCP server reconnection (disable/re-enable via hook or API)
  • #53125 — Remote Control: allow MCP server reload / process restart from a remote session
  • #53298 — Reconnect action unreachable for mcpServers entries added by direct ~/.claude.json edit
  • #43789 — MCP OAuth tokens expire frequently, requiring manual /mcp reconnect
  • #45399 — Desktop app missing slash commands available in CLI (general; this issue is the MCP-specific subset)
  • #46623 — HTTP OAuth MCP servers silently fail in Claude Code inside Claude Desktop (silent-failure adjacent)
  • #47538 — Local MCP tool calls approved but never forwarded to server (Desktop + Claude Code in Desktop)

Filing this separately because the Desktop-specific UI affordance for MCP reconnect is the missing piece across all of the above — fixing /mcp parity in Desktop, or adding any of the alternatives in "What I'm asking for," would benefit users regardless of which underlying disconnect cause they hit.

View original on GitHub ↗

6 Comments

github-actions[bot] · 4 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/45399
  2. https://github.com/anthropics/claude-code/issues/40059
  3. https://github.com/anthropics/claude-code/issues/46426

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

dsarno · 4 months ago

Not a duplicate of any of the three flagged issues. To save a maintainer the round-trip:

#45399 asks for general slash-command parity in Desktop (/btw, /compact, /diff, etc.). This issue isn't asking for /mcp as a slash command — it's asking for any MCP-reconnect affordance in Desktop. A button, a menu item, auto-reconnect, or a slash command would all close it. If #45399 ships tomorrow and /mcp becomes available as a slash command in Desktop, that's one possible fix here, but it's not the only one and not the broader ask. I cited #45399 in the body as related for exactly this reason.

#40059 and #46426 are both CLI-focused asks for a /mcp reload command that re-reads .mcp.json and picks up config changes (added/removed servers). This issue is about recovery from a failed/disconnected MCP server in the Desktop UI — a separate axis. A user hits this even when their config is fine: stdio transport closes after idle (#43177), OAuth token expires (#43789), server crashes. The CLI already has /mcp reconnect for these cases; the gap is that Desktop has no equivalent surface. Hot-reloading config (the #40059/#46426 ask) wouldn't fix a stuck-but-correctly-configured MCP, and exposing /mcp reconnect in Desktop wouldn't pick up new config entries.

Concretely, the three asks are orthogonal:

| Need | #45399 | #40059 / #46426 | This issue |
|---|---|---|---|
| Slash-command parity in Desktop | ✓ | | |
| Hot-reload .mcp.json config diffs (CLI) | | ✓ | |
| Reconnect a stuck/failed MCP from Desktop UI (no Cmd+Q) | | | ✓ |

Leaving open. 👎'd the auto-bot per its instructions to prevent auto-closure.

dbraasch · 3 months ago

+1 — reproducing the same dispatch failure on macOS across three consecutive subprocess instances in a single log, including one after 18 hours idle and two within a single chat session. None of them received a tools/call despite tool calls being attempted from the UI. Corroborates #43177 as the root cause.

Setup

Custom stdio MCP for Gmail (@gongrzhe/server-gmail-autoauth-mcp via npx), used by a daily triage workflow that needs the label-write operations the built-in Gmail connector doesn't expose. Claude Desktop on macOS Apple Silicon (no Claude Code integration in the loop — confirms the bug isn't specific to that path), Node v18.20.8 (nvm). Client identifies as claude-ai v0.1.0 in the handshake; server as gmail v1.0.0.

  • Claude Desktop version: Claude 1.7196.3 (ca0c62) 2026-05-16T23:42:08.000Z
  • macOS version: 15.7.5

Reproduction — three subprocesses, zero tools/call dispatched to any of them

Sanitized excerpts from ~/Library/Logs/Claude/mcp-server-gmail.log:

````
=== HISTORICAL CONTEXT ===

May 15, ~03:16–03:33 UTC: 100-call triage run completed cleanly. Final entry:
2026-05-15T03:33:12.362Z [gmail] [info] Message from server: {"jsonrpc":"2.0","id":100,"result":{"content":[{"type":"text","text":"Batch label modification complete.\nSuccessfully processed: 1 messages\n"}]}} { metadata: undefined }

May 18, ~15:30–15:32 UTC: 7-call run completed cleanly. Final entry:
2026-05-18T15:32:35.942Z [gmail] [info] Message from server: {"jsonrpc":"2.0","id":7,"result":{"content":[{"type":"text","text":"Batch label modification complete.\nSuccessfully processed: 16 messages\n"}]}} { metadata: undefined }

=== SUBPROCESS #1 — alive ~18 hours, received zero tools/call ===

May 18 20:34:08.878 UTC — Initializing server...
May 18 20:34:08.954 UTC — Using MCP server command: /Users/[USER]/.nvm/versions/node/v18.20.8/bin/npx @gongrzhe/server-gmail-autoauth-mcp
May 18 20:34:08.954 UTC — Server started and connected successfully
May 18 20:34:09.275 UTC — Message from client: initialize (protocolVersion 2025-11-25)
May 18 20:34:10.445 UTC — Message from server: initialize response (protocolVersion 2024-11-05) — DOWNGRADE
May 18 20:34:10.450 UTC — Message from client: notifications/initialized
May 18 20:34:10.451 UTC — Message from client: tools/list (id 1)
May 18 20:34:10.460 UTC — Message from server: tools/list response (19 tools)

[silence from May 18 20:34:10 UTC to May 19 14:47:46 UTC — ~18 hours, 13 minutes, zero tools/call]

May 19 14:47:46.589 UTC — Client transport closed
May 19 14:47:46.589 UTC — Server transport closed (intentional shutdown)

=== SUBPROCESS #2 — fresh start, init + tools/list, then renderer disconnect; zero tools/call ===

May 19 14:47:54.090 UTC — Initializing server...
May 19 14:47:54.111 UTC — Server started and connected successfully
May 19 14:47:54.174 UTC — Message from client: initialize (protocolVersion 2025-11-25)
May 19 14:47:55.455 UTC — Message from server: initialize response (protocolVersion 2024-11-05) — DOWNGRADE
May 19 14:47:55.455 UTC — Message from client: notifications/initialized
May 19 14:47:55.456 UTC — Message from client: tools/list (id 1)
May 19 14:47:55.459 UTC — Message from server: tools/list response (19 tools)

[silence ~1m 21s. Tool call attempted from chat UI during this window; never appears in log.]

May 19 14:49:16.350 UTC — Client transport closed
May 19 14:49:16.350 UTC — Server transport closed (renderer released port) ← different from "intentional shutdown"

=== SUBPROCESS #3 — immediate respawn 250ms later, same pattern; zero tools/call ===

May 19 14:49:16.600 UTC — Initializing server...
May 19 14:49:16.601 UTC — Server started and connected successfully
May 19 14:49:16.655 UTC — Message from client: initialize (protocolVersion 2025-11-25)
May 19 14:49:17.812 UTC — Message from server: initialize response (protocolVersion 2024-11-05) — DOWNGRADE
May 19 14:49:17.813 UTC — Message from client: notifications/initialized
May 19 14:49:17.813 UTC — Message from client: tools/list (id 1)
May 19 14:49:17.816 UTC — Message from server: tools/list response (19 tools)

[end of log]

````

Smoking gun: grep tools/call across the full log after 2026-05-18 20:34:10 UTC returns no matches. Three subprocesses spawned successfully by Claude Desktop, all completing initialize + tools/list, none receiving a single tools/call. The dispatch failure reproduces on every fresh subprocess — not just after long idle.

Exact error in chat:

Gmail MCP hung on the first call — this is the known issue where the connector locks up and needs a Claude Desktop restart. I haven't been able to fetch a single label or any inbox data.
Quick fix: Cmd+Q on Claude Desktop, reopen, start a fresh chat, and run "triage my email" again. A clean session resets the connector.

cc #43177 (root cause + one-line fix identified)

dBlitz · 3 months ago

Concrete use-case from a production deployment — adds reproducible signal for the missing capability.

Context

We run ~16 MCP servers (Cloudflare Workers + cloudflared-routed) via project-level .mcp.json. Today we shipped an architectural cleanup (PR removing per-brand URL suffix → routing brand/tenant via BEARER_BRAND_MAP KV inside the wrapper). The PR landed cleanly, but every running Claude Code CLI session held a stale MCP client connection to the OLD URL (now dead), and tools went silently unavailable mid-session.

What we tried

  • /mcp panel manual retry — retries the cached URL, doesn't re-read .mcp.json
  • /reload-plugins — N/A for project-level .mcp.json (only fires for plugin MCP servers)
  • Auto-reconnect exponential backoff (5 attempts) — uses cached URL, marks server failed after 5
  • Community workaround kill -HUP $PPID — risks conversation-state loss

What we needed

A /mcp reload (or /mcp reconnect <server>) that re-reads .mcp.json for the named server and re-initializes the client against the (possibly new) URL — without restarting the whole REPL or losing conversation state.

Why it matters in production

Stable URLs in .mcp.json is now an architectural rule we documented internally (treat URL changes as session-restart events). But:

  1. Operational pain: in-flight subagent fan-outs (/skill-creator 6-runs eval, /feature-dev 3-explorer phase) can't be re-run cheaply on session restart. A 30-60min eval that just landed Phase 1 gets restarted from zero.
  2. Recovery from misconfiguration: every team will eventually edit a .mcp.json URL by accident or for a real architectural cleanup. The blast radius is "kill every running session in the org" today.

A 5-line slash command + the existing MCP client init path closes this. Bundling it with /mcp panel surface ("[Failed: 5 retries exhausted] — re-read config from .mcp.json?") would be ideal UX.

Happy to test if you ship a prerelease.

afram123 · 3 months ago

+1. Confirming on Windows (Claude Desktop with embedded Claude Code, CC v2.1.156), with the config-change trigger rather than the idle-disconnect one:

My setup is several concurrent Claude Code sessions in the Desktop app. When I add an MCP server from one session, there's no per-pane way to pick up the new tools — in the terminal I'd just close and reopen that one tab and every other session kept running, but in Desktop the only reliable reset is fully quitting and relaunching the app, which tears down every session, including ones mid-task. So adding a server in one session blocks me from testing it until all my unrelated sessions happen to hit a stopping point.

What makes this especially frustrating: the CLI already does the right thing — v2.1.139 made /mcp Reconnect re-read .mcp.json without a restart. The gap is purely that /mcp (per your point, and #45399) isn't reachable from the Desktop pane, so that existing capability can't be used here. Option (1) — exposing /mcp / a clickable reconnect in the Desktop pane — would fully close this for me. #53298 is also in scope, since servers added at user scope (~/.claude.json) are common and currently have no reconnect path at all.

Adding a Windows data point too — this is currently labeled macOS-only, but the behavior is identical here.

ryancramerdesign · 2 months ago

Adding a data point that might help others hit this:

We ran into this exact pattern: local stdio MCP server (PHP, not Node, but same shape), process stays alive and healthy, but Claude Desktop tears down the transport after 60 seconds of no tool calls. Confirmed via logs that it's the client closing the connection, not the server crashing. The process is sitting there waiting on stdin the whole time.

We tried the usual suspects first (raising execution time limits, full binary paths, testing the exact launch command manually and via launchctl to rule out environment differences). None of those made a difference, since manually-run tests never hit the timeout in the first place... we were sending input ourselves, so there was never a real idle gap.

What fixed it for us was changing the server's main read loop from a blocking read to one with a timeout (something like select()/poll() on stdin, whatever your language's equivalent is), and when that timeout fires with no input, having the server proactively send a ping request to the client rather than staying silent, something like:

{"jsonrpc": "2.0", "id": "heartbeat-<timestamp>", "method": "ping"}

We set the timeout to 30 secs (comfortably under Desktop's 60 sec cutoff) and haven't seen a disconnect since, including sitting idle for 20+ minutes.

Note that this treats the disconnect as an idle/liveness check rather than a per-request timeout, since our heartbeat isn't a response to anything pending. It's unsolicited traffic sent purely to keep the connection alive. That theory held up for us, though not sure if it generalizes to every transport/SDK combo people are hitting in this thread. But if your server implementation controls its own read loop, it might be worth trying before resorting to Cmd+Q every time.

Configurable timeout or auto-reconnect on Desktop's side (per the feature request above) would be better than servers having to work around this, but this got us unblocked in the meantime.