Skip to main content

Push sessions

A push session receives new bus mail while idle. It needs the bus-push entry from client setup and must be started with a name and the development channels flag. scripts/claude-push.sh does both.

Start one​

scripts/claude-push.sh laptop-api

Without a name it uses <short-host>-<repo>:

scripts/claude-push.sh
# claude-push: session name laptop-api

Ask the session "what bus session are you?". It should answer with the name.

Extra Claude Code arguments​

Everything after the name goes to claude. The first argument is the name unless it starts with -:

scripts/claude-push.sh laptop-api --resume # name laptop-api, resume picker
scripts/claude-push.sh --continue # default name, continue last conversation
scripts/claude-push.sh server-ci --model opus # name server-ci

The script puts --allowedTools mcp__bus and the channels flag last, because both take a variable number of values.

What the script sets​

  • SESSION_BUS_NAME=<name> for this claude process only.
  • --dangerously-load-development-channels server:bus-push.
  • --permission-mode default. A bus message is a peer request, not your authorization. Do not combine push with skip-permissions.
  • --allowedTools mcp__bus: bus tool calls do not prompt; other tools still do.
  • Clears DISABLE_TELEMETRY and CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC for this process (see below).

Set SESSION_BUS_NAME only on launches with the channels flag. A named shim in a session without the flag still moves its cursor while Claude Code drops the pushes. The mail stays unacked and inbox still returns it.

Availability​

Channels are a Claude Code research preview.

  • On Claude Code 2.1.312, the channels flag is ignored, with the message "Channels are not currently available", while both DISABLE_TELEMETRY and CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC are set (any value, including 0). Clearing one alone is not enough. Verified on 2026-10-28.
  • claude-push.sh clears both for its own process, in the environment and through --settings. Your settings files are not changed. That session sends telemetry. If you do not want that, remove those lines from the script; push then stays off and pull still works.
  • For org-managed accounts, channelsEnabled must not be turned off by policy. Look for a startup warning.

What arrives​

A pushed message shows as ← bus-push: <body> with meta:

{ "msg_id": "42", "to": "laptop-api", "from": "server-ci", "from_principal": "me", "thread_id": "" }

The model is told to ack with session=<meta.to> and ids=[<msg_id>] after handling it.

Only messages from allowlisted principals are pushed. The default is the shim's own principal. To accept others, add --allow-from to the bus-push entry's args, for example ["/path/to/dist/cli.js","channel","--allow-from","me,teammate"].

Ending a session​

When claude exits cleanly, the shim calls unregister for its name (up to 3 s). If the session still has unacked mail, the bus refuses and keeps both the session and the mail; the shim keeps its cursor file. The next claude-push.sh with the same name picks up from there.

Per-launch fallback​

If a stdio server ever does not inherit claude's environment, write a per-launch config with a distinct server name and --session in args, then:

claude --mcp-config ./bus-push-laptop-api.json --dangerously-load-development-channels server:bus-push-laptop-api

This was not needed in testing (stdio servers do inherit the environment). Whether the channels flag resolves a server defined only in --mcp-config is untested.