AgentStack
MCP unreviewed MIT Self-run

Gossip

mcp-yigitkonur-gossip · by yigitkonur

Bidirectional bridge between Claude Code and Codex CLI: two AI agents, one conversation.

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add mcp-yigitkonur-gossip

Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Pipes remote content directly into a shell (remote code execution).

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Gossip? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

   ____  ___   ____ ____ ___ ____
  / ___|/ _ \ / ___/ ___|_ _|  _ \
 | |  _| | | |\___ \___ \| || |_) |
 | |_| | |_| | ___) |__) | ||  __/
  \____|\___/ |____/____/___|_|

Claude Code ⇄ Codex, whispering on the same machine.

[](https://github.com/yigitkonur/gossip/actions/workflows/ci.yml) [](LICENSE) [](go.mod)


Gossip is a small, single-binary bridge that lets Claude Code and OpenAI Codex collaborate on the same workstation — one as planner/reviewer, the other as implementer/executor — with messages flowing through a local daemon instead of you copy-pasting context.

┌─────────────┐   MCP stdio    ┌────────────┐   WebSocket   ┌───────────────┐   WS    ┌──────────────┐
│ Claude Code │ ◀────────────▶ │   Gossip   │ ◀────────────▶│ Codex TUI     │ ◀─────▶ │ codex app-   │
│             │                │   daemon   │               │ (via proxy)   │         │  server       │
└─────────────┘                └────────────┘               └───────────────┘         └──────────────┘

Table of contents

  • [Why Gossip exists](#why-gossip-exists)
  • [Install in one line](#install-in-one-line)
  • [Five-minute quick start](#five-minute-quick-start)
  • [How it works](#how-it-works)
  • [The completion loop](#the-completion-loop)
  • [Commands](#commands)
  • [Configuration](#configuration)
  • [Environment variables](#environment-variables)
  • [MCP tools exposed to Claude](#mcp-tools-exposed-to-claude)
  • [Uninstall](#uninstall)
  • [Troubleshooting](#troubleshooting)
  • [Building from source](#building-from-source)
  • [Cross-compilation](#cross-compilation)
  • [Contributing](#contributing)
  • [License](#license)

Why Gossip exists

Two things are true at once today:

  1. Claude Code is great at reading large codebases, reasoning about designs, and catching regressions before you merge.
  2. Codex CLI is great at turning concrete plans into working patches, running tests, and reproducing bugs.

Making the two agents cooperate requires a shared channel, a way to hand-off turns, and some mechanical plumbing (MCP on the Claude side, a JSON-RPC WebSocket on the Codex side). Gossip is that plumbing:

  • One background daemon per machine.
  • An MCP server Claude Code already knows how to talk to.
  • A proxy in front of codex app-server so a single Codex TUI can attach, survive reconnects, and replay messages.

You run gossip claude in Claude Code and gossip codex in a second terminal — and they can talk.

Install in one line

curl -fsSL https://raw.githubusercontent.com/yigitkonur/gossip/master/install.sh | sudo bash

This downloads the right prebuilt binary for your OS and architecture, drops it at /usr/local/bin/gossip, verifies the sha256 checksum, and runs gossip version. Re-running upgrades in place; if the target version is already installed it exits cleanly without touching anything.

# install a specific version
curl -fsSL https://raw.githubusercontent.com/yigitkonur/gossip/master/install.sh | sudo bash -s -- --version v0.2.0

# install to a user-writable dir (no sudo)
curl -fsSL https://raw.githubusercontent.com/yigitkonur/gossip/master/install.sh | bash -s -- --install-dir "$HOME/.local/bin"

# uninstall
curl -fsSL https://raw.githubusercontent.com/yigitkonur/gossip/master/install.sh | sudo bash -s -- --uninstall

> Prefer not to pipe to sudo? Inspect the script first: curl -fsSL https://raw.githubusercontent.com/yigitkonur/gossip/master/install.sh -o install.sh && less install.sh. Or [build from source](#building-from-source).

Supported targets:

| OS | Architectures | | ------- | ------------------ | | macOS | arm64, amd64 | | Linux | amd64, arm64 |

Gossip is POSIX-only: the daemon relies on Unix signals, PID files, and terminal state handling that does not exist on Windows.

Five-minute quick start

1. Install the gossip binary (see above).

2. Install Claude Code and Codex CLI. You need both on your PATH. Check with:

claude --version   # requires 2.1.80 or newer
codex --version

3. Initialize your project.

cd your-project
gossip init

gossip init does three things:

  1. Writes .gossip/config.json and .gossip/collaboration.md — the project-local configuration and the shared Claude↔Codex collaboration rules.
  2. Merges a gossip MCP server entry into .mcp.json so Claude Code auto-loads the bridge whenever it opens this directory.
  3. Merges Stop + SessionStart hooks into .claude/settings.json so the autonomous [completion loop](#the-completion-loop) runs without any extra setup.

All three merges are additive: existing MCP servers, hook entries, and settings are preserved. Re-running init is idempotent.

4. Start Claude Code. Either run Claude as usual and let it launch gossip claude via the MCP config — or start it directly:

claude  # Claude Code will spawn gossip claude in stdio mode

5. Attach the Codex TUI. In a second terminal, from the same project:

gossip codex

The first call starts the background daemon, waits for the proxy to be ready, then launches the Codex TUI pointed at the gossip proxy (--remote ws://127.0.0.1:). Either terminal (gossip claude or gossip codex) can be started first — the daemon is a singleton that the second side just attaches to.

6. Collaborate. Ask Claude to do a task that benefits from Codex review:

> "Claude, implement the new rate limiter and have Codex review it before we're done."

Claude works normally. When it believes the task is complete, it ends its reply with the tag [COMPLETION] — the Stop hook then automatically sends its summary to Codex, injects Codex's review as Claude's next turn, and loops until Codex approves (via [COMPLETED]) or a safety cap stops the loop. See [The completion loop](#the-completion-loop) for the full protocol.

For one-off sends that are not part of a review cycle — "Codex, what's the stack trace on X?" — Claude can also call the consult_codex MCP tool directly.

How it works

Gossip is five layers wearing one binary:

  1. Claude bridge (gossip claude)

Foreground stdio process. Speaks MCP to Claude Code, forwards traffic over a WebSocket to the daemon. Claude sees gossip as "just another MCP server" that exposes consult_codex and get_messages tools.

  1. Daemon (gossip daemon, auto-started)

Long-lived background supervisor. Owns the Codex subprocess lifecycle, buffers messages during brief Claude disconnects, multiplexes one Codex TUI at a time, and runs a FIFO outbound queue that blocks for [IMPORTANT]-marked Codex replies (the engine behind the completion loop). Survives Claude Code restarts and session switches.

  1. Codex proxy

A local WebSocket endpoint that the Codex TUI connects to (codex --remote). Rewrites request IDs, replays cached initialize / thread/start results when a duplicate TUI re-initialises, and rewrites userAgent strings so Codex thinks it's talking to a real app-server.

  1. Codex app-server connection

The daemon keeps one WebSocket open to codex app-server. That's the upstream authority on threads, turns, and tool calls.

  1. Hook layer (gossip hook …, wired into .claude/settings.json by gossip init)

Short-lived subprocesses Claude Code spawns at SessionStart and Stop. They read the live session transcript, detect the [COMPLETION] tag, and drive the autonomous review cycle with Codex via the daemon's blocking queue. No state of their own; all state lives in the daemon or in /loop-state.json (per-user, not per-project — see the State directory bullet below).

Message path, visualised:

Claude Code ─┬─▶ gossip claude (MCP stdio)          ──┐
             │       │                                 │ consult_codex (explicit)
             │       ▼                                 │
             ├─▶ gossip hook stop (fires on [COMPLETION]) ─┤ gossip bridge send (blocking)
             │       │                                 │
             │       ▼                                 ▼
             │   gossip daemon ◀── TUI state, killed sentinel,
             │       │              loop queue, message buffer, thread ID
             │       ▼
             │   gossip codex proxy ◀──── Codex TUI (ws://127.0.0.1:N)
             │       │
             │       ▼
             └── codex app-server (upstream)

Key runtime rules

  • Readiness gating. Claude can only consult_codex when the TUI is attached and a Codex thread exists. Otherwise the daemon returns a "Codex is not ready" error instead of silently dropping the message.
  • Single current TUI. Only the most-recent Codex TUI connection receives live upstream traffic. Stale TUIs are isolated.
  • Buffered replay. A short Claude disconnect doesn't lose messages — the daemon buffers up to max-buffered-messages and replays on reconnect.
  • Blocking queue for loop sends. Completion-loop pushes go through an in-memory FIFO on the daemon. If the TUI has not attached yet when the hook fires, the send waits (up to loop.perTurnTimeoutMs) and flushes automatically when Codex connects — so gossip claude and gossip codex can be started in either order without losing a loop round.
  • Killed sentinel. gossip kill writes a file that prevents auto-reconnect until you explicitly restart. This is what lets you reliably park the system.
  • State directory. Runtime files live in a per-user directory (~/Library/Application Support/Gossip on macOS, ~/.local/state/gossip on Linux) — daemon.pid, daemon.lock, status.json, gossip.log, killed, codex-tui.pid, loop-state.json.

The completion loop

The completion loop is the core productivity feature of gossip: Claude does a piece of work, announces it is done with a sentinel tag, and Codex reviews. If Codex approves, Claude writes a one-line confirmation to the user and stops. If Codex pushes back, its feedback is injected as Claude's next turn and the cycle continues — up to a hard iteration cap. All of this happens without you copy-pasting, without Claude calling tools, and without a single extra human turn.

The protocol

Two tags make the loop work. Everything else is mechanics.

| Who writes it | Tag | Meaning | | ------------- | -------------- | --------------------------------------------------------- | | Claude | [COMPLETION] | "I believe this task is done — please review." | | Codex | [COMPLETED] | "Approved. Looks correct and complete." |

Tags are matched case-insensitively on word boundaries. [COMPLETION], COMPLETION, and completion all match. COMPLETIONS and RECOMPLETION do not. The defaults deliberately avoid generic words like DONE or APPROVED (which would match ordinary prose like "I'm done with the changes" or "not approved"). Additional aliases are configurable per project in .gossip/config.json → loop.{completionTags,approvalTags} — the default LGTM approval tag demonstrates that aliases work.

The cycle

User: "Claude, refactor the rate limiter and have Codex review it."
│
▼
Claude: (plans, edits files, runs checks)
Claude: "Done. Token-bucket implementation in internal/ratelimit/, tests pass. [COMPLETION]"
│
▼ Stop hook reads the last assistant message, spots [COMPLETION],
  pushes a summary through the daemon loop queue to Codex.
│
▼
Codex (in the other terminal): (reads, inspects files, thinks)
Codex: "The bucket size should be configurable, not hard-coded at 100."
│
▼ Hook returns {decision: "block", reason: "Codex review: …"} which Claude
  receives as its next user turn.
│
▼
Claude: (reads the feedback, edits)
Claude: "Exposed bucketSize via constructor and updated tests. [COMPLETION]"
│
▼ Loop iteration 2 — same path through Codex.
│
▼
Codex: "Good. [COMPLETED]"
│
▼ Hook sees the approval tag, blocks one more time with reason
  "Codex approved. Write a one-line confirmation, no more revisions."
│
▼
Claude: "Rate limiter refactor complete; bucket size is now configurable and
         Codex signed off on the change."
│
▼ No [COMPLETION] in the last message → Stop hook exits silently →
  Claude stops for real. The user sees one clean summary.

Termination rules

The loop always ends — never hangs the session. The Stop hook terminates with an instruction to Claude in one of four ways:

  1. Approved. Codex's reply contains an approval tag → hook blocks once with "Codex approved — write a one-line confirmation". Loop state is reset to iteration 0.
  2. Iteration cap. Default 5 rounds. When Claude hits the cap without approval, the hook escalates: "Loop cap reached; summarize current state for the user and hand back for a human decision." Loop state resets.
  3. No reply. Codex is silent for loop.perTurnTimeoutMs (default 90 s) or its turn finishes without an [IMPORTANT]-marked reply → hook escalates: "Codex did not reply: <reason>. Ask the user whether to retry or abandon."
  4. Daemon unreachable. Hook treats it as branch #3 with the specific error surfaced.

When the hook does nothing

The Stop hook is deliberately conservative. It exits silently (no decision: "block") in any of:

  • loop.enabled is false, or GOSSIP_LOOP_DISABLE=1 is set.
  • The last assistant message has no completion tag.
  • The last assistant message still contains a pending tool_use block — Claude is mid tool-loop, not "done".
  • The transcript file cannot be read (fail-open).

This means the loop never interferes with normal conversation. It engages only when Claude explicitly announces completion.

Loop configuration

The loop block in .gossip/config.json:

{
  "loop": {
    "enabled": true,               // master switch
    "maxIterations": 5,            // approval-less cap before the hook escalates
    "perTurnTimeoutMs": 90000,     // per-round wait for Codex's reply
    "completionTags": ["COMPLETION"],          // Claude → "review please"
    "approvalTags":   ["COMPLETED", "LGTM"]    // Codex → "approved"
  }
}

Setting loop.enabled: false (or GOSSIP_LOOP_DISABLE=1 in the environment) makes gossip hook stop a no-op, regardless of what Claude writes. Useful for CI, scripted runs, or when you want Claude to converse without the review gate.

What Codex sees

Every completion-loop push is wrapped with a short preamble so Codex understands the request regardless of what's in its own system prompt (Codex has no --append-system-prompt flag, so the prefix is the only reliable steering vector):

[gossip:review-request iter=1/max=5]
Claude believes the task below is complete. Please review and:
  - If correct and complete, include [COMPLETED] in your reply.
  - Otherwise, describe specifically what needs to change.
Task summary from Claude:
---

Codex is also instructed (via the existing require_reply mechanism) to reply with an [IMPORTANT] marker so the daemon force-forwards the answer without attention-window delay. The hook waits for that [IMPORTANT] message; a plain [STATUS] / [FYI] reply won't close the round.

Startup-order independence

Either gossip claude or gossip codex can be started first. If Claude emits [COMPLETION] while Codex is not yet attached, the daemon's loop queue holds the send in memory and pumps it the moment Codex becomes ready (EventThreadReady). The hook gets the reply within perTurnTimeoutMs either way — so you can start Claude first, prompt a task, and open Codex minutes later.

Under the hood

  • gossip hook session-start — injects a short protocol primer into the session context so Claude knows about [COMPLETION] without you adding it to a CLAUDE.md file.
  • gossip hook stop — the decision table above, with advisory-locked loop state at /loop-state.json.
  • gossip hook user-prompt — reserved, no-o

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.