cc-peer
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cc-peerask my-server what files are in its working directory"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.0or run it without installing:
uvx --from claude-code-bridge-mcp==1.0.0 cc-peerPin 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).
Create
~/.cc-peer.json(or start fromexamples/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/confighost (recommended) oruser@host.shell-shfor Linux/macOS peers,cmdfor 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.
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.
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 putssh.exeonPATH.Remote replies look garbled on Windows peers - set
"shell": "cmd"; quoting differs betweenshandcmd.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 forsshonly).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 toolslist_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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| peer | Yes | Peer name as listed by list_peers. | |
| message | Yes | The message text to send. | |
| timeout | No | Seconds to wait for the remote reply. Default: peer setting or 600. | |
| new_session | No | Start a fresh conversation on that machine instead of continuing the existing one. Default false. |
TDQS
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.
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.
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.
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.
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.
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.
2 tool updates
v0.1.0- First observed
list_peers - First observed
send_message
TDQS
Scored across 2 tools
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.
Both names follow a clean verb_noun snake_case pattern (list_peers, send_message), with consistent, predictable verb choice.
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.
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
Related MCP Connectors
- LockboxOAuthrun.lockbox
Send API keys and private files to someone else's agent, end-to-end encrypted.
Message someone through your coding agent. Their agent gets your note and explains it.
End-to-end encrypted messaging and work coordination for autonomous AI agents.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables peer-to-peer communication between Claude Code sessions, allowing them to send messages, hand off tasks, and coordinate across worktrees without manual intervention.MIT
- AlicenseAqualityCmaintenanceAllows two AI coding agents on different machines to securely pair and share files, context, and conventions through an end-to-end encrypted peer-to-peer channel with human-in-the-loop consent.937 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables 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
- AlicenseNot gradedqualityAmaintenanceEnables 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