Bridge Claude Code and Codex on the same machine. Ask Codex for a second opinion, brainstorm across both models, or call Codex directly from Claude — all without copy/pasting.
Status: v0.1. Single-machine, single Claude ↔ single Codex. Pull-only model (Claude initiates). Push-style FYIs from Codex are deferred.
Claude Code ──MCP──▶ bridge ──WS──▶ daemon ──WS proxy──▶ codex app-server
▲
│ (WS proxy)
▼
Codex TUI
- bridge runs as an MCP stdio server inside Claude Code. It exposes
ask_codex,wait_for_codex,peers,get_messages. - daemon runs detached. It owns the proxy that sits between the Codex TUI and
codex app-server. The proxy intercepts agent messages and lets Hivemind inject prompts into the live thread. - The daemon survives across Claude restarts and idle-shuts-down after 60s with no bridge attached.
git clone https://github.com/abderrahimghazali/hivemind.git
cd hivemind
bun install
bun run build
bun link # exposes `hm` and `hivemind` on your PATHYou'll need claude and codex already on your $PATH.
In one terminal, launch Codex through the proxy:
hm codexThis boots the daemon (idempotent), spawns codex app-server, and launches the Codex TUI pointed at the proxy. Send any message in Codex once — that creates the thread Hivemind can target.
In another terminal, launch Claude with the Hivemind plugin loaded:
hm claudeNow from inside Claude:
| Slash command | What it does |
|---|---|
/hivemind:peers |
List connected peers, threads, warnings |
/hivemind:second-opinion <question> |
Ask Codex, then summarize Codex's view + Claude's view + a recommendation |
/hivemind:brainstorm <topic> |
Three rounds of back-and-forth, then a synthesis |
Or call MCP tools directly in conversation:
use
mcp__hivemind__ask_codexwithtext: "..."andwait_ms: 60000
ask_codex({ text, wait_ms? })— inject a prompt into the Codex thread. Ifwait_ms > 0, blocks until the turn completes (or the timeout) and returns the reply. Otherwise returns immediately and the reply arrives viawait_for_codex.wait_for_codex({ timeout_ms? })— block until Codex sends a message, or drain any buffered messages immediately if available.peers({})— list peer state. Reportsunsupported_session_pickerwarning if Codex opened the picker (Hivemind v0.1 only supports fresh sessions).get_messages({})— non-blocking drain of buffered messages.
hm status # daemon health, thread id, queue depth
hm logs -f # tail the daemon log
hm kill # stop the daemon and write a "killed" sentinel
hm dev # run the daemon in the foreground (logs to stderr)hm kill writes a sentinel that prevents the bridge from auto-relaunching the daemon. hm codex clears it.
| Env var | Default | Purpose |
|---|---|---|
CODEX_WS_PORT |
4600 |
Port the codex app-server listens on |
CODEX_PROXY_PORT |
4601 |
Port the Codex TUI connects to (the Hivemind proxy) |
HIVEMIND_CONTROL_PORT |
4602 |
Port the bridge ↔ daemon control channel uses |
HIVEMIND_IDLE_SHUTDOWN_MS |
60000 |
Idle timeout before the daemon shuts itself down |
HIVEMIND_STATE_DIR |
macOS: ~/Library/Application Support/Hivemind; Linux: $XDG_STATE_HOME/hivemind |
Where pid/log/lock live |
- Fresh sessions only. If Codex opens the session picker (e.g. you launched
codexdirectly withouthm codex, then later attached), Hivemind detects it andask_codexreturnsPICKER_DETECTED. Runhm kill && hm codexto reset. - One Codex thread at a time. Multiple TUI connections aren't multiplexed.
- Pull-only. Codex can't proactively notify Claude. Claude has to ask.
- No git writes from Codex. The bridge contract reminder tells Codex not to run
git commit/push/checkout -b/...— those hang in the Codex sandbox. Read-only git is fine.
bun run typecheck # tsc --noEmit
bun run test # bun test src
bun run check # both of the above
bun run build # bundles dist/cli.js, dist/daemon.js, plugins/hivemind/server/{bridge,daemon}.js
bun run dev # foreground daemon (or: hm dev)The proxy's protocol logic (processTuiPayload, handleAppServerPayload, injectMessage) is pure with respect to I/O — see src/codex-proxy.test.ts for fixture tests covering id rewriting, stale-conn drops, bridge id consumption, inject gates, and agent message extraction.
src/
bridge.ts # foreground entry: MCP server + daemon client
daemon.ts # detached entry: control WS + Codex proxy
codex-proxy.ts # WS proxy with JSON-RPC id rewriting (the testable core)
daemon-client.ts # bridge → daemon WS client
daemon-lifecycle.ts # pid/lock/health/spawn
claude-mcp.ts # MCP tool definitions and handlers
control-protocol.ts # bridge ↔ daemon message types
codex-protocol.ts # codex JSON-RPC types + guards
bridge-contract.ts # the contract reminder appended to every Claude → Codex message
cli.ts, cli/*.ts # `hm` subcommands
plugins/hivemind/ # Claude Code plugin (commands, .mcp.json, bundled server/)
MIT. See LICENSE.
