Two places report IDE emulation as working when it is not, and neither can surface the failure. They are the same shape as the defect #316 fixes, and as the missing terminal link provider being built alongside it: a state that reads right and is not.
1. mcpActive means "a server is listening", not "the CLI connected"
main.js:2299 (reattach) and main.js:2630 (spawn) both set it from the presence of the server object. The "IDE Emulation" badge in the terminal header is driven by it (public/file-panel.js:574-581, rendered at :1489-1508).
The proof that IDE emulation actually works is the wss.on('connection') handler in mcp-bridge.js firing — the CLI attaching to the websocket. A session where the server started and the CLI never attached shows the badge and behaves exactly as if the feature were off.
Failure scenario. The lockfile is written, the port listens, the CLI is spawned without ever connecting (a --ide that did not take, a CLI version that does not discover the lockfile, a port already claimed by a stale peer). The badge says IDE Emulation. Every file open goes nowhere, and nothing in the UI distinguishes this from a healthy session.
2. The spawn-time catch degrades silently
// main.js:2537-2545
if (sessionOptions?.mcpEmulation !== false) {
try {
mcpServer = await startMcpServer(sessionId, [spawnCwd], mainWindow, log);
claudeCmd += ' --ide';
} catch (err) {
log.error(`[mcp] Failed to start MCP server for ${sessionId}: ${err.message}`);
}
}
A session that could not register starts anyway, without --ide, and is indistinguishable from one that did except in the log. The badge is correctly off here — mcpServer stays undefined — but nothing says why, so the user sees a feature that is on in settings and absent in the session, with no route to the cause.
Scope, so the three do not overlap
Three instances of one failure mode in one subsystem argues for a rule rather than three patches: a state indicator reports the thing it claims to report, or it is not shown. Worth settling in this issue rather than separately in each fix.
Evidence
Measured on this machine, 2026-09-22. ~/.claude/ide/ empty across sessions while Global Settings showed IDE Emulation ticked; zero [mcp] lines in the app log, establishing that startMcpServer was never called rather than having failed; after saving the settings dialog once, ~/.claude/ide/40141.lock appears and the badge shows for a new session.
Separately measured, and the reason the terminal route matters at all: an agent cannot put a file in the side panel itself. openFile and openDiff are declared by the bridge (mcp-bridge.js:52-80) but the CLI exposes only getDiagnostics to it, and an OSC 8 hyperlink cannot be emitted from a tool call — its stdout is a file, and /dev/tty cannot be opened from it.
Two places report IDE emulation as working when it is not, and neither can surface the failure. They are the same shape as the defect #316 fixes, and as the missing terminal link provider being built alongside it: a state that reads right and is not.
1.
mcpActivemeans "a server is listening", not "the CLI connected"main.js:2299(reattach) andmain.js:2630(spawn) both set it from the presence of the server object. The "IDE Emulation" badge in the terminal header is driven by it (public/file-panel.js:574-581, rendered at:1489-1508).The proof that IDE emulation actually works is the
wss.on('connection')handler inmcp-bridge.jsfiring — the CLI attaching to the websocket. A session where the server started and the CLI never attached shows the badge and behaves exactly as if the feature were off.Failure scenario. The lockfile is written, the port listens, the CLI is spawned without ever connecting (a
--idethat did not take, a CLI version that does not discover the lockfile, a port already claimed by a stale peer). The badge says IDE Emulation. Every file open goes nowhere, and nothing in the UI distinguishes this from a healthy session.2. The spawn-time
catchdegrades silentlyA session that could not register starts anyway, without
--ide, and is indistinguishable from one that did except in the log. The badge is correctly off here —mcpServerstays undefined — but nothing says why, so the user sees a feature that is on in settings and absent in the session, with no route to the cause.Scope, so the three do not overlap
SETTING_DEFAULTSand the settings panel's own fallbacks, which is what made the feature off while the toggle showed on.Three instances of one failure mode in one subsystem argues for a rule rather than three patches: a state indicator reports the thing it claims to report, or it is not shown. Worth settling in this issue rather than separately in each fix.
Evidence
Measured on this machine, 2026-09-22.
~/.claude/ide/empty across sessions while Global Settings showed IDE Emulation ticked; zero[mcp]lines in the app log, establishing thatstartMcpServerwas never called rather than having failed; after saving the settings dialog once,~/.claude/ide/40141.lockappears and the badge shows for a new session.Separately measured, and the reason the terminal route matters at all: an agent cannot put a file in the side panel itself.
openFileandopenDiffare declared by the bridge (mcp-bridge.js:52-80) but the CLI exposes onlygetDiagnosticsto it, and an OSC 8 hyperlink cannot be emitted from a tool call — its stdout is a file, and/dev/ttycannot be opened from it.