Preflight Checklist
What's Wrong?
When claude_desktop_config.json contains an MCP server configured with a url field (for Streamable HTTP transport per the MCP 2025-03-26 spec), Claude Desktop silently destroys the entire mcpServers section and strips some preferences keys on startup. No error is shown to the user — the config is simply rewritten with the offending entries removed.
This is a data loss bug. The app should either support the field or reject it with a visible error — not silently rewrite the user's config file.
Config Before Startup
{
"mcpServers": {
"brain-mcp": {
"url": "http://127.0.0.1:7677/mcp"
}
},
"preferences": {
"quickEntryShortcut": "off",
"launchPreviewPersistSession": true,
"allowAllBrowserActions": false,
"coworkScheduledTasksEnabled": true,
"ccdScheduledTasksEnabled": true,
"sidebarMode": "code",
"bypassPermissionsModeEnabled": true,
"coworkWebSearchEnabled": true
}
}
Config After Startup (rewritten by the app)
{
"preferences": {
"coworkScheduledTasksEnabled": true,
"ccdScheduledTasksEnabled": true,
"sidebarMode": "code",
"coworkWebSearchEnabled": true,
"bypassPermissionsModeEnabled": true,
"launchPreviewPersistSession": true
}
}
Note:
- The entire
mcpServers key is gone
quickEntryShortcut and allowAllBrowserActions preferences were also stripped
- No error dialog, no log message, no indication that the config was modified
What Should Happen?
One of:
- Support the
url field for Streamable HTTP transport, as the MCP spec defines it and Claude Code CLI already supports it via "type": "http" in ~/.claude/settings.json
- Show an error ("Unknown MCP server configuration: missing 'command' field") and leave the config file intact
- Ignore the unrecognized entry but preserve it in the file
Silently deleting user configuration is never acceptable behavior.
Context
The url field is the natural way to configure a Streamable HTTP MCP server. The MCP 2025-03-26 specification replaces the old HTTP+SSE transport with Streamable HTTP, where the server exposes a single endpoint that accepts POST requests with JSON-RPC bodies. This is how shared MCP daemons (one process serving multiple Claude sessions) should be configured — spawning a separate stdio process per session is wasteful when the server maintains shared state like a database connection pool.
Claude Code CLI already supports this via ~/.claude/settings.json:
{
"mcpServers": {
"brain-mcp": {
"type": "http",
"url": "http://127.0.0.1:7677/mcp"
}
}
}
This works correctly. The gap is that Claude Desktop's claude_desktop_config.json doesn't support the same configuration format.
Current Workaround
Using mcp-remote as a stdio-to-HTTP bridge in claude_desktop_config.json:
{
"mcpServers": {
"brain-mcp": {
"command": "npx",
"args": ["mcp-remote", "http://127.0.0.1:7677/mcp"]
}
}
}
This works but defeats the purpose — it spawns a Node.js process per session to bridge between stdio and HTTP, adding latency and process overhead that the Streamable HTTP transport was designed to eliminate.
Related Issues
Steps to Reproduce
- Edit
~/Library/Application Support/Claude/claude_desktop_config.json
- Add an MCP server with a
url field (no command):
{"mcpServers": {"test": {"url": "http://127.0.0.1:8080/mcp"}}}
- Restart Claude Desktop
- Observe that
claude_desktop_config.json has been rewritten with mcpServers removed
Environment
- macOS 15.4
- Claude Desktop (latest as of 2026-03-21)
- Claude Code 2.1.78
Preflight Checklist
What's Wrong?
When
claude_desktop_config.jsoncontains an MCP server configured with aurlfield (for Streamable HTTP transport per the MCP 2025-03-26 spec), Claude Desktop silently destroys the entiremcpServerssection and strips somepreferenceskeys on startup. No error is shown to the user — the config is simply rewritten with the offending entries removed.This is a data loss bug. The app should either support the field or reject it with a visible error — not silently rewrite the user's config file.
Config Before Startup
{ "mcpServers": { "brain-mcp": { "url": "http://127.0.0.1:7677/mcp" } }, "preferences": { "quickEntryShortcut": "off", "launchPreviewPersistSession": true, "allowAllBrowserActions": false, "coworkScheduledTasksEnabled": true, "ccdScheduledTasksEnabled": true, "sidebarMode": "code", "bypassPermissionsModeEnabled": true, "coworkWebSearchEnabled": true } }Config After Startup (rewritten by the app)
{ "preferences": { "coworkScheduledTasksEnabled": true, "ccdScheduledTasksEnabled": true, "sidebarMode": "code", "coworkWebSearchEnabled": true, "bypassPermissionsModeEnabled": true, "launchPreviewPersistSession": true } }Note:
mcpServerskey is gonequickEntryShortcutandallowAllBrowserActionspreferences were also strippedWhat Should Happen?
One of:
urlfield for Streamable HTTP transport, as the MCP spec defines it and Claude Code CLI already supports it via"type": "http"in~/.claude/settings.jsonSilently deleting user configuration is never acceptable behavior.
Context
The
urlfield is the natural way to configure a Streamable HTTP MCP server. The MCP 2025-03-26 specification replaces the old HTTP+SSE transport with Streamable HTTP, where the server exposes a single endpoint that accepts POST requests with JSON-RPC bodies. This is how shared MCP daemons (one process serving multiple Claude sessions) should be configured — spawning a separate stdio process per session is wasteful when the server maintains shared state like a database connection pool.Claude Code CLI already supports this via
~/.claude/settings.json:{ "mcpServers": { "brain-mcp": { "type": "http", "url": "http://127.0.0.1:7677/mcp" } } }This works correctly. The gap is that Claude Desktop's
claude_desktop_config.jsondoesn't support the same configuration format.Current Workaround
Using
mcp-remoteas a stdio-to-HTTP bridge inclaude_desktop_config.json:{ "mcpServers": { "brain-mcp": { "command": "npx", "args": ["mcp-remote", "http://127.0.0.1:7677/mcp"] } } }This works but defeats the purpose — it spawns a Node.js process per session to bridge between stdio and HTTP, adding latency and process overhead that the Streamable HTTP transport was designed to eliminate.
Related Issues
"type": "streamable-http", falls back to SSESteps to Reproduce
~/Library/Application Support/Claude/claude_desktop_config.jsonurlfield (nocommand):{"mcpServers": {"test": {"url": "http://127.0.0.1:8080/mcp"}}}claude_desktop_config.jsonhas been rewritten withmcpServersremovedEnvironment