claudex
by arpan1221
README.md
# claudex
**A tiny, standalone bridge between [Claude Code](https://code.claude.com) and
[Codex](https://developers.openai.com/codex/cli/).** 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** + Cod**ex**. 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.
## Setup
Clone the repo, then wire it into each tool. `claudex init` prints the exact lines with
absolute paths filled in:
```sh
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):
```sh
claude --plugin-dir /absolute/path/to/claudex
```
**Codex** — add the MCP server to `~/.codex/config.toml`:
```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:
```sh
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
```sh
node --test test/*.test.mjs
```
## License
[MIT](./LICENSE) © Arpan Nookala
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues