atrium:// protocol
URI-based dispatch for panes, state, hooks, and commands.
The atrium:// protocol is atrium's internal dispatch system. It turns every workspace concept — panes, rooms, workspaces, commands, hooks, state reads — into addressable URIs. The CLI, keybindings, and adapters all resolve to atrium:// URIs internally.
You rarely invoke these URIs by hand, but you can bind custom keybindings to them (see Keybindings) and reference them from adapter hooks.
URI shape
atrium://<category>/<path>[?<query>]
Categories:
commands— execute an app action.panes— read pane state.agents— message an agent pane and manage its dismiss / wake state.state— read or write namespaced state.hooks— dispatch an adapter hook event.
mcp:// namespace was retired in the protocol cleanup (Epic 51). Anything that used to route through mcp://panes/... or mcp://agents/... now goes through the equivalent atrium:// route.
Commands
Dispatches an app command. Actions mirror the command list shown in Settings → Keyboard (also surfaced by atrium commands).
atrium://commands/pane.split.horizontal?pane=$FOCUS
atrium://commands/pane.split.vertical?pane=$FOCUS
atrium://commands/pane.close?pane=$FOCUS
atrium://commands/room.new
atrium://commands/room.close?room=$ACTIVE
atrium://commands/workspace.new
atrium://commands/launcher.open?pane=$FOCUS
Query parameters:
$FOCUS— substituted with the currently focused pane's UUID.$ACTIVE— substituted with the active room or workspace.- Explicit UUIDs are also accepted.
Panes
Read-only URIs for pane introspection.
atrium://panes/ list all panes (respecting access scope)
atrium://panes/{pane-id}/ pane state snapshot
atrium://panes/{pane-id}/scrollback rendered scrollback
atrium://panes/{pane-id}/write write to PTY stdin (POST-like, via CLI)
These are the transport layer for atrium pane list, atrium pane read, and atrium pane write — the CLI just translates its arguments into the URI and calls the resolver.
Agents
Routes targeted at adapter-managed panes — message dispatch, dismiss / wake, and the activity-sidebar transitions that go with them. Resolved by atrium's AgentsHandler.
atrium://agents/{id}/message send text to the agent's PTY
atrium://agents/{id}/dismiss dismiss the agent's activity card
atrium://agents/{id}/wake clear dismiss and bring the card back
{id} accepts a full pane UUID or an unambiguous prefix. Pane-to-agent dispatch from the source-control pane's Send to agent, from notepad canvas/HTML notes, and from atrium agent message all resolve through this route. Access checks for the calling pane's MCP scope (same-tab / same-workspace / all) apply the same way they do for panes/....
State
Namespaced state reads and writes. Used internally for things like editor scroll position, file-tree expansion, and launcher history.
The path form is atrium://state/{scope}/{namespace} where:
{scope}is one ofapp,workspace,tab(room),pane.{namespace}is an arbitrary, dotted key namespaced by feature area.
atrium://state/workspace/file-tree
atrium://state/pane/{pane-id}/editor
atrium://state/tab/{tab-id}/subtab-groups
Writes are atomic and flow into the relevant snapshot (state.json or the workspace snapshot).
This surface is for internal and adapter use; user-facing configuration lives in config.json, not state.
Hooks
Hook dispatch target. Adapter manifests' hooks object maps event names to these URIs. When the adapter fires an event, atrium runs the URI, which:
- Parses the adapter name and event.
- Forwards the event (with any payload) to the hook server and the activity atom.
- Updates the relevant pane's activity status.
atrium://hooks/claude-code/session-start
atrium://hooks/claude-code/tool-use-pre
atrium://hooks/codex/permission-request
Hooks are the mechanism that drives the activity sidebar's status transitions, the task dispatch machinery, and the "agent needs input" notifications.
Resolving from the CLI
Keybindings and adapter hooks call URIs automatically. For ad-hoc resolution from a shell:
atrium exec protocol.resolve --params '{"uri":"atrium://commands/pane.split.horizontal?pane=$FOCUS"}'
Error handling
- Unknown category — error
invalid_params. - Unknown command or pane ID — error
not_found. - Access denied by MCP scope (pane tried to read a pane in another room when scope is
same-tab) — erroraccess_denied.
Why a URI scheme
Every workspace action has to be reachable from three places: the UI, the CLI, and the inter-agent coordination layer. A URI scheme keeps the three in sync — if you can describe an action with a URI, all three surfaces can invoke it without a separate binding per entry point. Custom keybindings and adapter hooks are the most common places to write a URI directly.
