Skip to main content
Glama

claude-code-bridge

A small MCP server that lets one coding-agent session message another machine's session over plain SSH, and get the reply back. No cloud relay, no shared account, no extra API keys.

The internal name is cc-peer; this repository is its public home. It is published on PyPI as claude-code-bridge-mcp.

 ┌────────────────────┐      stdio (MCP)      ┌────────────┐      ssh      ┌──────────────────┐
 │  agent (host)      │ ◄───────────────────► │  cc_peer.py│ ────────────► │  agent -p        │
 │  list_peers /      │                       │  (local)   │ [--resume]    │  (remote machine)│
 │  send_message      │                       └────────────┘               └──────────────────┘
 └────────────────────┘

Why

Cross-session messaging between machines is often tied to a cloud account or a shared login. SSH is usually already set up and needs neither. So this server just uses SSH.

Each peer keeps its own conversation history: the bridge stores the remote session id and resumes it on the next message. It only starts a fresh session when the old one is provably gone. A network error never silently drops the history.

Related MCP server: Covalent Bond

Install

pipx install claude-code-bridge-mcp==1.0.0

or run it without installing:

uvx --from claude-code-bridge-mcp==1.0.0 cc-peer

Pin the version in client configs and bump it deliberately. To audit exactly what you run, install from source: python cc_peer.py.

Features

  • MCP over stdio - works with any MCP-capable client. Single file, Python standard library only.

  • list_peers - shows the configured peers and whether each is reachable.

  • send_message - sends a message, returns the reply, and keeps the conversation going across calls.

  • Session resume with stale-session detection and safe retry.

  • Windows-aware - correct quoting for both POSIX (sh) and Windows (cmd) peers.

  • Built-in self-test: cc-peer --self-test.

Quickstart

Requirements: Python 3.11+, the same agent CLI on both machines, and SSH key auth to the peer (BatchMode-friendly).

  1. Create ~/.cc-peer.json (or start from examples/cc-peer.example.json):

{
  "peers": {
    "my-server": {
      "ssh": "my-server",
      "shell": "sh",
      "cwd": "",
      "command": "agent",
      "args": [],
      "ssh_args": ["-o", "BatchMode=yes", "-o", "ConnectTimeout=10"],
      "timeout": 600
    }
  }
}
  • ssh - a ~/.ssh/config host (recommended) or user@host.

  • shell - sh for Linux/macOS peers, cmd for Windows peers.

  • cwd - optional: run the remote command from a different directory.

  • command - the remote CLI to run. It must accept -p, --session-id <id> and --resume <id>.

  • args - optional extra arguments for that command.

  1. Register the server with your MCP client. With uvx:

{
  "mcpServers": {
    "cc-peer": {
      "command": "uvx",
      "args": ["--from", "claude-code-bridge-mcp==1.0.0", "cc-peer"]
    }
  }
}

After pipx install, use "command": "cc-peer" with no args instead.

  1. Try it from the client:

list_peers()
send_message(peer="my-server", message="What is in your working directory?")

Session ids are stored in ~/.cc-peer-state.json - never commit it.

How it works

send_message runs ssh <peer> <command> -p --resume <session-id> and pipes the message to stdin. The remote session's stdout is the reply. Session ids are kept per peer in a small state file; if the remote reports that the conversation no longer exists, the bridge retries once with a fresh session id. Any other failure (timeout, unreachable host) is returned as an error without touching the stored session.

Safety notes

  • Authenticate with SSH keys and BatchMode=yes. The bridge never handles passwords and stores no secrets.

  • Everything you send becomes input to the remote session - do not pass credentials through it.

  • The bridge adds no permission-bypass flags on its own. If you add one via args, that is an explicit choice on your side.

Troubleshooting

  • ssh not found on PATH - on Windows the server falls back to the Git for Windows and Windows OpenSSH locations; if both are missing, install OpenSSH or put ssh.exe on PATH.

  • Remote replies look garbled on Windows peers - set "shell": "cmd"; quoting differs between sh and cmd.

  • No conversation found - the stored session is gone; the bridge retries once with a fresh session automatically. If it keeps happening, the remote CLI is rejecting --session-id/--resume.

Limitations

  • Both machines need the same agent CLI on PATH (the server falls back to common Windows install locations for ssh only).

  • No streaming: you receive the remote reply when the remote command finishes.

  • One conversation per peer (a single stored session id), not per topic.

  • The state file has no concurrency guard - run one bridge process per user account.

  • Deliberately small: this is a bridge, not an agent framework.

License

MIT

Available Tools

2 tools
list_peersA

List the remote machines this session can message and whether each is reachable. Each peer runs its own coding-agent session on that machine.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses that the result includes reachability per peer and that each peer runs its own coding-agent session, which helps an agent interpret results, but it says nothing about staleness of reachability, cost, or how peer identifiers relate to subsequent calls.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, with the core action and its output shape front-loaded and the clarifying definition of 'peer' following. Nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless, annotation-free discovery tool with no output schema, the description covers what it returns (messageable machines plus reachability). It falls just short on connecting the returned peers to send_message and on how reachability should be interpreted.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies. The description correctly implies there is nothing to scope the listing by, matching the empty, additionalProperties:false schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('List the remote machines this session can message') plus the scope qualifier 'this session', and the second sentence clarifies what a peer is. It is trivially distinguishable from the sibling send_message by the discovery-vs-send framing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: listing the machines 'this session can message' suggests this is the discovery step before send_message, but the description never states when to call it or that it should precede messaging. No explicit alternatives or exclusions are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_messageA

Send a message to the coding-agent session running on another machine and return its reply. The remote session keeps its own conversation history across calls; it works on that machine against its own files.

ParametersJSON Schema
NameRequiredDescriptionDefault
peerYesPeer name as listed by list_peers.
messageYesThe message text to send.
timeoutNoSeconds to wait for the remote reply. Default: peer setting or 600.
new_sessionNoStart a fresh conversation on that machine instead of continuing the existing one. Default false.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does disclose two important traits: the remote session is stateful ('keeps its own conversation history across calls') and it executes against its own remote filesystem, implying possible remote side effects. It does not cover auth/permission needs, timeout/failure behavior, or whether remote files may be modified, so it stops short of complete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the action and its return value, followed by the state model. Nothing is redundant or padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description states the call returns the remote reply, and all four parameters are fully documented in the schema. The statefulness note is a valuable addition; the only gap is timeout/error semantics and confirmation of remote file side effects, which matter for a cross-machine call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with peer, message, timeout, and new_session each documented in the schema (including defaults and the list_peers reference). The description adds no parameter-level detail beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Send a message to the coding-agent session running on another machine') and adds the outcome ('return its reply'), which distinguishes it from the sibling list_peers. An agent can identify the operation without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the purpose: it is the tool for talking to a remote session, with list_peers as the natural prerequisite for discovering 'peer' values. However, the description never explicitly says when to use this instead of alternatives, nor does it state exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.1.0
    • First observedlist_peers
    • First observedsend_message

TDQS

A4.1/5.0

Scored across 2 tools

Disambiguation5/5

list_peers and send_message have completely distinct purposes—one enumerates reachable peers, the other transmits a message and returns a reply. There is no plausible way to confuse them.

Naming Consistency5/5

Both names follow a clean verb_noun snake_case pattern (list_peers, send_message), with consistent, predictable verb choice.

Tool Count4/5

Two tools is slightly thin for the stated peer-messaging scope, but each earns its place and the surface is not padded. A minimal discovery+send pair is a reasonable design.

Completeness4/5

The core lifecycle—discover peers, send a message, get a reply—is fully covered. Minor gaps exist (e.g. broadcasting to multiple peers or inspecting message history), but agents can work around them by iterating over peers.

Maintenance

ActivityNo data
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables peer-to-peer communication between Claude Code sessions, allowing them to send messages, hand off tasks, and coordinate across worktrees without manual intervention.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables a coding agent to ask another person's coding agent questions across different machines, networks, and subscriptions, with revocable directional permission and a locked-down responder session enforced by configuration.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables coding agents to communicate with each other by sending messages and waiting for replies across sessions, supporting agents like Claude Code, Codex, and Grok.
    MIT