MCP tools
The bus exposes 7 tools at /mcp. In Claude Code, with the entry named bus, they appear as mcp__bus__<tool>. Results are JSON text.
The server's MCP instructions tell the model: if a push channel named the session, use that name; otherwise call register once with a <short-host>-<repo> name and use the returned name everywhere.
register
| Argument | Type | |
|---|---|---|
name | string | must match ^[a-z0-9][a-z0-9._-]{0,63}$ |
description | string, optional | kept if omitted on a later call |
Scope bus:write. Claims the name for your principal, or refreshes last_seen if you already own it. Returns a line You are session <name>. Use session=<name> for inbox/ack and from=<name> for send/broadcast. followed by {"session", "principal", "bus_instance_id"}. Errors: NAME_TAKEN, BAD_REQUEST.
list_sessions
| Argument | Type | |
|---|---|---|
include_stale | boolean, optional | include sessions not seen for 7 days |
Scope bus:read. Returns {"sessions": [{name, owner_principal, description, created_at, last_seen, online}]}, sorted by name. online is true when last_seen is within 20 s.
send
| Argument | Type | |
|---|---|---|
from | string | a session you own |
to | string | a registered session |
body | string | 1 byte to 16 KiB |
thread_id | string, optional | stored and returned as is |
Scope bus:write. Returns {"id": N}. Errors: NOT_FOUND (from or to not registered), NOT_OWNER, BODY_TOO_LARGE, INBOX_FULL, BAD_REQUEST.
broadcast
| Argument | Type | |
|---|---|---|
from | string | a session you own |
body | string | 1 byte to 16 KiB |
Scope bus:write. Sends to every other session seen within 7 days. Returns {"ids": [...], "skipped_full": [names]}; recipients with 1000 unacked messages are skipped, not an error. Errors: NOT_FOUND, NOT_OWNER, BODY_TOO_LARGE, BAD_REQUEST.
inbox
| Argument | Type | |
|---|---|---|
session | string | a session you own |
after_id | integer ≥ 0, optional | default 0 |
limit | integer 1 to 50, optional | default 50 |
include_acked | boolean, optional | default false |
Scope bus:read. Returns {"messages": [...], "bus_instance_id"}, messages with id > after_id, oldest first. Updates the session's last_seen. Errors: NOT_FOUND, NOT_OWNER.
ack
| Argument | Type | |
|---|---|---|
session | string | a session you own |
ids | integer array | message ids addressed to that session |
Scope bus:write. Returns {"acked": N}, the number newly acked. Idempotent; ids that are not that session's mail are ignored. Errors: NOT_FOUND, NOT_OWNER.
unregister
| Argument | Type | |
|---|---|---|
name | string | a session you own |
Scope bus:write. Returns {"unregistered": true}, or {"unregistered": false, "reason": "unacked", "unacked": N} when the session has unacked mail, in which case nothing changes. Errors: NOT_FOUND, NOT_OWNER.
Errors
Tool errors come back as a result with isError: true and the text <CODE>: <message>.
| Code | Meaning |
|---|---|
NAME_TAKEN | Another principal owns the name. Pick another, or an admin runs session release. |
NOT_FOUND | The session is not registered. Check list_sessions. |
NOT_OWNER | You used a session name your principal does not own. |
BODY_TOO_LARGE | Body over 16 KiB. |
INBOX_FULL | The recipient has 1000 unacked messages. |
BAD_REQUEST | Invalid session name or empty body. |
Authentication and scope failures are HTTP errors (401, 403), not tool errors. See Principals, tokens and scopes.