# How MCP Server Configuration Is Transferred During Sync in Claude Code

> Discover how the claude sync command transfers MCP server configuration from ~/.claude/ to OpenCode, Codex, Pi, Cursor, or Droid automatically handling secrets and file merging.

- Repository: [Every/compound-engineering-plugin](https://github.com/everyinc/compound-engineering-plugin)
- Tags: internals
- Published: 2026-02-16

---

**The `claude sync` command reads MCP server definitions from `~/.claude/` and converts them to platform-specific formats for OpenCode, Codex, Pi, Cursor, or Droid, handling secrets warnings and file merging automatically.**

When managing AI coding assistants across multiple platforms, keeping MCP (Model Context Protocol) server configurations synchronized is critical. The `compound-engineering-plugin` repository from EveryInc provides a `claude sync` command that automates this transfer, translating Claude Code's native MCP format into the specific schemas required by each target platform.

## Overview of the MCP Sync Process

The synchronization operation follows a consistent three-phase pattern defined in [`src/commands/sync.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/sync.ts). First, the system loads the Claude home configuration from `~/.claude/`. Second, it performs a security scan on environment variables. Third, it dispatches to a target-specific sync function that handles the actual format conversion and file writing.

Each target platform receives MCP configuration through a dedicated `syncTo<Target>()` function located in `src/sync/<target>.ts`. These functions handle directory preparation, skill symlinking, and the critical MCP configuration conversion step.

## Step-by-Step Configuration Transfer

### Loading the Claude Home Configuration

The process begins with `loadClaudeHome()` parsing the `~/.claude/` directory structure. This produces a `ClaudeHomeConfig` object containing two key properties: an array of skills and a map of MCP servers under `config.mcpServers`. Each MCP entry includes the command, arguments, environment variables, or remote URL configuration as defined in the source JSON.

### Secret Detection and Warnings

Before any write operation occurs, the system invokes `hasPotentialSecrets()` to scan MCP `env` objects for keys that resemble secrets. This security check, implemented in [`src/commands/sync.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/sync.ts) at lines 19-31, prints a warning to the console if potentially sensitive environment variables are detected, giving users a chance to review before propagation.

### Target-Specific Dispatch

The command dispatches to the appropriate sync implementation based on the user-provided target parameter. The dispatch logic in [`src/commands/sync.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/sync.ts) at lines 87-103 handles the five supported platforms: `opencode`, `codex`, `pi`, `droid`, and `cursor`.

## Platform-Specific MCP Configuration Formats

### OpenCode: JSON Merge Strategy

For OpenCode, the sync process writes to `~/.config/opencode/opencode.json`. The implementation in [`src/sync/opencode.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/sync/opencode.ts) uses a shallow-merge strategy: it reads any existing configuration via `readJsonSafe`, then merges the new `mcp` object into the root `mcp` key.

The `convertMcpForOpenCode()` function (lines 48-74) maps Claude's generic format to `OpenCodeMcpServer` objects. Local servers receive `type: "local"` with `command`, `args`, and `environment` fields, while remote servers get `type: "remote"` with `url` and `headers`.

```jsonc
// Source: ~/.claude/mcp.json
{
  "my-local": {
    "command": "my-tool",
    "args": ["--fast"],
    "env": { "API_KEY": "123" }
  }
}

// Result: ~/.config/opencode/opencode.json
{
  "mcp": {
    "my-local": {
      "type": "local",
      "command": ["my-tool", "--fast"],
      "environment": { "API_KEY": "123" },
      "enabled": true
    }
  }
}

```

### Codex: TOML with Idempotent Markers

The Codex target writes to `~/.codex/config.toml` using a distinct marker-based approach implemented in [`src/sync/codex.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/sync/codex.ts) (lines 25-52). The system inserts a comment marker `# MCP servers synced from Claude Code` before the generated block, enabling idempotent updates.

The merge strategy reads the existing TOML content, strips any previous MCP block identified by the marker, then appends the fresh configuration. The `convertMcpForCodex()` function (lines 65-91) generates TOML sections only for **local** MCP servers, as Codex currently supports only command-based tools; remote URL-based servers are filtered out during conversion.

```toml

# Existing ~/.codex/config.toml

[general]
debug = true

# MCP servers synced from Claude Code

[mcp_servers.mytool]
command = "my-tool"
args = ["--fast"]

```

### Pi: Deep-Merged JSON with McPorter

For the Pi platform, configuration transfers to `~/.pi/agent/compound-engineering/mcporter.json`. The implementation in [`src/sync/pi.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/sync/pi.ts) (lines 37-50) performs a deep merge of the `mcpServers` object, giving precedence to newly converted entries while preserving existing structure.

The `convertMcpToMcporter()` function (lines 65-87) translates Claude MCP definitions into the *McPorter* format. Local servers receive `command`, `args`, `env`, and `headers` fields, while remote servers are converted to use `baseUrl` and `headers`. The sync process sets file permissions to `0600` (read/write for owner only) to protect potentially sensitive configuration data.

Pi agents then expose these tools through the **`mcporter_list`** and **`mcporter_call`** extensions defined in [`src/templates/pi/compat-extension.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/templates/pi/compat-extension.ts).

```jsonc
// ~/.pi/agent/compound-engineering/mcporter.json
{
  "mcpServers": {
    "my-local": {
      "command": "my-tool",
      "args": ["--fast"],
      "env": { "API_KEY": "123" },
      "headers": {}
    },
    "my-remote": {
      "baseUrl": "https://api.example.com",
      "headers": { "Authorization": "Bearer abc" }
    }
  }
}

```

### Droid and Cursor: Skills Only

Both **droid** and **cursor** targets currently **do not transfer MCP server configuration**. According to the source in [`src/sync/droid.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/sync/droid.ts) at lines 13-21, these implementations only create skill directory symlinks and skip MCP conversion entirely. The cursor implementation follows an identical pattern, focusing exclusively on skill propagation without MCP server mapping.

## Security Considerations During Transfer

The sync command implements multiple security measures. The `hasPotentialSecrets()` scan in [`src/commands/sync.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/sync.ts) (lines 19-31) analyzes MCP environment variable keys to detect potential secrets before writing to disk. For the Pi platform, the system explicitly sets file permissions to `0600` on the generated [`mcporter.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/mcporter.json), ensuring only the file owner can read or write the configuration. These measures protect sensitive API keys and tokens that may be embedded in MCP server environment variables.

## Summary

- The `claude sync` command transfers MCP server configuration from `~/.claude/` to target platforms through a three-phase process: loading, security scanning, and platform-specific conversion.
- **OpenCode** receives shallow-merged JSON at `~/.config/opencode/opencode.json` with `type: "local"` or `type: "remote"` server definitions.
- **Codex** uses marker-based TOML updates at `~/.codex/config.toml`, supporting only local command-based servers.
- **Pi** stores deep-merged JSON at `~/.pi/agent/compound-engineering/mcporter.json` with `0600` permissions, exposing tools via McPorter extensions.
- **Droid** and **Cursor** currently sync only skills, ignoring MCP server configuration entirely.
- Security checks in [`src/commands/sync.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/sync.ts) scan for potential secrets in environment variables before any file writes occur.

## Frequently Asked Questions

### What file formats does the sync command support for MCP configuration?

The sync command supports **JSON** for OpenCode and Pi, and **TOML** for Codex. OpenCode uses shallow-merged JSON at `~/.config/opencode/opencode.json`, Pi uses deep-merged JSON at `~/.pi/agent/compound-engineering/mcporter.json`, and Codex uses marker-delimited TOML at `~/.codex/config.toml`. Droid and Cursor do not currently support MCP configuration transfer.

### How does the sync command handle existing MCP configurations?

Each target platform uses a different merge strategy to preserve existing settings. OpenCode performs a **shallow merge** of the `mcp` key into [`opencode.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/opencode.json). Codex **strips previous MCP blocks** identified by a marker comment before appending new configuration. Pi performs a **deep merge** of the `mcpServers` object, giving precedence to new entries while preserving existing structure. These strategies ensure idempotent updates without destroying unrelated platform settings.

### Why does Codex only support local MCP servers?

According to the source code in [`src/sync/codex.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/sync/codex.ts) at lines 65-91, the `convertMcpForCodex()` function explicitly filters for command-based servers and ignores remote URL-based configurations. This limitation reflects Codex's current architecture, which only supports executing local command-line tools as MCP servers. Remote servers requiring HTTP endpoints are not converted or written to the TOML configuration during the sync operation.

### Are secrets in MCP environment variables safe during sync?

The sync command implements security measures to protect secrets, though users should remain cautious. Before writing any configuration, the `hasPotentialSecrets()` function in [`src/commands/sync.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/sync.ts) (lines 19-31) scans MCP `env` objects for keys that resemble secrets and prints a warning to the console. Additionally, when writing Pi configuration, the system sets file permissions to `0600` (owner read/write only) on [`mcporter.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/mcporter.json). However, secrets are still written to disk in plain text within configuration files, so users should ensure these files are not committed to version control.