Skip to main content
Glama

claudex

A tiny, standalone bridge between Claude Code and Codex. Run them side by side and let them talk to each other — pass questions, hand off work, report back — through a shared local mailbox.

claudex = Claude + Codex. The two fused into one is the bridge.

  • No server, no network, no tokens. Messages are plain JSON files under ~/.local/state/claudex/. Both sides just read and write the same directory on local disk.

  • Symmetric over MCP. You register one MCP server in both CLIs. Claude identifies as claude, Codex as codex, and each gets the same five tools.

  • Zero dependencies. Pure Node built-ins (Node ≥ 18).

  • Fails open. The Claude-side hooks never block, steer, or inject anything into Claude; if nothing is listening, they silently do nothing.

How they talk

┌──────────────┐   bridge_send / bridge_inbox   ┌──────────────┐
│  Claude Code │ ─────────────▶  ◀───────────── │    Codex     │
│  (peer:claude)│      ~/.local/state/claudex/   │ (peer:codex) │
└──────────────┘        rooms/<room>/*.json      └──────────────┘
        │  SessionStart / Stop / Notification hooks (Claude → bridge, one way)
        └────────────────────────────▶ presence notes Codex can read

Both sessions share a single default room, so any Claude + any Codex on your machine are connected out of the box. To isolate a project, set CLAUDEX_ROOM=my-project in both.

Related MCP server: claude-intercom

Setup

Clone the repo, then wire it into each tool. claudex init prints the exact lines with absolute paths filled in:

git clone https://github.com/arpan1221/claudex.git
cd claudex
node bin/claudex.mjs init

Claude Code — load the plugin (registers the MCP server and the presence hooks):

claude --plugin-dir /absolute/path/to/claudex

Codex — add the MCP server to ~/.codex/config.toml:

[mcp_servers.claudex]
command = "node"
args = ["/absolute/path/to/claudex/scripts/mcp.mjs"]
env = { CLAUDEX_PEER = "codex" }

That's it. Start a Claude Code session and a Codex session (anywhere on the machine, or the same folder if you set a shared CLAUDEX_ROOM) and they can message each other.

The tools (in both Claude Code and Codex)

Tool

What it does

bridge_whoami

Show your peer name, room, and where messages live.

bridge_send

Send a message. Omit to to broadcast; set to: "codex"/"claude" to direct it.

bridge_inbox

Read unread messages addressed to you (or broadcast). Reading marks them seen.

bridge_peek

View recent messages without marking anything seen.

bridge_peers

List who has posted in the room and when.

Try asking one side: "Use bridge_send to tell codex to take the frontend, then poll bridge_inbox for its reply."

The CLI

bin/claudex.mjs (also claudex if you npm link) lets you watch and join from a terminal:

node bin/claudex.mjs watch          # live-print new messages as they arrive
node bin/claudex.mjs send "ping"    # post a message as peer "cli"
node bin/claudex.mjs read           # read your unread messages
node bin/claudex.mjs peers          # who's in the room
node bin/claudex.mjs init           # print Claude Code + Codex config

Configuration

All optional; sensible defaults mean it works with nothing set.

Variable

Default

Purpose

CLAUDEX_PEER

claude (plugin) / cli

Your identity in the room. Codex config sets this to codex.

CLAUDEX_ROOM

default

Channel name. Same value on both sides = same conversation.

CLAUDEX_HOME

~/.local/state/claudex

Where message files are stored.

CLAUDEX_TTL_MS

7 days

Messages older than this are pruned on the next read/send.

Design notes

  • Each message is a single write-once JSON file (msg-<ts>-<uuid>.json) written atomically via temp-file + rename. The two peers only ever create distinct files, so there is no write contention and no lock.

  • Each peer owns its own read cursor (read-<peer>.json) — only that peer writes it — so "mark as seen" is per-reader and race-free.

  • Hooks are Claude-side only (Codex has no hook system); they forward selected metadata — session lifecycle and notification text — never prompt contents, source files, or tool output. Those selected fields can still contain context, so keep the mailbox on your own machine.

  • This is a local, single-user coordination tool, not a secured or remotely exposed service.

Test

node --test test/*.test.mjs

License

MIT © Arpan Nookala

Related MCP Connectors

Related MCP Servers