How-to · Explained by Xiaohu

Claude Code sessions can now talk to each other and work as a team

We break down the official docs: two tools, three delivery outcomes, and the rule that keeps messaging separate from permission.
The tl;dr
  • Separate Claude Code sessions can now message each other. When one terminal finishes a change, Claude tells another terminal on its own.
  • What's sent is a short piece of plain text—no history, no files. Moving the whole context is a different feature.
  • The key rule: a message from another session never counts as your authorization.
⚑ This article breaks down the official Anthropic documentation; all mechanics and configuration options are taken from that page. The three spots marked "Tested by us" are actual results from a macOS machine.
01 Opening

Sessions can now send each other messages

Run several Claude Code terminals at once—one on the frontend, one on migrations, one in another worktree—and those sessions used to be sealed off from each other. None knew what the others were doing; syncing meant manual copy-paste.

That wall now has a door. When one session learns something, Claude can hand it to another on its own. It doesn't wait for you to ask—if your change affects another session's work, it proactively goes and says hi.

Official demo: the session on the left changes the database field users.name to users.display_name and tells weekly-digest in a single message. The session on the right receives a message starting with @user-profiles, figures out that "the stats query is still reading the old field," and updates the code on the spot. No copy-pasting between terminals. Video: Anthropic

You'll need Claude Code v2.1.224 or newer, running on macOS or Linux. If you meet the requirements, it's on automatically — no configuration needed.

v2.1.224
Minimum version. Our test machine ran 2.1.225 — just above the line.
3
Delivery outcomes: delivered, held for approval, or refused
5 min
Default wait time on the approval prompt; walk away and the message is dropped
0
Times same-machine messages pass through Anthropic's servers

To check if your setup supports it, run /list-agents (the command also works as /peers). If the command is recognized, the feature is on.

Tested by us: on this macOS machine, claude --version returned 2.1.225, just over the line. The environment variable CLAUDE_CODE_MESSAGING_SOCKET was indeed set, with the value /tmp/cc-socks/27983.sock — the inbox socket described in the docs was really bound. With only one session running, the list came back empty: no peers, so nothing to reach.

Session

Start Claude Code in a terminal and you have a session; open three terminals and you have three independent sessions.

Like three coworkers at their own desks — soundproofed before, now with a slot to pass notes through.

Inbox socket

A mailbox each session opens on the local machine, where other sessions drop messages.

Like the mailboxes by each apartment door — only people in the same building (machine and system user) can drop anything in.

02 What it is

A message is just plain text — no history, no files

This is the easiest thing to get wrong, so let's be clear.

A message is a piece of plain text from one Claude to another. Not conversation history, not a file, no context attached. The receiver only sees the sender's name and that text — what the other session talked about or which files it touched is completely invisible.

Here's the example message from the docs:

The DB migration is done; the new field is called tenant_id, so rebasing to main is safe now.

Example message from the official docs

That's it. One sentence.

So the boundary is clear: if what you want to move is the entire conversation — say, switching to another computer, or having a new session inherit the current context — messaging isn't the tool. That's what session resume is for.

SEND MESSAGE Session A History · Files Plain text Session B Gets the text only History & files stay behind RESUME SESSION Same session Whole context moves Another terminal
To send a note, use messaging. To move the whole conversation, use resume. Diagram by us, based on the docs.
03 How it works

Two tools, called by Claude itself — you don't send manually

Two tools power this: ListAgents discovers which sessions are reachable, and SendMessage delivers a message by name.

You never touch these tools. Claude decides whether to send, to whom, and even writes the wording itself. All you do is give a hint — "ask the session in the other terminal if the migration is done," or "tell the session working on the payment API what we just did." The actual message is Claude's call.

To see which sessions are reachable yourself, run /list-agents. The list has three categories:

1
Subagents

Agents running inside the current session. Note that Agent team members don't show up here — Claude reaches them through the team's own roster.

2
Your other local sessions

Claude Code sessions running on the same machine, including background sessions. A session only appears here if it has bound an inbox socket.

3
Sessions outside this machine

Shown only when Remote Control is connected, labeled Remote Control — these include sessions on your other machines and in the web version. These can only reply, not initiate.

NAMINGWhere session names come from

Messages are delivered by name, and names have three sources: whatever you set with /rename, what you pass at startup with --name, or — if neither — Claude Code generates one from the folder name of the working directory, like myapp-3f.

Two sessions can end up with the same name. The /list-agents output includes each session's working directory to tell them apart, and Claude's own list adds a short identifier per row, used to pin down the right one when names collide.

04 Delivery

Messages arrive between tool calls, with three possible outcomes

When a message reaches the other side, it doesn't interrupt whatever's in flight. The receiving Claude reads it in the gap between two tool calls, so a running command is never broken mid-step. If the session happens to be idle, the message simply starts a new turn.

As for whether it gets through, there are three outcomes:

A message Receiver's inbound rules Delivered to Claude Held until you approve or settings allow Refused silently dropped
Every incoming message first passes through the receiver's own inbound rules, then forks into one of three outcomes. Diagram by us, based on the docs.

Once a message is delivered, it's billed like a prompt you typed yourself. The receiver can also reply on the same channel — except in the one-way cross-machine case.

05 The safety line

A message from another session is not your authorization

This is the most carefully designed part of the feature.

When session A messages session B, Claude Code explicitly tells B: this message comes from another session, not from your human user. Then it limits what B can do with it — four restrictions, each blocking a specific bad scenario:

1
Can't approve on your behalf

A message from another session never counts as your authorization, and can't be used to answer a permission prompt waiting on you. This blocks: session A says "go ahead," and session B approves an operation you never green-lit.

2
Can't change configuration

The receiver is explicitly told never to change permission settings, CLAUDE.md, or any other config because another session said something. This blocks: starting from one message, gradually loosening your security settings.

3
Commands in messages don't execute

If a slash command appears in the message text, it's treated as plain text. Claude Code won't run it. This blocks: sneaking a command in disguised as message content.

4
Permission prompts still appear

If acting on the message needs a permission, you'll see the exact same prompt as always. This blocks: using "another session asked me to do this" to bypass the normal approval flow.

The sending side has its own constraint: Claude is told never to ask another session to do something that was already refused, blocked, or simply not allowed by its own permission settings here. In that situation, it has to hand the work back to you rather than route around the block through another session.

Both sides add up to the same principle: cross-session messaging is a channel for passing information, not a channel for gaining privilege.

06 Default rules

With no configuration, the two sessions' permission modes decide

When you haven't set anything, Claude Code looks at both sessions' permission modes. It sorts sessions into two buckets: ones that prompt you, and ones that skip prompts and act directly.

(plan mode counts as "skip" when the session has skip capability; auto, acceptEdits, and dontAsk all count as "prompt.")

The rule works like this:

ReceiverSender promptsSender skips prompts
PromptsDeliveredHeld for approval
Skips promptsHeld for approvalDelivered

It looks convoluted at first, but the logic is straightforward: a session that acts without asking is the one that most needs protection from unsolicited messages, because it will just do whatever it receives. So the looser the permissions, the tighter the inbound gate.

bypassPermissions

A permission mode where Claude stops asking you each time and just executes.

Like giving your assistant a master key — efficient, but precisely because it doesn't ask you, any note that comes in from the outside needs your eyes first.

crossSessionInbound

Your own inbound policy setting. Three values: accept delivers everything, hold holds everything, refuse drops everything.

Like setting a rule for your mailbox: take everything in, set it aside for me to review, or just seal the slot.

DIALOGWhat happens when a message is held

When a message is held, the receiver pops an approval dialog showing the sender and a preview. Three ways out:

  • Approve — the message goes to Claude
  • Reject, or just close the dialog — the message is dropped
  • Leave it alone — after dialogExpiry (default five minutes) the dialog closes on its own and the message is discarded

Held messages are capped at 100; beyond that, the oldest go. If the session's permission mode changes while a message is held, the rules are re-evaluated — what should pass now passes. If the mode becomes refuse, all held messages are dropped and every reachable sender gets a rejection notice.

The sender sees the activity too: it gets a notice when a message is held, then a follow-up on whether it was delivered, rejected, or expired. Only if a message is refused outright does the sender get no signal at all.

07 Paths

Same machine goes over a local socket; cross-machine is reply-only

Which path a message takes, and what you can send, depends on where the other session lives:

SAME MACHINE Session A Session B socket Both directions No Anthropic server Anthropic server Another machine via Remote Control Web session straight to cloud Reply-only Other side must initiate
The same-machine path stays entirely local; the other two go through Anthropic's servers and are one-way. Diagram by us, based on the docs.

"Reply-only" means the other side has to message you first before you can respond. Want to proactively reach a session on another machine? That path doesn't exist.

VISIBILITYSame-machine reachability requires "seeing the same files"

Each session registers itself in files on disk and binds its inbox socket there. When Claude lists or contacts local sessions, it reads those files — so two sessions can reach each other only if they can see the same files.

This has a practical consequence: containers have their own filesystem, so a session inside a container and a session on the host can't reach each other. But two sessions in the same container can talk, and the same applies on self-hosted runners.

One more detail that's easy to trip on: for cross-machine replies, if you're not connected to Remote Control when you send, the message still goes through (via a direct request to the Anthropic server), but it carries no return address — the other side can't reply back. Claude is told this when it sends.

If you want every message leaving the machine to require your sign-off, set isolatePeerMachines to true. Once set, even in a mode that skips all permission prompts, a reply will ask you before it leaves the machine. A true at any settings level counts, so a project config committed to the repo can turn this on, but can't turn it off. Same-machine messages are unaffected.

08 Automation

claude -p sessions can receive too; the socket is available to scripts

Unattended claude -p sessions also bind the inbox socket, can receive messages, and show up in the list — so a long-running -p worker can take instructions.

But there's a catch: -p sessions can't show approval dialogs. So if a message gets held, it stays held until a later settings change releases it. To let an unattended worker receive messages on its own, set crossSessionInbound to accept in the startup --settings file. (Setting it at the user level also works, but that applies to every session you run.)

There's also a bare mode launch option — that one doesn't bind a socket, can't receive messages, and doesn't appear in the list.

SOCKETWhere the socket is, and how to use it

Two places to find the path:

  • The Peer address line in /status, with a uds: prefix on the path
  • The CLAUDE_CODE_MESSAGING_SOCKET environment variable — available to hooks and Bash commands, and exported before any hook runs (including SessionStart). Each session exports its own; it never inherits the parent's

That means a script or a hook can drop a message into its own session. In our test the value was /tmp/cc-socks/27983.sock — the number is the session's process ID.

One platform difference worth noting. When a session's own child process (like a hook or Bash command) sends a message back in, it's delivered directly if the origin can be verified: Linux (including WSL 2) can verify even exited children; macOS only while the process is still alive; in containers where Claude Code is PID 1, it can't be verified at all. If verification is impossible, the message is treated like a normal one — so a permission-skipping session will hold it for your approval.

Whether sandboxed Bash commands can reach the socket is governed by the sandbox's Unix socket settings (sandbox.network.allowAllUnixSockets and sandbox.network.allowUnixSockets).

09 Turning it off

Receiving and sending shut off separately, each with a side effect

Receiving and sending are two independent switches, and you can flip just one:

What you want offHow
ReceivingSet crossSessionInbound to refuse — incoming messages are all dropped without delivery. Set it in project or local settings; that overrides all other sources.
Sending, and being listedAdd permission denial rules naming SendMessage and ListAgents — both as bare tool names with no arguments.
The whole organizationAdmins put both denial rules and refuse together in managed settings.

Two side effects to know about:

First, denying SendMessage also kills the ability to message subagents and team members. Same tool serves both purposes, so what you meant as "keep sessions from bothering each other" also shuts down collaboration inside the session.

Second, once it's off, nothing from the outside shows it. Claude Code still binds the socket as usual, just silently drops everything that arrives. A refusing session carries no marker in its own /status or in anyone else's list — to confirm, you have to check its config.

10 Division of labor

How it maps against resume, Agent teams, and the rest

Claude Code has several "run multiple things" mechanisms, and it's easy to pick the wrong one. The docs include a dedicated comparison, worth copying down:

What you want to doUse this
Continue the same conversation in another terminal, or bring context into a new sessionSession resume
A team that Claude spawns and directs itselfAgent teams
Watch and control many sessions from one placeAgent view
Drive a session personally from your phone or another deviceRemote Control
Push external events (CI results, chat messages) into a sessionchannels
Send a note between your own independent sessionsCross-session messaging, the subject of this article

The one-line distinction: cross-session messaging is for your own independent sessions talking to each other. The ones Claude spawns and directs use the team roster; moving the whole context is resume's job.

11 Checklist

Platform limits, provider restrictions, and message-loop throttles

ConditionRequirement
OSmacOS and Linux (including Linux inside WSL 2). Native Windows doesn't have this feature
Versionv2.1.224 or newer
ProvidersAmazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, and Microsoft Foundry don't offer it
Environment variablesThe telemetry-off variables (CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_GROWTHBOOK) also disable the feature flags this feature depends on

This last one is the easiest to miss: you may have never intended to turn off messaging, just set an environment variable to reduce telemetry — and the feature has been off the whole time. These variables can come from your shell, an env section in a settings file, or admin configuration.

TROUBLESHOOTHow to check when messages aren't going through

Run /list-agents and split the diagnosis in two:

Command not recognized: this session doesn't have the feature at all. Go down the table above, starting with claude --version.

Command works, but the message never arrived: the feature is on; the problem is finer. Could be a permission denial rule removing the two tools, the receiver's inbound control holding or dropping the message, or the target living on another machine (which is reply-only).

LIMITSTwo hard limits

Plain text only. The structured protocol messages used inside Agent teams don't leave the team.

Message loops get cut off automatically. There's rate limiting per sender; identical duplicate messages arriving in quick succession get dropped, and each session caps unread messages at 50. So two sessions ping-ponging messages at each other will stop on their own — no rescue needed.

✅ Getting Started Checklist
Source
Message your other Claude Code sessionsClaude Code Docs·Official docs
Our note
Mechanics and configuration items all come from the official docs above. The three spots marked "Tested by us" were verified on a macOS machine: version 2.1.225, CLAUDE_CODE_MESSAGING_SOCKET set to /tmp/cc-socks/27983.sock, and an empty agent list in single-session mode. The docs don't specify a message length limit, don't clarify how the "100 held" cap relates to the "50 unread" queue, and don't detail how downstream actions triggered by a received message are billed. They mention that scripts can write to the socket but don't give a protocol format. All diagrams are ours, drawn from the docs.