Pular para o conteúdo principal

Cross-Session Messaging

Avançado
What you'll learn
  • Why native cross-session messaging replaces the copy-paste bridge — no daemon, no MCP server, no polling
  • The two tools Claude uses (ListAgents + SendMessage), the @mention picker, and what version each requires
  • How a message travels: same machine via a per-session socket, cross-machine via Anthropic servers over Remote Control
  • The inbound-controls state machine — accept, hold, refuse — and the default that changes based on permission mode
  • The trust boundary: a peer message never counts as your consent and never runs commands
  • When to reach for messaging vs. a subagent, a shared worktree, or Remote Control
  • Where community projects (session-bridge, claude-slack) still fit, and when they don't

The pain this solves

Two terminals, one repo problem. Terminal A works on libfoo/. Terminal B works on app-that-uses-libfoo/. B hits a type error the moment A pushes a change. Historically, you did the routing: read the error in B, switch to A, paste it, wait for a fix, switch back. Every hop lost state on both sides.

Since Claude Code v2.1.224 on macOS/Linux (and v2.1.234 on native Windows), you don't. The Claude in one session can address the Claude in another session by name, deliver a short message, and — as of v2.1.236 — ask to be told when that session next goes idle. No plugin, no daemon, no MCP server. When a session meets the requirements, messaging is on with nothing to enable.

The two tools Claude actually calls

You never call these yourself. Claude reaches for them when the moment fits, exactly like it reaches for Read or Bash.

ToolWhat it does
ListAgentsEnumerates every agent this session can reach: subagents in this session, agent-team teammates, your other local Claude Code sessions, and — while Remote Control is connected — your cloud and other-machine sessions.
SendMessageDelivers a plain-text message to one of those agents by name. The same tool also messages subagents and teammates within a single session or team, so denying it turns off intra-session delegation too.

To see what Claude sees, run the slash command /list-agents (aliased /peers). The first row is this session's own name — the address your other sessions use to reach you.

Address a target by @mention

Claude will pick the target on its own when the intent is clear from your prompt. To name a target yourself, type @ followed by the first letters of the session's name and pick from the typeahead — exactly like @-mentioning a subagent. Requires Claude Code v2.1.232 or later.

Two ways to prompt a cross-session send

# Let Claude pick the target from context
Ask the session running in my other terminal whether the migration finished.

# Name the target explicitly with @mention (v2.1.232+)
Let @api-worker know the schema migration finished — the new column is tenant_id.

Once you type at least one letter after the @, Claude Code suggests your other live local sessions. A cloud or Remote Control session only appears once Claude has already listed or messaged your beyond-this-machine sessions in that turn. Multiple live sessions can share a name; when they do, Claude asks which one you mean before sending.

How a message travels

Guided walkthrough1 of 3
  1. Delivery goes over a per-session Unix domain socket (macOS/Linux, including WSL 2) or a named pipe (native Windows). It never leaves your box. Each session's socket is user-restricted so another OS user's sessions can't post into it.

The receiving Claude reads the message between tool calls during an active turn, so a running tool is never interrupted. If the target session is idle, Claude Code starts a new turn with the message.

The inbound-controls state machine

Every session decides what happens to arriving peer messages with the crossSessionInbound setting. Three values:

ValueBehavior
acceptClaude Code delivers every message to Claude.
holdClaude Code shows a notice for each message and doesn't deliver it. If an accept later applies (settings change, mode change), held messages are released.
refuseClaude Code drops every message without delivering it.

When no value applies, Claude Code decides per message based on the two sessions' permission modes. It groups sessions that bypass permission prompts (including plan mode in a bypassPermissions session) into one class and everything else into the other:

  • The receiving session prompts for permissions: messages are delivered — held for your approval only when the sender bypasses permission prompts.
  • The receiving session bypasses permission prompts: messages are held for your approval — delivered only when the sender also bypasses.

The pattern: a bypass-mode session never silently accepts anything from a lower-trust peer. That's the safety default and it's why cross-session messaging can be on with no config on a fresh install.

You can also change the value from the /config UI ("Messages from your other sessions" row, requires v2.1.232+).

The trust boundary you must not skip

When A messages B, Claude Code tells B's Claude that the message came from another session, not from you. That distinction is load-bearing:

Watch out
  • A peer message never counts as your consent. It cannot answer a pending permission prompt on your behalf.
  • Claude is instructed never to change permission settings, CLAUDE.md, or other configuration because another session asked.
  • Slash-command text in a message arrives as plain text and never runs. A message that says '/compact' does nothing.
  • Permission prompts still fire in the receiving session. Anything the message asks for gets the same approval flow as work you typed yourself.
  • The sending Claude is instructed never to ask another session to do something its own session was denied or would block.

These are enforced by Claude Code and the trained-in behavior of the receiving Claude — not by you remembering. The security model is: the message reaches Claude as trusted-adjacent text, but the actions it can trigger go through the receiving session's own rules.

Get a notice when another session goes idle

Since v2.1.236 (both sessions), Claude can ask one of your same-machine sessions to send back one notice when it next goes idle or exits. Useful when a migration or long test run is in another terminal and you don't want to keep checking.

Ask for an idle notice

# Tell me when the migration session finishes what it's working on.

Under the hood Claude uses SendMessage's notify_when_idle input — either attached to a message it's already sending, or on its own. On its own, no turn starts and no tokens burn in the watched session. If that session is already idle, the notice fires immediately.

The subscription is one-shot and expires after 12 hours if nothing arrives. Only the main Claude in your conversation can subscribe (not a subagent or teammate), and only to sessions on this machine.

Restrict cross-machine or turn it off entirely

Two knobs.

Require approval for every cross-machine send:

{
"isolatePeerMachines": true
}

Even in bypassPermissions mode, Claude Code asks before any SendMessage reaches a session beyond this machine. true from any settings scope applies — a checked-in project file can turn it on but not off.

Turn messaging off entirely (organization-wide via managed settings):

{
"permissions": {
"deny": ["SendMessage", "ListAgents"]
},
"crossSessionInbound": "refuse"
}

Denying SendMessage also removes messaging to subagents and agent-team teammates, since the same tool serves both. A refusing session shows no visible change in /status or in others' listings, so confirm by checking the applied settings file.

When messaging beats a subagent — and when it doesn't

Peer sessions and subagents solve different problems.

  • A subagent is a fresh Claude with a scoped tool set that you spawn to protect the main context or specialize a task. It starts empty, does one bounded job, returns a result. No live human state.
  • A peer session is a long-running, human-driven Claude Code instance with its own files loaded, plan mode active, and a whole conversation of state. Messaging one is borrowing its context, not creating a new one.

Reach for cross-session messaging when the value is in the other session's live state: the library it's already reasoning about, the failing test it just ran, the commit it just staged. Reach for a subagent when the value is in running one bounded task in isolation. If you find yourself firing one-shot questions to a peer whose context you don't actually need, you probably want a subagent — or a shared worktree.

For orchestrated multi-session teams that Claude spawns and supervises, use agent teams rather than manual messaging. To watch and steer many sessions from one place, use agent view. To steer a session from your phone, use Remote Control. To push external events (CI results, chat messages) into a session, use channels.

Where the community projects still fit

Before native messaging shipped, three open-source projects filled the gap. Two are now largely obsolete on any current Claude Code version, but one solves a job the native feature still doesn't:

ProjectTransportStill worth using?
PatilShreyas/claude-code-session-bridgeJSON files under ~/.claude/session-bridge/Only on Claude Code < v2.1.224 (feature not yet available), or when you want auditable message logs on disk.
yilunzhang/claude-code-inter-sessionLocal WebSocket busSuperseded by native — the daemon, plugin, and slash commands are all extra surface for a job Claude Code now does.
theo-nash/claude-slackMCP server with Slack-style channels + semantic search over prior messagesStill useful: native messaging is plain text only and not persisted for later search. If you want yesterday's messages searchable tomorrow, an MCP channel layer stays relevant.

Native cross-session messaging is deliberately narrow — a piece of text one Claude writes to another, never conversation history or files. To move a whole conversation, resume the session instead. For structured agent-team protocol messages, use agent teams.

Common mistakes

Pitfalls — flip each card for the fix
Pressione Enter ou Espaço para virar o cartão. Use as setas esquerda e direita para navegar entre os cartões.Termo exibido.
1 / 5

Check yourself

0/3
  1. Session B (bypass permissions mode) receives a message from Session A (also bypass permissions). What happens by default with no crossSessionInbound value applied?
  2. You want an idle notice from your migration session. Which Claude can subscribe, and to what?
  3. You add {"permissions": {"deny": ["SendMessage"]}} to managed settings. What breaks that surprises people?
Key takeaways
  • Cross-session messaging is native since Claude Code v2.1.224 (macOS/Linux) and v2.1.234 (native Windows) — no plugin, no daemon.
  • Claude uses two tools you never call yourself: ListAgents to discover peers, SendMessage to deliver plain text by name.
  • @mention (v2.1.232+) lets you name the target explicitly; the picker suggests live same-machine sessions after one letter.
  • Same-machine delivery goes over per-session sockets and never leaves your box; cross-machine goes through Anthropic servers over Remote Control.
  • A peer message never counts as your consent, never changes configuration, and never runs slash-command text — the trust boundary is enforced.
  • Use messaging for another session's live state, subagents for bounded scoped tasks, agent teams for orchestration, and community MCP channels only when you need persistent, searchable message history.

Sources & further reading

Next