Import Reference
mcporter merges your local config/mcporter.json with editor- or tool-specific config files so you can reuse servers without copying them manually. This document spells out the supported formats, the directories we scan for each import kind, and how precedence works.
#Import Pipeline
- Each resolved home or project config layer supplies its own imports (an explicit
--configselects only that file). A non-empty"imports"array puts those kinds first, followed by any omitted defaults. Without the array, the order is["cursor", "claude-code", "claude-desktop", "codex", "windsurf", "opencode", "vscode"]. - For each import kind, we read its candidate paths in order, starting with project-relative paths when supported. Every readable file contributes entries. Names collide on a “first wins” basis—once an imported name is merged, later imports with the same name are ignored unless the local config defines an override.
- Finally, any servers declared inside
mcpServerstake precedence over imports regardless of the order above.
Set "imports": [] to disable imports for that config layer. A non-empty subset (for example ["cursor", "codex"]) changes priority; it does not restrict discovery to those kinds.
#Supported Formats
- JSON containers: Cursor, Claude Code, Windsurf, and VS Code configs use JSON. We accept three shapes:
- Root-level dictionary where each key is a server (
{ "my-server": { ... } }). { "mcpServers": { ... } }(Cursor-style).{ "servers": { ... } }(older VS Code previews).- TOML container: Codex uses TOML files with
[mcp_servers.<name>]tables. Only.codex/config.tomlis recognized. - Shared fields: We convert JSON/TOML entries into mcporter’s schema, honoring
baseUrl,command(string or array),args,headers,env,bearerToken,bearerTokenEnv,description,tokenCacheDir,clientName,oauthClientId,oauthClientSecretEnv,oauthTokenEndpointAuthMethod, andauth. Extra properties are ignored. - Environment placeholders: Imported
headersandenvvalues support${VAR},${VAR:-fallback}, and whole-value$env:VAR. The${env:VAR}form used by some clients is not expanded; mcporter reports the supported alternatives before starting a request or child process.
#Import Support Matrix
| Kind | Typical owner | Format | Project paths | User paths | Notes |
|---|---|---|---|---|---|
cursor | Cursor IDE | JSON (mcpServers) | .cursor/mcp.json | macOS/Linux: ${XDG_CONFIG_HOME:-~/.config}/Cursor/User/mcp.jsonWindows: %APPDATA%/Cursor/User/mcp.json | Mirrors Cursor’s “MCP Servers” panel. Per-workspace files override the global file when both exist. |
claude-code | Claude Code (browser) | JSON (mcpServers) | .claude/settings.local.json, .claude/settings.json, .claude/mcp.json | ~/.claude/settings.json, ~/.claude/mcp.json, ~/.claude.json | settings.local.json (ignored by git) overrides settings.json, which is the shared project config; both beat the legacy mcp.json. |
claude-desktop | Claude Desktop | JSON (mcpServers) | — | macOS: ~/Library/Application Support/Claude/claude_desktop_config.jsonWindows: %APPDATA%/Claude/claude_desktop_config.jsonLinux: ~/.config/Claude/claude_desktop_config.json | Desktop Claude stores all servers per-machine, so there’s no project-relative file. |
codex | Codex | TOML ([mcp_servers.*]) | .codex/config.toml | ~/.codex/config.toml | Only config.toml is recognized; the deprecated mcp.toml filename is ignored. |
windsurf | Codeium Windsurf | JSON (mcpServers) | — | Windows: %APPDATA%/Codeium/windsurf/mcp_config.jsonmacOS/Linux: ~/.codeium/windsurf/mcp_config.json | Global-only config managed by Codeium. |
opencode | OpenCode | JSON/JSONC (mcp) | opencode.json, opencode.jsonc | OPENCODE_CONFIG overrideOPENCODE_CONFIG_DIR/opencode.json(c)macOS/Linux: ${XDG_CONFIG_HOME:-~/.config}/opencode/opencode.json(c)Windows: %APPDATA%/opencode/opencode.json(c) | Accepts comment-friendly .jsonc files and honors OpenCode’s precedence env vars. |
vscode | VS Code MCP extension | JSON (mcpServers or servers) | — | macOS: ~/Library/Application Support/Code(/Code - Insiders)/User/mcp.jsonWindows: %APPDATA%/Code(/Code - Insiders)/User/mcp.jsonLinux: ~/.config/Code(/Code - Insiders)/User/mcp.json | Stable precedes Insiders; later files contribute unique server names. |
Tip: mcporter resolves
~and$XDG_CONFIG_HOMEinside these paths automatically, so you can rely on the sameimportslist across platforms.Claude tip: keep shared servers in
.claude/settings.jsonand stash personal tweaks or credentials in.claude/settings.local.json, which Claude auto-ignores in git.
#Default Order & Overrides
- When
config/mcporter.jsonomits the"imports"key, we load imports in this order:["cursor", "claude-code", "claude-desktop", "codex", "windsurf", "opencode", "vscode"]. - If you set a non-empty
"imports"array, mcporter appends any missing defaults after your list, so shared presets stay available without extra JSON churn. - Set
"imports": []to disable auto-merging entirely (handy for CI or projects that want deterministic configs).
#Verifying & Troubleshooting
- Run
mcporter config list --source import --jsonto inspect imported definitions without contacting servers. - Use
mcporter list --verboseto inspect effective servers and their configuration sources, including local overrides. - If a server is defined in multiple tools (e.g., Cursor and OpenCode), the first import in the list wins. Reorder
"imports"or copy the entry locally viamcporter config import <kind> --copyto break ties. - When debugging OpenCode, remember that
OPENCODE_CONFIGbeats every other path. Clearing or overriding that env var is often the fastest way to validate changes. - When tests need deterministic data, follow
tests/config-imports.test.ts—it copies fixtures into a fake home directory and asserts the merged server order. Mirror that pattern when adding new import kinds.
Keeping this reference up to date is the best way to prevent “my editor has servers but mcporter can’t see them” bug reports. If you add a new import kind, update this table, add fixtures under tests/fixtures/imports, and document the format here.