Multi-tool setup — Claude Code + Codex + Cursor on one machine
Sync MCP servers between three clients with one config script. Avoid port collisions and config drift.
Multi-tool setup
Three different tools, three different config formats, and they all want to talk to the same MCP servers. This recipe wires up Claude Code, Codex (OpenAI), and Cursor to read the same context file and connect to the same MCP servers. One source of truth, three clients.
Step 1: Symlink CLAUDE.md → AGENTS.md (project + global)
Project-scoped (per repo):
cd /path/to/your-project
ln -sf CLAUDE.md AGENTS.md
Globally:
cd ~/.claude
ln -sf CLAUDE.md AGENTS.md
# Codex by default reads ~/.codex/AGENTS.md — point that at the same file:
mkdir -p ~/.codex
ln -sf ~/.claude/CLAUDE.md ~/.codex/AGENTS.md
Now Claude Code (CLAUDE.md), Codex (AGENTS.md), and any other AGENTS.md-aware tool read the same content. Edit one, all see it.
Step 2: Add a Cursor rule that includes CLAUDE.md
Cursor uses MDC files in .cursor/rules/. Create one that includes the project CLAUDE.md by reference:
mkdir -p .cursor/rules
cat > .cursor/rules/main.mdc <<'EOF'
---
description: Project context for Cursor — same content as CLAUDE.md / AGENTS.md
globs: ["**/*"]
alwaysApply: true
---
@file ../CLAUDE.md
EOF
The @file directive inlines the referenced file's content into Cursor's context. Done — Cursor now sees the same project context as Claude Code and Codex.
For globally-scoped rules in Cursor, drop the same MDC into ~/.cursor/rules/ instead.
Step 3: Same MCP server, three configs
This is where the format split is real. Same server (memory.studiomeyer.io for example), three different config files.
Claude Code (~/.claude.json user scope, or .mcp.json project scope, or via CLI):
claude mcp add --transport http memory https://memory.studiomeyer.io/mcp
Or in .mcp.json (project) / ~/.claude.json (user):
{
"mcpServers": {
"memory": {
"url": "https://memory.studiomeyer.io/mcp",
"type": "http"
}
}
}
Codex (~/.codex/config.toml):
[mcp_servers.memory]
url = "https://memory.studiomeyer.io/mcp"
type = "http"
Cursor (Settings → Features → Model Context Protocol):
{
"mcpServers": {
"memory": {
"url": "https://memory.studiomeyer.io/mcp",
"type": "http"
}
}
}
For OAuth-based servers (memory.studiomeyer.io is one), the same browser-based magic-link flow runs the first time you call a tool from each client. Use the same email in all three and you land on the same tenant — the same memory data appears in Claude, Codex, and Cursor.
Step 4: Verify
Run aiguide_validate_step. The validator confirms at least one of CLAUDE.md, AGENTS.md, ~/.claude/CLAUDE.md, or ~/.codex/AGENTS.md exists. Symlinks count.
ls -la ./CLAUDE.md ./AGENTS.md ~/.claude/CLAUDE.md ~/.codex/AGENTS.md 2>/dev/null || true
Step 5: Sanity check + a known port collision
Ask the same question in each tool: "What does this project do?"
- Claude Code (run from the repo root) — should reference CLAUDE.md content.
- Codex (
codexfrom the repo root) — should reference the same content via AGENTS.md. - Cursor — open the repo, ask in chat. Same content.
If one tool gives a generic "I do not know what this project does", check that you launched it from the repo root.
Known gotcha: if you run Codex Desktop and the Codex VS Code Extension in parallel, they can fight over the OAuth callback port (1455). Symptom: the extension's first MCP login hangs. Fix: completely quit VS Code, finish the login in the Desktop app, then start VS Code again — the extension picks up the existing session.
Where the tools diverge
The symlink trick fixes the 80% (project context, conventions, rules). Three places it does not cover:
- Slash commands. Claude has
~/.claude/commands/, Codex has~/.codex/prompts/. Different formats, similar idea. Symlink one to the other only if your commands are simple Markdown bodies. - Skills. Claude-specific. No equivalent in Codex or Cursor today. If a skill is critical, mention its trigger word in CLAUDE.md so the other tools at least know about the keyword.
- Subagents. Claude-specific (Recipe 3.3). No equivalent.
Keep that in mind when you write CLAUDE.md so the rules do not reference Claude-only features the other tools cannot run. Anything cross-tool goes in CLAUDE.md/AGENTS.md. Anything Claude-only goes in .claude/-scoped files only.