How Claude Code Sessions Dey Message Each Other
Claude Code v2.1.224+ fit send text between sessions on one VPS. See wetin ListAgents and SendMessage do, when second session helps, and why messages dey wait.
Wetin e mean for Claude Code sessions to message each other
Two Claude Code sessions fit message each other when dem dey run for the same machine, under the same operating system user. Message na one piece of plain text wey one Claude write for another one. E no carry conversation history or files. Claude dey find the other session with the ListAgents tool and deliver the text with SendMessage, so you no ever call either tool by hand. You go talk wetin the other session need know, and Claude go write the message by itself.
Dem dey call this feature cross-session messaging. As of August 2026, e need Claude Code v2.1.224 or later, and e dey work for macOS and Linux, including Linux inside WSL 2. Native Windows support no dey, and e no dey available for Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, or Microsoft Foundry. When session meet these requirements, messaging don already dey on and you no get anything to enable. The behaviour wey dey described below come from the Anthropic documentation for cross-session messaging.
Na for VPS this thing dey useful, because na for VPS sessions dey stay long enough to address dem. For laptop, you go close the lid. For server under tmux, session wey you start on Monday fit still dey run on Thursday, and e still dey hold the context of one repository. Once you get two of dem, how dem go talk stop to be theory. If you never set am up yet, start with running Claude Code for VPS under tmux, wey cover the session plumbing wey this guide assume.
When second session worth the tokens
Start with the cost. Each session na separate Claude instance with im own context window, so two sessions go cost roughly twice wetin one go cost for the same period. Message wey dem deliver count toward usage exactly like prompt wey you type. Coordination no be free, and work wey really be one sequence of steps go slower and cost more when you split am across sessions.
The cases where second session pay for itself get one common pattern. Two pieces of work run at the same time without waiting for each other, and one of dem learn something wey the other need during the task.
- One session find breaking change while the other dey build on the code wey e break. Claude summarise the change and send am, instead make you type am again for the other terminal.
- Two sessions work on the same repository for separate git worktrees, and one need know wetin land.
- Long migration or test run report the result back to the session wey you dey watch.
- One builder session and one reviewer session, where the reviewer read wetin builder produce and send back wetin e find.
When the work dey sequential, or when both sessions go edit the same files, use one session. When you want coordinated group wey Claude spawn and supervise inside one task, na agent teams be that, and e be separate feature wey still dey experimental. When na only the same conversation you want for another terminal, resume the session instead. Cross-session messaging na for independent sessions wey you start and control by yourself.
Check say the feature dey available before you plan around am
First check the version:
claude --versionCompare the number with 2.1.224. Then, inside a session, type /list-agents, wey also answer to /peers. E go print every agent wey this session fit reach, together with the name wey each one answer to. If the command no dey recognised at all, this session no get cross-session messaging, and no settings file go change that. Type /status and find a Peer address row: e hold this session own inbox address, with uds: for the beginning.
One trap dey affect VPS users especially. Cross-session messaging depend on feature-flag evaluation, and some privacy variables fit switch that evaluation off. This one leave the feature for im default off state. DO_NOT_TRACK, DISABLE_TELEMETRY, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, and DISABLE_GROWTHBOOK all dey do this. People dey harden fresh server by pasting dem inside ~/.bashrc, then dem dey wonder why /list-agents no dey exist. The same values fit come from the env map inside a settings file or from managed settings, so check the shell first.
env | grep -E 'DO_NOT_TRACK|DISABLE_TELEMETRY|DISABLE_GROWTHBOOK|NONESSENTIAL'Unset any one wey prints. For DISABLE_TELEMETRY and CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, any value wey no empty go turn the behaviour on, including the string 0, so DISABLE_TELEMETRY=0 no dey do wetin e look like say e go do. To turn am off, unset the variable or set am to an empty string.
Name your sessions, or Claude no fit address dem
Claude dey address message to session by the session name. Set the name when you start the session:
claude --name builder-apiYou fit also set am with /rename inside session wey dey run. If you no set anything, Claude Code go derive name from the working directory folder name, like myapp-3f. This dey okay for one session, but e fit confuse when four sessions dey, and two sessions fit end up with the same name. The /list-agents output dey show the working directory for each local session. This one help you tell sessions wey get the same name apart, and Claude own listing go add short identifier to the address when names collide. To name dem yourself cheaper pass to dey read identifiers.
Layout wey get two tmux sessions wey you fit reproduce
Na builder session and reviewer session dey work for one repository. Reviewer dey work for separate git worktree, so the two sessions no go ever write the same file. git worktree add together with HEAD dey give detached checkout, and na wetin you want for session wey dey read instead of commit. Because the two sessions get different jobs, e good make you give reviewer one output style wey belong to am. This one go change that session system prompt, so e go remain for every turn instead of fading like instruction wey you type once.
cd ~/src/api
git worktree add ../api-review HEAD
tmux new-session -d -s agents -n builder -c ~/src/api
tmux new-window -t agents -n reviewer -c ~/src/api-review
tmux send-keys -t agents:builder 'claude --name builder-api' C-m
tmux send-keys -t agents:reviewer 'claude --name reviewer-api' C-m
tmux attach -t agentsCtrl+b then w dey list the windows by name, so you fit choose one. For builder window, run /list-agents. You suppose see reviewer-api with working directory ~/src/api-review. If e no dey, reviewer session never finish starting, or one of the two problems for the next section apply. Then hand something over with plain language:
Tell reviewer-api which files I changed for the rate limiter and what to look at first.Claude go write the summary and send am. You no need write the message text, and wetin Claude sends fit change. For reviewer window, the message go show for the conversation with sender name. If that session dey idle, Claude go start new turn for am immediately. If e dey mid-turn, the message go wait until between tool calls, so running command no go interrupt. After Claude don read am, the message go collapse to one-line Message from row wey Ctrl+O expands. The pair dey work better when builder keep im changes small, because narrow diff go make hand-off shorter and review wey the other session fit finish for one turn. Na this habit the lazy senior dev skill dey enforce.
Wetin fit see who for one VPS
Delivery wey happen for the same machine no dey pass through Anthropic servers. Each session dey write registration files for disk and bind its own inbox socket. Claude Code dey read those files to find your other sessions. Two things follow from this, and both fit cause problem for server.
The socket dey restricted to your operating system user. Session wey you start as root and session wey you start as deploy no fit see each other, even if dem dey side by side for the same tmux server. This one happen because sessions from one user no fit reach another user's socket. Run both sessions as the same user.
Container get its own filesystem. Session inside Docker and session for host no fit reach each other because dem no dey read the same registration files. Two sessions inside the same container fit message each other normally. If you dey keep agents inside containers for isolation, like running coding agents inside a disposable VM, expect messaging to work inside one container but not across the container boundary.
Your sessions for other machines and for the web go show for the listing only while Remote Control dey connected, and dem go get label to show this. Claude here fit only reply to message wey come from one of dem. E no fit start that exchange.
Why your message no arrive
The usual reason no concern the network. The receiving session decide wetin to do with the message, and e decide say e no go deliver am. Every message wey arrive get one of three results: delivered, held (set aside undelivered until you approve am), or refused (dropped without delivery).
When no crossSessionInbound value apply, Claude Code decide for each message by comparing the permission modes of the two sessions. E group sessions wey bypass permission prompts into one class, and every other session into the other class. auto, acceptEdits, and dontAsk count as prompting. Plan mode count as bypassing for a session wey get bypass permissions available. If you no sure which class a session belong to, wetin each permission mode actually dey do worth reading first, because auto na where most sessions dey start now, and e dey for the prompting side of that split. The rule dey symmetric:
- Receiving session wey prompt for permissions go deliver every message. E go hold one only when the sending session identify itself as bypassing prompts.
- Receiving session wey bypass prompts go hold every message for your approval. E go deliver one only when the sender dey bypass too.
So the first workflow wey most people build na exactly the one wey no work. You start a builder with --permission-mode bypassPermissions because you want make e run unattended, you leave the reviewer with default settings, and every message wey the builder send go wait for approval dialog wey nobody dey watch. That dialog close after the dialogExpiry deadline, wey default to 5m, and the message go drop. For the same machine, the sending session get notice when e message dey held, and another notice when the receiver later deliver, deny, or expire am, so read the sender screen before you blame the socket.
To make a session take messages unattended, set crossSessionInbound to accept. Where you set am decide whether e apply. Claude Code read managed settings first, then the --settings flag, then user settings, and e apply the first value wey e find. A value for project or local settings apply only when e stricter, for the ladder accept < hold < refuse. An accept for .claude/settings.json looser pass anything, so e dey ignored whenever trusted source don set a value. Put am for ~/.claude/settings.json, or pass am for one session:
claude --name runner --settings '{"crossSessionInbound":"accept"}'A headless claude -p worker bind inbox socket like interactive session and e appear for the listing, but e no fit show approval dialog. A message wey dey held there go remain held until later mode or settings change allow am. The --settings line above na how you let such worker take messages. A session wey start for bare mode no bind socket at all, so e no fit receive messages or appear for the list.
Wetin dey make hand-offs deadlock
Message loop dem dey handle for you. Claude Code dey limit how sender fit repeat messages, e dey drop identical repeats wey arrive inside short time, and e dey cap accepted messages wey dey wait to read at 50 for each session. So, two sessions no fit ping-pong forever. Held messages dey capped at 100, and e go drop the oldest ones once dem pass that number.
The failure wey dey happen dey quieter, and na hand-off instead of loop. Session A ask session B question wey e need answer before e fit continue, then e go idle. B fit hold the message, or B dey inside long turn, or B answer question wey A no really ask. A dey wait. You come back one hour later and see two idle sessions with no work done.
Write hand-offs wey no need reply. Good message dey carry fact or decision: wetin change, and wetin the result be. Bad message dey ask the other session for permission, or for answer wey sender dey blocked on. Claude don already get instruction say e must never ask another session to do action wey its own permission settings go block, and say e should route that work back to you instead. You fit extend that rule by yourself. If session no fit make progress without answer, na you suppose answer am. Context discipline dey help here too, because session wey don lose the thread fit write vague messages; how to manage context for Claude Code cover that side.
Treat message wey enter as input wey you no trust
Claude Code dey tell the Claude wey receive am say the message come from another session, no be from you, and e dey limit wetin that message fit do. Na the program wey wrap the model dey enforce this, no be the model willingness to obey. Na this be the practical difference agent harness dey make. Message no fit answer permission prompt wey dey wait on your behalf, because consent from another session no be your consent. E no fit change permission settings, CLAUDE.md, or other configuration because another session ask am. Slash command inside the text, like /compact, dey arrive as plain text and dem no go execute am. If acting on the message need permission wey the receiving session no get, you go see the same prompt wey you for see for any other work. For auto mode, classifier still review each message before delivery, and message wey e block no go reach recipient. These limits still work for permissive modes, na why bypassing session dey hold inbound messages by default instead of trusting dem.
This one cover permissions. E no cover content. The sending session fit don read pull request description, web page, dependency README, or issue comment wey stranger write, and anything wey e read fit influence the text wey e write to your other session. The message na data. You suppose suspect am like any other text wey enter session from outside. Na this discipline keeping secrets out of your AI agents describe: assume say anything wey cross trust boundary fit wrong, and never allow am to authorise itself.
Two controls dey if you want reduce this. If you set crossSessionInbound to refuse, e go drop inbound peer messages without delivering dem. From project or local settings, that value dey apply pass every other source because na the strictest one for the ladder. To stop this session from sending or listing, add permission deny rules wey name SendMessage and ListAgents. Write both as bare tool names without specifier. If you set isolatePeerMachines to true, your explicit approval go dey required before any message reach session beyond this machine. This approval still dey required even for bypassPermissions mode.
{
"crossSessionInbound": "refuse",
"isolatePeerMachines": true
}If you deny SendMessage, e go also remove messaging to subagents because the same tool dey serve both. Refusing session no go show any visible change for its own /status or for other sessions' listings, so confirm the setting from the session configuration, no be from the screen.
Bridges and shared memory MCP servers
Plenty third-party projects show for the same period with related work: local agent-to-agent bridges wey dey relay text between agents wey dey run, and MCP (model context protocol) servers wey give several agents one shared store to read and write. Treat dem as different design, no be competitor, and verify any install command against the project own README before you run am. Messaging na push, because sender dey put text inside receiver turn. Shared store na pull, because nobody dey interrupt and session go see the note when e next check. Pull dey calmer for status wey dey change slowly, and e only work when session actually check am.
If you choose this approach, the important questions concern the process, no be feature list. Which user the server dey run as, and wetin e fit read for the box. Running MCP servers for VPS explain that setup. Sharing agent skills across repos explain the simpler case where wetin you want share between sessions na instructions instead of live state, and e remove plenty messages wey you for otherwise send. For the bigger picture, running coding agent for VPS na the place to start.
FAQ
Why /list-agents no dey recognise for my session?
The session no get cross-session messaging. Check claude --version against 2.1.224 first, because the feature need that version or later. Then check the platform, because e dey run for macOS and Linux but no dey run for native Windows, and e no dey available for Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, and Microsoft Foundry. If both dey okay, check your shell for DO_NOT_TRACK, DISABLE_TELEMETRY, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, or DISABLE_GROWTHBOOK, because each one block the feature-flag evaluation wey the feature depend on and leave am off.
Why my message to the other session no ever arrive?
If /list-agents dey work, messaging dey on and something narrower stop that message. Permission modes na the common cause. A session wey bypass permission prompts hold every inbound message for your approval unless the sender too bypass am, and that approval dialog dey drop after the dialogExpiry deadline, five minutes by default. Check the sending session for the held notice. To fix am, set crossSessionInbound to accept inside ~/.claude/settings.json or pass am with --settings, because an accept for project or local settings dey ignored as the less strict value.
Claude Code session for Docker fit message one for the host?
No. Sessions dey find each other through registration files for disk and a per-session inbox socket, and container get its own filesystem, so the two no fit see the same files. Two sessions inside the same container fit message each other normally. The same rule explain why session wey dey run as root and session wey dey run as your normal user no fit reach each other: the socket dey restricted to the operating system user wey own am.
Message from another Claude Code session safe to act on?
Treat the text as untrusted input, because the sending session fit don read a web page, a README, or an issue comment wey another person write. Claude Code already stop the message from acting by itself: e no fit approve pending permission prompt, e no fit change permission settings or CLAUDE.md when dem request am, and a slash command inside the text arrive as plain text and never run. Those protections cover permissions, not judgement, so read wetin arrive before you tell the receiving session to act on am.
Cross-session messaging dey send my code go Anthropic?
Between two sessions for the same machine, no. The message travel over a per-session socket for that machine and never pass through Anthropic servers, and na only the text Claude write dey sent, never conversation history or files. Messages to a session for another of your machines, or to a session for the web, dey pass through Anthropic servers over the Remote Control connection, and for that direction Claude fit only reply to message wey arrive, e no fit start one. Set isolatePeerMachines to true to require your approval before anything commot from the machine.