Your Claude Code sessions can message each other. On one machine that happens over a local socket. Across machines it travels over the Remote Control connection, which makes this the one feature where Remote Control is doing work you never asked it to do.
Requires Claude Code v2.1.224 or later, on macOS or Linux including WSL2. Not available on native Windows, and not on Bedrock, Claude Platform on AWS, Google Cloud Agent Platform or Microsoft Foundry. Check with /list-agents, also aliased as /peers.
What a message actually is
A piece of plain text one Claude writes to another. Never conversation history, never files. The receiving session gets the sender name, the text, and usually a reply address, and nothing else. To move a whole conversation somewhere, resume the session instead.
Claude uses two tools, ListAgents to see what it can reach and SendMessage to deliver, so you never call either yourself. You just say what you want the other session to know:
Ask the session running in my other terminal whether the migration finished
Claude writes the message itself. What arrives looks like a sentence a colleague would send: Schema migration finished: the new column is tenant_id, and rebasing on main is safe now.
Where the other session is decides what you can do
| Other session runs | How it travels | What you can send |
|---|---|---|
| On this machine | A per-session socket, never through Anthropic servers | New messages and replies |
| On another of your machines | Through Anthropic servers, arriving over that machine’s Remote Control connection | Replies only |
| On Claude Code on the web | Through Anthropic servers to the cloud session | Replies only |
That reply-only restriction is the important asymmetry. Claude cannot start a conversation with a session on another machine. It can only answer one that arrived. So the cross-machine channel opens from the far side, and Remote Control is what holds it open.
A reply sent while the replying session is not connected to Remote Control still goes through, but it arrives with no reply address, so the receiver cannot answer it. Claude is told this when it sends.
Why a session you expect is missing from the list
Same-machine discovery works through files on disk. Each session registers itself and binds an inbox socket there, and sessions can only reach each other when they can see the same files.
So a session inside a container and a session on the host cannot message each other, because the container has its own filesystem. Two sessions inside the same container still can.
Sessions answer to the name set with /rename or --name. Without one, Claude Code derives a name from the working directory folder, such as myapp-3f. Two sessions can end up with the same name, which is why /list-agents shows working directories.
What an incoming message is not allowed to do
Claude Code tells the receiving session the message came from another session, not from you, and constrains it accordingly:
- It cannot approve anything. A message never counts as your consent, so it cannot answer a pending permission prompt.
- It cannot change configuration. Claude is instructed never to alter permission settings or
CLAUDE.mdbecause another session asked. - Commands do not run. A
/compactin the text arrives as text. - Permission prompts still fire for anything acting on the message requires.
Claude is also instructed never to ask another session to do something that was denied in its own session, and to route that back to you instead.
Controlling what arrives
Set crossSessionInbound to decide what a session does with messages from your other sessions:
| Value | Behaviour |
|---|---|
accept | Every message is delivered |
hold | A notice appears, nothing is delivered until you approve |
refuse | Messages are dropped silently |
With no value set, Claude Code decides per message from the two sessions’ permission modes. Sessions that bypass permission prompts form one class, everything else the other. A session that prompts for permissions accepts messages, except from a bypassing sender. A session that bypasses holds everything unless the sender also bypasses.
A held message opens an approval dialog showing sender and preview. Leave it and it expires after dialogExpiry, five minutes by default, and the message is dropped. Claude Code holds at most 100 messages and drops the oldest past that.
Keeping messages on one machine
If you would rather nothing left the machine without you saying so:
{
"isolatePeerMachines": true
}
That requires your explicit approval before any SendMessage reaches a session beyond this machine, and it holds even in bypassPermissions mode. A true from any settings scope applies, so a checked-in project file can turn it on but not off. Same-machine messages never prompt.
To switch the feature off completely, both directions need handling:
{
"permissions": {
"deny": ["SendMessage", "ListAgents"]
},
"crossSessionInbound": "refuse"
}
Note that denying SendMessage also removes messaging to subagents and agent-team teammates, since one tool serves all three.
Headless workers
A claude -p session binds an inbox socket like an interactive one, so a long-running worker can receive messages and shows in the listing. Bare mode does not bind one.
The catch: a -p session cannot show an approval dialog, so a held message stays held forever. To let an unattended worker take messages, start it with crossSessionInbound set to accept in its --settings value.
Loops cannot run away
Two sessions messaging each other in circles is the obvious failure mode, and it is handled. Claude Code rate-limits repeated messages per sender, drops identical repeats arriving in a short window, and caps accepted messages waiting to be read at 50 per session. A loop therefore stops on its own.
Related: background sessions for the parallel sessions you would message, worktrees for keeping their edits apart, and permission modes for the two classes the inbound default uses.