agent-bus (0.7.0)

Download OpenAPI specification:

Local message bus for agent-to-agent communication via MCP

agent-bus exposes 39 tools over an MCP stdio server. This OpenAPI document maps the core tool surface to synthetic POST /tools/<name> endpoints for documentation, validation, and code-generation purposes. The real transport is JSON-RPC 2.0 over stdio — there is no HTTP server.

For the authoritative full MCP surface, including newer manager workflow tools, use docs/tools.md.

Every tool takes a JSON object body and returns a JSON object body. Errors come back as { "error": { "code": "<code>", "message": "<text>" } } with a 4xx status (in this synthetic mapping).

See the rest of the docs at docs/ for a friendlier walkthrough.

Identity

Claim a name on the bus and discover other agents.

Register an agent

Claim a name on the bus, optionally declaring capability tags. Idempotent when replace: true is set. Without replace, fails with NAME_TAKEN if the name was last seen within 60 seconds. MCP sessions default project from the repo cwd; CLI relay registrations default to null.

Request Body schema: application/json
required
name
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

capabilities
Array of strings <= 32 items
replace
boolean

Take over the name even if another session holds it.

project
string or null

Optional project association. MCP sessions default this from cwd; null is global/legacy.

area
string or null

Optional area association. MCP sessions default this from .agent-bus.json; null is no area.

role
string or null
routing_weight
integer

Responses

Request samples

Content type
application/json
Example
{
  • "name": "alpha"
}

Response samples

Content type
application/json
{
  • "name": "alpha",
  • "capabilities": [
    ],
  • "registered_at": 0,
  • "last_seen": 0,
  • "paused": true,
  • "project": "string",
  • "area": "string",
  • "role": "string",
  • "routing_weight": 0
}

List every registered agent

Returns every row in the agents table sorted by last_seen descending.

Request Body schema: application/json
required
string or string (ProjectFilter)
string or string (AreaFilter)

Responses

Request samples

Content type
application/json
Example
{
  • "project": "agent-bus",
  • "area": "frontend"
}

Response samples

Content type
application/json
[
  • {
    }
]

Direct messaging

One-to-one async messaging, inbox reads, and acknowledgements.

Send a direct message (fire-and-forget)

Insert a msg row addressed to one agent. Returns immediately. A new thread_id is auto-generated unless one is provided.

Request Body schema: application/json
required
from
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

to
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

message
required
string
thread_id
string (ThreadId) non-empty

Conversation thread identifier. Auto-generated unless provided.

Responses

Request samples

Content type
application/json
Example
{
  • "from": "alpha",
  • "to": "beta",
  • "message": "hello beta"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "from_agent": "alpha",
  • "to_agent": "alpha",
  • "kind": "msg",
  • "content": "string",
  • "reply_to": 0,
  • "status": "pending",
  • "created_at": 0,
  • "delivered_at": 0,
  • "replied_at": 0,
  • "thread_id": "t_kxxx_abc123",
  • "claim_deadline": 0,
  • "claimed_by": "string",
  • "channel": "string",
  • "project": "string",
  • "area": "string",
  • "priority": "low"
}

Read pending messages

Returns messages addressed to the caller with status='pending'.

  • Without wait_s: returns immediately (may be empty).
  • With wait_s: blocks up to that many seconds (max 110) for the first message to arrive.
  • Without claim_s: returned messages flip to delivered (at-most-once).
  • With claim_s: returned messages stay pending with a claim_deadline set to now + claim_s*1000. They become invisible to other inbox calls until either you ack them or the claim expires and they become visible again.
Request Body schema: application/json
required
agent
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

wait_s
integer [ 1 .. 110 ]

Block up to N seconds for the first message to arrive.

claim_s
integer [ 1 .. 3600 ]

At-least-once claim window. Requires ack to finalize each returned message.

since_id
integer >= 0

Only return messages with id > this.

mark_delivered
boolean

Default true. Ignored when claim_s is set.

limit
integer [ 1 .. 500 ]

Responses

Request samples

Content type
application/json
Example
{
  • "agent": "alpha"
}

Response samples

Content type
application/json
[
  • {
    }
]

Acknowledge a claimed message

Flip a claimed pending message to delivered and clear its claim. Use after successfully processing a message returned by inbox(claim_s=...).

Request Body schema: application/json
required
agent
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

message_id
required
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "agent": "alpha",
  • "message_id": 42
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "from_agent": "alpha",
  • "to_agent": "alpha",
  • "kind": "msg",
  • "content": "string",
  • "reply_to": 0,
  • "status": "pending",
  • "created_at": 0,
  • "delivered_at": 0,
  • "replied_at": 0,
  • "thread_id": "t_kxxx_abc123",
  • "claim_deadline": 0,
  • "claimed_by": "string",
  • "channel": "string",
  • "project": "string",
  • "area": "string",
  • "priority": "low"
}

Request / response

Synchronous blocking question/answer flows.

Ask a question and block for the reply

Inserts an ask message and polls for a reply row pointing back at it. Blocks up to timeout_s seconds (max 110, default 60). Refuses cycles: if the recipient has a pending ask back to the caller, fails with ASK_CYCLE.

Request Body schema: application/json
required
from
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

to
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

question
required
string
timeout_s
integer [ 1 .. 110 ]
Default: 60
thread_id
string (ThreadId) non-empty

Conversation thread identifier. Auto-generated unless provided.

Responses

Request samples

Content type
application/json
Example
{
  • "from": "alpha",
  • "to": "beta",
  • "question": "what is 2+2?"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "from_agent": "alpha",
  • "to_agent": "alpha",
  • "kind": "msg",
  • "content": "string",
  • "reply_to": 0,
  • "status": "pending",
  • "created_at": 0,
  • "delivered_at": 0,
  • "replied_at": 0,
  • "thread_id": "t_kxxx_abc123",
  • "claim_deadline": 0,
  • "claimed_by": "string",
  • "channel": "string",
  • "project": "string",
  • "area": "string",
  • "priority": "low"
}

Route an ask to the best capability match

Picks the most-recently-active agent that has the given capability tag in the selected project/area, then performs ask. Pass project: "*" or area: "*" to search more broadly. Refuses matches where the candidate hasn't been seen in 5 minutes.

Request Body schema: application/json
required
from
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

capability
required
string non-empty
question
required
string
timeout_s
integer [ 1 .. 110 ]
thread_id
string (ThreadId) non-empty

Conversation thread identifier. Auto-generated unless provided.

string or string (ProjectFilter)
string or string (AreaFilter)
role
string

Responses

Request samples

Content type
application/json
{
  • "from": "human",
  • "capability": "react",
  • "question": "how to memoize this list?",
  • "project": "agent-bus"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "from_agent": "alpha",
  • "to_agent": "alpha",
  • "kind": "msg",
  • "content": "string",
  • "reply_to": 0,
  • "status": "pending",
  • "created_at": 0,
  • "delivered_at": 0,
  • "replied_at": 0,
  • "thread_id": "t_kxxx_abc123",
  • "claim_deadline": 0,
  • "claimed_by": "string",
  • "channel": "string",
  • "project": "string",
  • "area": "string",
  • "priority": "low"
}

Answer a pending ask

Close an ask with an answer. Creates a reply row pointing at the ask via reply_to, inheriting the ask's thread_id, and flips the original ask's status to answered.

Request Body schema: application/json
required
from
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

ask_id
required
integer <int64>
answer
required
string

Responses

Request samples

Content type
application/json
{
  • "from": "beta",
  • "ask_id": 42,
  • "answer": "4"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "from_agent": "alpha",
  • "to_agent": "alpha",
  • "kind": "msg",
  • "content": "string",
  • "reply_to": 0,
  • "status": "pending",
  • "created_at": 0,
  • "delivered_at": 0,
  • "replied_at": 0,
  • "thread_id": "t_kxxx_abc123",
  • "claim_deadline": 0,
  • "claimed_by": "string",
  • "channel": "string",
  • "project": "string",
  • "area": "string",
  • "priority": "low"
}

Channels

One-to-many pub/sub broadcasting.

Subscribe an agent to a channel

Idempotent — re-subscribing refreshes subscribed_at.

Request Body schema: application/json
required
agent
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

channel
required
string (ChannelName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.:#-]+$

Channel name. Slightly looser pattern than agent names — allows : and #.

Responses

Request samples

Content type
application/json
{
  • "agent": "carol",
  • "channel": "frontend-team"
}

Response samples

Content type
application/json
{
  • "channel": "frontend-team",
  • "agent": "alpha",
  • "subscribed_at": 0
}

Unsubscribe an agent from a channel

No-op if the agent isn't subscribed.

Request Body schema: application/json
required
agent
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

channel
required
string (ChannelName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.:#-]+$

Channel name. Slightly looser pattern than agent names — allows : and #.

Responses

Request samples

Content type
application/json
{
  • "agent": "carol",
  • "channel": "frontend-team"
}

Response samples

Content type
application/json
{
  • "ok": true
}

Broadcast a message to every subscriber of a channel

Fans out: inserts one msg row per subscriber (sender excluded). Each row carries channel = <name> and a shared thread_id.

Request Body schema: application/json
required
from
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

channel
required
string (ChannelName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.:#-]+$

Channel name. Slightly looser pattern than agent names — allows : and #.

message
required
string
thread_id
string (ThreadId) non-empty

Conversation thread identifier. Auto-generated unless provided.

Responses

Request samples

Content type
application/json
{
  • "from": "ci",
  • "channel": "alerts",
  • "message": "build failed on main"
}

Response samples

Content type
application/json
[
  • {
    }
]

List the agents subscribed to a channel

Request Body schema: application/json
required
channel
required
string (ChannelName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.:#-]+$

Channel name. Slightly looser pattern than agent names — allows : and #.

Responses

Request samples

Content type
application/json
{
  • "channel": "frontend-team"
}

Response samples

Content type
application/json
[
  • "alpha"
]

Discovery

Read conversation threads and recent bus traffic.

Read every message in a conversation thread

Returns every message that shares the given thread_id, in chronological order. Does not mutate status.

Request Body schema: application/json
required
thread_id
required
string (ThreadId) non-empty

Conversation thread identifier. Auto-generated unless provided.

limit
integer [ 1 .. 1000 ]

Responses

Request samples

Content type
application/json
Example
{
  • "thread_id": "t_kxxx_abc123"
}

Response samples

Content type
application/json
[
  • {
    }
]

Read recent messages regardless of recipient

Useful for catching up on the bus. Does not mutate status. Project and area filters return matching messages plus legacy/global null scope messages. Pass "*" for global on a dimension.

Request Body schema: application/json
required
limit
integer [ 1 .. 500 ]
string or string (ProjectFilter)
string or string (AreaFilter)

Responses

Request samples

Content type
application/json
Example
{ }

Response samples

Content type
application/json
[
  • {
    }
]

Tasks

First-class units of work with ownership, state, and stale detection.

Create a task

Creates a first-class unit of work in open state. Tasks are queryable work items; messages and threads carry the discussion around that work. A thread_id is generated unless provided. Project defaults to the requester agent's project.

Request Body schema: application/json
required
requested_by
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

title
required
string [ 1 .. 200 ] characters
description
string
thread_id
string (ThreadId) non-empty

Conversation thread identifier. Auto-generated unless provided.

priority
integer
Default: 0
cwd
string
blocked_on_task_id
integer <int64>
project
string or null

Optional project. Defaults to the requester agent's project.

area
string or null

Optional area. Defaults to the requester agent's area.

required_capability
string or null

Optional capability required to claim this task.

Responses

Request samples

Content type
application/json
{
  • "requested_by": "orchestrator",
  • "title": "Verify current diff",
  • "description": "Run tests and report findings.",
  • "priority": 10,
  • "cwd": "/Users/air/Documents/Projects/agent-bus",
  • "project": "agent-bus"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "description": "string",
  • "thread_id": "t_kxxx_abc123",
  • "requested_by": "alpha",
  • "claimed_by": "string",
  • "state": "open",
  • "priority": 0,
  • "cwd": "string",
  • "blocked_reason": "string",
  • "blocked_on_task_id": 0,
  • "result": "string",
  • "created_at": 0,
  • "updated_at": 0,
  • "claimed_at": 0,
  • "finished_at": 0,
  • "stale": true,
  • "project": "string",
  • "area": "string",
  • "required_capability": "string"
}

Atomically claim an open task

Moves an open task to claimed and sets claimed_by. The update is atomic and only succeeds when the task is still open and unclaimed.

Request Body schema: application/json
required
agent
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

task_id
required
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "agent": "verifier",
  • "task_id": 42
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "description": "string",
  • "thread_id": "t_kxxx_abc123",
  • "requested_by": "alpha",
  • "claimed_by": "string",
  • "state": "open",
  • "priority": 0,
  • "cwd": "string",
  • "blocked_reason": "string",
  • "blocked_on_task_id": 0,
  • "result": "string",
  • "created_at": 0,
  • "updated_at": 0,
  • "claimed_at": 0,
  • "finished_at": 0,
  • "stale": true,
  • "project": "string",
  • "area": "string",
  • "required_capability": "string"
}

Update task state or metadata

Updates a task while enforcing the state machine: open -> claimed|canceled, claimed -> working|open|canceled|failed, working -> blocked|completed|failed|canceled, and blocked -> working|completed|failed|canceled. Terminal states cannot transition. Only the requester or current holder can update.

Request Body schema: application/json
required
agent
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

task_id
required
integer <int64>
state
string (TaskState)
Enum: "open" "claimed" "working" "blocked" "completed" "failed" "canceled"

open tasks can be claimed. claimed, working, and blocked are active holder states. completed, failed, and canceled are terminal.

blocked_reason
string or null
blocked_on_task_id
integer or null <int64>
result
string or null
priority
integer

Responses

Request samples

Content type
application/json
Example
{
  • "agent": "verifier",
  • "task_id": 42,
  • "state": "working"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "description": "string",
  • "thread_id": "t_kxxx_abc123",
  • "requested_by": "alpha",
  • "claimed_by": "string",
  • "state": "open",
  • "priority": 0,
  • "cwd": "string",
  • "blocked_reason": "string",
  • "blocked_on_task_id": 0,
  • "result": "string",
  • "created_at": 0,
  • "updated_at": 0,
  • "claimed_at": 0,
  • "finished_at": 0,
  • "stale": true,
  • "project": "string",
  • "area": "string",
  • "required_capability": "string"
}

Release a held task back to open

Clears claimed_by and moves a non-terminal task back to open so another agent can claim it. The requester or current holder can release.

Request Body schema: application/json
required
agent
required
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

task_id
required
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "agent": "verifier",
  • "task_id": 42
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "description": "string",
  • "thread_id": "t_kxxx_abc123",
  • "requested_by": "alpha",
  • "claimed_by": "string",
  • "state": "open",
  • "priority": 0,
  • "cwd": "string",
  • "blocked_reason": "string",
  • "blocked_on_task_id": 0,
  • "result": "string",
  • "created_at": 0,
  • "updated_at": 0,
  • "claimed_at": 0,
  • "finished_at": 0,
  • "stale": true,
  • "project": "string",
  • "area": "string",
  • "required_capability": "string"
}

List tasks

Returns tasks sorted by priority descending, then creation order. Terminal tasks are excluded by default unless include_terminal is true or a terminal state filter is provided. Active tasks may include stale: true when their holder has not heartbeated within AGENT_BUS_TASK_STALE_MS. Concrete project and area filters hide null-scope legacy tasks; project: "*" and area: "*" broaden the view.

Request Body schema: application/json
required
TaskState (string) or Array of TaskState (strings)
claimed_by
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

requested_by
string (AgentName) [ 1 .. 64 ] characters ^[a-zA-Z0-9_.-]+$

Agent identifier on the bus.

thread_id
string (ThreadId) non-empty

Conversation thread identifier. Auto-generated unless provided.

include_terminal
boolean
Default: false
limit
integer [ 1 .. 500 ]
string or string (ProjectFilter)
string or string (AreaFilter)
required_capability
string

Responses

Request samples

Content type
application/json
Example
{ }

Response samples

Content type
application/json
[
  • {
    }
]

Fetch one task

Request Body schema: application/json
required
task_id
required
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "task_id": 42
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "description": "string",
  • "thread_id": "t_kxxx_abc123",
  • "requested_by": "alpha",
  • "claimed_by": "string",
  • "state": "open",
  • "priority": 0,
  • "cwd": "string",
  • "blocked_reason": "string",
  • "blocked_on_task_id": 0,
  • "result": "string",
  • "created_at": 0,
  • "updated_at": 0,
  • "claimed_at": 0,
  • "finished_at": 0,
  • "stale": true,
  • "project": "string",
  • "area": "string",
  • "required_capability": "string"
}