Skip to main content
Kodelyth ECC
engineering

Six IDEs, One MCP Server, and the Two That Stay Manual

kodelythecc --target <ide> wires ECC's MCP server — the whole catalog plus local memory — into Claude Code, Cursor, Windsurf, Gemini, Codex, and Kiro automatically. Here is which config file each one gets, why the merge refuses to clobber, and what still needs a human.

By Kodelyth · · 7 min read

One install command fanning out to six IDE config files — Claude Code's .claude.json, Cursor's .cursor/mcp.json, Windsurf, Gemini, Kiro, and Codex's TOML — each receiving the same kodelythecc mcp server entry.

ECC ships a Model Context Protocol server that exposes the entire toolkit — every agent, skill, command, and rule, plus the local memory store — to any MCP-compatible client. That is useful only if the server is actually wired into the IDE you use, and wiring MCP by hand means finding the right config file, guessing the right JSON key, and not corrupting whatever is already in there.

kodelythecc --target <ide> does that wiring for six IDEs. This post is about which file each one gets, the one that isn't JSON, and the careful part that keeps the merge from eating your config.

What the server is

One process, stdio JSON-RPC, no network:

kodelythecc mcp
[kodelyth-mcp] ready · 2.29.0 · 16 tools · 6 prompts · 389 resources

The 16 tools are the useful surface. route_intent suggests the right specialist for a message; list_agents / get_agent (and the skill, command, rule, bundle equivalents) fetch catalog entries on demand; recall_memory and capture_memory read and write the local BM25 store. The server adds no model calls of its own — it surfaces context, and your IDE's model decides what to do with it. Local reads and local memory only; no telemetry.

One command wires the targeted IDE

Install and target an IDE in one step:

npm i -g kodelyth-ecc
kodelythecc --target cursor

The post-install step does two things. First it always registers the server in Claude Code (~/.claude.json) and Claude Desktop — those are the baseline. Then, if your --target is a non-Claude IDE whose config ECC can safely merge, it wires the server there too:

━ ECC MCP server registration ─────────────────
  ✓ added: /Users/you/.claude.json
  ✓ added: /Users/you/.cursor/mcp.json
  · Restart your AI tool to pick up the server

The six auto-wired targets are claude-code, cursor, windsurf, gemini-cli, codex, and kiro. Opt out of all of it with --no-mcp-register.

Which file each IDE gets

The server definition is identical across clients; only the file location and format differ.

TargetConfig fileFormat
claude-code~/.claude.jsonJSON
cursor<project>/.cursor/mcp.jsonJSON
windsurf~/.codeium/windsurf/mcp_config.jsonJSON
gemini-cli~/.gemini/settings.jsonJSON
kiro<project>/.kiro/settings/mcp.jsonJSON
codex~/.codex/config.tomlTOML

The five JSON targets all use the same { mcpServers: { ... } } shape as Claude Code — Kiro included, because it is MCP-native — so one hardened merge handles all of them. The entry written is deliberately minimal:

{
  "mcpServers": {
    "kodelyth-ecc": { "command": "kodelythecc", "args": ["mcp"], "env": {} }
  }
}

Codex is the odd one out. It stores MCP servers in TOML as [mcp_servers.<name>] tables, so ECC writes that instead — without pulling in a TOML parser, and only when the table is absent, because appending a table is order-independent in TOML and never clobbers existing servers:

[mcp_servers."kodelyth-ecc"]
command = "kodelythecc"
args = ["mcp"]

The merge refuses to clobber

This is the part worth dwelling on, because an installer that edits your config files has one job above all others: do no harm. Reading a config file has three outcomes, not two, and collapsing them is how data gets destroyed.

An earlier version returned null for every read failure and the caller did readJson(file) || {}. So a config that merely failed to parse — one trailing comma from a hand-edit, a half-written file — was treated as empty, and the merge wrote it back containing only ECC's own entry. Measured on a realistic config: 366 bytes in, 140 bytes out, with every other MCP server and every setting gone. Silently, during an install nobody thought was risky.

The reader now distinguishes absent from unreadable:

if (cfg.state === 'unreadable') {
  throw new Error(
    `refusing to modify ${file}: it exists but could not be parsed. ` +
    `Fix or move the file, then re-run. Nothing was written.`
  );
}

Absent is safe to treat as empty and create. Unreadable is not — it is refused, with nothing written. The write itself is atomic (temp file, then rename) and preserves the file's existing permissions, and the whole thing is idempotent: run it twice and the second run reports unchanged.

What it unlocks

Once wired, the IDE's model can reach the whole ECC catalog and your memory without you attaching anything by hand. A single route_intent call turns "my build is red" into the right build-resolver; a recall_memory call surfaces how you fixed the same class of bug three weeks ago in another repo — and because the memory store is keyed by git remote, that recall works even if you've since moved the repo. The 389 resources mean every agent and skill is addressable as kodelyth://agents/<name> for clients that render resources.

What still needs a human

Two honest gaps. Cline and Roo Code store their MCP settings inside VS Code's globalStorage, a path that is editor-version-specific and fragile to guess, so ECC does not write it for you — those stay a manual paste of the same server entry. And RTK, ECC's separate shell-output compression layer, wires into a different set of targets than MCP does; it has no mapping for Kiro or Aider, so on those two you get the MCP server and memory but not RTK's input savings.

Neither gap is hidden. The installer only claims the targets it can wire safely, and stays quiet on the ones it can't — which is the right behaviour for a tool that edits files you care about.


Auto-registration shipped across the ECC 2.2x line. The per-IDE config writer, including the tri-state reader and the TOML special case, is dependency-free Node in scripts/mcp/register-self.js. See MCP Server for the full tool list and External MCP Servers for the inverse — ECC consuming Stripe, GitHub, or Postgres.

npm i -g kodelyth-ecc && kodelythecc --target cursor