Carry a user's Claude Code or Codex memory and MCP servers into Muse Code.
Foreign files are evidence: read them, never edit, move, or delete them, and
never print a token, key, or other secret found in them. Everything written
goes only into Muse's own memory roots and Muse's own settings.json.
-
File: ${XDG_CONFIG_HOME:-$HOME/.config}/muse/settings.json, key
mcpServers (camelCase). Never write a mcp_servers key next to it: when
both keys are present the loader drops the whole MCP member, so every server
the user already had stops loading while the rest of the settings still
apply. If the file already carries the legacy mcp_servers key, rename it
to mcpServers (keeping its entries) in the same edit before adding
servers. Read the file first; a missing file is created as
{"schema_version": 1, "mcpServers": {...}}. Preserve every other key.
Servers Muse already defines under the same name are left alone.
-
Write contract (same as manage-settings): resolve the one path from the
environment, then use edit_file or write_file for the smallest JSON
change. If those tools reject the app-private path, fall back to a shell
edit only when the startup security context already says YOLO mode is
active (approval bypassed, shell sandbox off, workspace trusted), and then
only through a JSON parser plus atomic replace and reread; never use text
substitution. Otherwise stop and hand the user the exact mcpServers block
to paste. Never ask the user to change a security mode for this edit.
-
Entry shape:
"github": {
"type": "stdio",
"command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"],
"env": {"GITHUB_TOKEN": "<literal value>"},
"mode": "optional"
}
"docs": {"type": "streamable-http", "url": "https://example/mcp",
"headers": {"Authorization": "Bearer <literal value>"}, "mode": "optional"}
-
Mapping: Claude stdio (or a bare command) and Codex command become
type: "stdio" with command, args, env. Claude http /
streamable-http and Codex url become type: "streamable-http" with url
and headers (Codex http_headers). Never write the extraction output
itself into settings: a <redacted> entry, a url reduced to
scheme://host/..., or a key-names-only env/headers list is a summary,
not a value. Where the summary hid something (the mask also hides harmless
entries such as --keyring or --config=..., and the cut drops a query
such as ?tenant=acme), treat it like a ${VAR} value: ask the user for
it by position or key name only, write it only when they supply or approve
it, and leave the server out rather than write the placeholder or the
shortened url. Codex enabled and tool_timeout_sec
copy verbatim under the same names and take effect. Codex
startup_timeout_sec, enabled_tools, and disabled_tools also copy under
the same names but are stored, not enforced yet (spec 12857): Muse's startup
budget is fixed and every tool stays exposed, so list them in the completion
report as settings the user still has to check. Always add
"mode": "optional" so a server that fails here cannot block Muse startup
(Muse's canonical resolver parses required, but the startup gate is fed
from the typed settings carrier, which knows only mode — default required
— and drops an unknown required, so required: false alone leaves the
server in the default required mode; and never write both on one server,
because required plus mode is an ambiguous-alias fault that drops the
whole user MCP settings member, not just that server (spec 12857)).
-
Muse does not expand ${VAR} and starts stdio servers with only a small
fixed allowlist of the user's environment (HOME, PATH, USER, LANG, TERM and
similar) plus the literal env map, so a Claude ${VAR} value or a Codex
env_vars, env_http_headers, or bearer_token_env_var entry outside that
allowlist has no automatic equivalent. Tell the user which variable each
server needs; write the literal value only when the user provides or
approves it, and never echo it back. Leave the server out rather than guess.
-
Not supported in Muse, skip and report: sse, ws, sdk transports,
oauth, headersHelper, http_headers_helper, auth = "oauth". Drop
Claude timeout and alwaysLoad, Codex cwd, and approval settings with a
note.
-
After the edit, re-read the file to confirm the saved value. The change is
permanent and takes effect on the next Muse Code launch; the current session
does not load new servers.