Plugin .orphaned_at marker permanently disables MCP server after transient transport disconnect
Bug
After a transient MCP transport disconnect (e.g., the local MCP server daemon respawning), Claude Code writes ~/.claude/plugins/cache/<plugin>/<version>/.orphaned_at and never re-evaluates the plugin even when the daemon recovers. Result: every MCP tool that came from that plugin becomes permanently unavailable (deferred-unavailable namespace) until the user runs /clear or restarts the VS Code window.
This is reproducible in our environment any time the local MCP gateway process respawns — even when the new instance is fully healthy and serving requests.
Reproduction
- Have an MCP server running via
~/.claude/plugins/cache/<plugin>/<version>/.mcp.json. - Restart the MCP server process (simulating a respawn — e.g., on a content-equivalent regen, on a crash, or on an admin
/shutdown). - Observe a
.orphaned_atmarker appears in the plugin cache directory. - Even after the server is healthy and accepting connections, Claude Code does not re-attach.
ToolSearch(and the namespace itself) reportsdeferred-unavailable.
Investigation findings (2026-05-09)
We've shipped a server-side mitigation that signals reconnect to Claude Code, but the client-side path appears to ignore it:
- The Claude Code extension (
extension.js, ~2.1 MB minified, no source maps) contains a string reference toreconnectMcpServerbut the actual HTTP transport retry logic is not accessible to us. - The plugin (
mcp-gateway-local) is purely declarative (.mcp.json+plugin.jsononly — no transport state of its own). - Our daemon enqueues
reconnectpatch actions correctly on every plugin regen (including startup), and exposes them viaGET /api/v1/claude-code/pending-actionsfor Claude Code to poll. The patch flow is wired and verified by 7/7 unit tests in our repo. - We also fall back to bumping the
.mcp.jsonmtime(os.Chtimes) on respawn to fire the plugin manager's fs-watcher path, since content-equivalent regens preserve mtime by default.
Despite both signals being correctly sent server-side, the .orphaned_at marker remains and tools stay unavailable until either:
- The user runs
/clear(in-session MCP transport teardown + re-establish), or - An external hook deletes
.orphaned_atand touches.mcp.jsonmtime (we shipmcp-rehydrate.shfor this), or - The VS Code window is restarted.
Feature request
Any one of these would unblock us; we'd be happy with the cheapest path:
- (a) Documentation only — clarify the
.orphaned_atmarker semantics so operators know exactly what triggers it, what clears it, and what state Claude Code's MCP client is in when it's present. Right now the marker is invisible from the UI and undocumented. - (b) Automatic HTTP transport retry in the MCP client when the daemon enqueues a
reconnectaction via/api/v1/claude-code/pending-actions(or when the plugin's.mcp.jsonmtime changes). This is the canonical fix. - (c) Debug flag (e.g.,
CLAUDE_MCP_DEBUG_RECONNECT=1/--mcp-debug) that logs reconnect attempts, transport disconnects, and.orphaned_atwrite/read events to stderr or a known file. Would let us narrow down whether the issue is in transport-disconnect detection, reconnect-action consumption, or fs-watcher dispatch.
Environment
- Claude Code version: 2.1.137
- VS Code version: 1.119
- OS: Windows 11 Enterprise
Happy to provide additional logs, traces, or a minimal reproducer on request. Our local mitigation hook is at hooks/mcp-rehydrate.sh (deletes the marker + touches mtime) and works reliably as a workaround, but the client-side transport reconnect path is the canonical fix-surface that only Claude Code can address.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗