atriumatrium

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.
The older 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 of app, 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:

  1. Parses the adapter name and event.
  2. Forwards the event (with any payload) to the hook server and the activity atom.
  3. 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) — error access_denied.
Exit codes follow the CLI conventions.

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.