Cross-Agent Configuration Migration¶
Overview¶
The agentsync migrate command translates configuration from one AI agent's format to another. It reads local agent config files, transforms them through format-specific translators, and writes the result to the target agent's config location.
No vault initialisation is required — migrate operates on local files only.
Command¶
| Flag | Required | Values | Description |
|---|---|---|---|
--from |
yes | claude, cursor, codex, copilot, vscode | Source agent |
--to |
yes | claude, cursor, codex, copilot, vscode, all | Target agent(s) |
--type |
no | global-rules, mcp, commands | Filter to one config type |
--name |
no | filename (requires --type) | Migrate a single artefact |
--dry-run |
no | — | Preview without writing |
Config Type Support Matrix¶
| From \ To | Claude | Cursor | Codex | Copilot | VS Code |
|---|---|---|---|---|---|
| Claude | — | GR, MCP, CMD | GR, MCP, CMD | GR, CMD | MCP |
| Cursor | GR, MCP, CMD | — | GR, MCP, CMD | GR, CMD | MCP |
| Codex | GR, MCP, CMD | GR, MCP, CMD | — | GR, CMD | MCP |
| Copilot | GR, CMD | GR, CMD | GR, CMD | — | — |
| VS Code | MCP | MCP | MCP | — | — |
GR = global-rules, MCP = MCP servers, CMD = commands
Migration Flow¶
flowchart TD
classDef input fill:#1a5276,color:#ffffff
classDef process fill:#1e8449,color:#ffffff
classDef decision fill:#7d3c98,color:#ffffff
classDef output fill:#b9770e,color:#ffffff
classDef skip fill:#922b21,color:#ffffff
CLI["CLI: parse --from, --to, --type, --name, --dry-run"]:::input
VALIDATE["Validate agent names and flags"]:::process
RESOLVE["Resolve targets and config types"]:::process
LOOP["For each target + config type"]:::process
LOOKUP["Lookup translator in registry"]:::decision
NO_TRANSLATOR["Skip: no translator"]:::skip
READ["Read source artefacts"]:::process
TRANSLATE["Translate content"]:::process
DETECT{"MCP? Check for secrets"}:::decision
ABORT["ABORT: secrets found"]:::skip
DRYRUN{"Dry run?"}:::decision
PREVIEW["Log preview"]:::output
WRITE["Write to target"]:::process
REPORT["Print summary"]:::output
CLI --> VALIDATE --> RESOLVE --> LOOP
LOOP --> LOOKUP
LOOKUP -->|"not found"| NO_TRANSLATOR
LOOKUP -->|"found"| READ --> TRANSLATE --> DETECT
DETECT -->|"secrets"| ABORT
DETECT -->|"clean"| DRYRUN
DRYRUN -->|"yes"| PREVIEW
DRYRUN -->|"no"| WRITE
WRITE --> REPORT
PREVIEW --> REPORT
NO_TRANSLATOR --> LOOP
Key Behaviours¶
- Overwrite on collision: If the target already has a matching entry, the source value wins.
- MCP per-server merge: Only colliding server names are overwritten; target-only servers are preserved. The merge key is target-specific: VS Code uses top-level
servers+inputs, Claude/Cursor usemcpServers, Codex uses[mcp.servers.*]TOML tables. - Secret detection: If API keys or tokens are found in MCP content (including HTTP-transport
headers.Authorization), migration aborts with a clear error. Remove literal secrets and retry. - Graceful skipping: Missing source files and unsupported pairs produce skip messages, not errors.
MCP Transport Support¶
AgentSync parses each source MCP config into a transport-aware intermediate
model before writing the target. The model represents a discriminated union
over stdio, http, and sse transports plus VS Code-specific metadata
(inputs, sandbox, sandboxEnabled, dev, envFile).
| Target | Schema | Supported transports | Lossy fields |
|---|---|---|---|
| VS Code | top-level servers + inputs (docs) |
stdio, http, sse | — |
| Claude | top-level mcpServers (stdio-only) |
stdio | non-stdio servers dropped with warning; inputs dropped with warning; stdio-only envFile/sandbox/sandboxEnabled/dev named per-server in a warning |
| Cursor | top-level mcpServers (stdio-only) |
stdio | same as Claude |
| Codex | TOML [mcp.servers.<name>] |
stdio, plus structured type/url/headers/auth for future HTTP/SSE clients |
inputs dropped with warning |
When a target cannot represent a transport, AgentSync emits an explicit
translator warning that names the dropped server and the unsupported
transport (e.g. vscode → claude (mcp): Dropped server "remote": transport
"http" is not representable…). Warnings flow into MigrateResult.warnings
so the CLI surfaces them — they are never dropped silently.
If a source migrates to a stdio-only target where every server is
unrepresentable (e.g. an all-HTTP VS Code config → Claude), the translator
skips the write rather than creating a brand-new file containing only
{"mcpServers":{}}. The warning still surfaces in MigrateResult.warnings
so the operator hears about the dropped servers.
Examples¶
Migrate everything from Claude to Cursor¶
agentsync migrate --from claude --to cursor --dry-run # preview
agentsync migrate --from claude --to cursor # apply