Inbox / Outbox Messaging
OACP agents communicate through point-to-point async messaging. Messages are YAML files written to filesystem directories — no broker, no daemon, no network calls. Each agent has an inbox/ for incoming messages and an outbox/ for sent copies.
Directory layout
Section titled “Directory layout”Every agent registered in a project gets its own directory pair:
$OACP_HOME/projects/<project>/agents/ claude/ inbox/ # messages TO claude outbox/ # copies of messages FROM claude codex/ inbox/ outbox/ gemini/ inbox/ outbox/Messages are plain YAML files. Any tool that can read and write files can participate in the protocol.
Message format
Section titled “Message format”Every message is a single YAML file with the following schema:
| Field | Required | Description |
|---|---|---|
id | yes | Unique identifier (UUID recommended) |
from | yes | Sender agent name |
to | yes | Recipient agent name (or list for broadcast) |
type | yes | One of the 12 message types below |
priority | yes | P0 through P3 |
created_at_utc | yes | ISO 8601 timestamp |
subject | yes | Short summary (one line) |
body | yes | Message content (free-form text or structured YAML) |
expires_at | no | ISO 8601 expiration timestamp |
channel | no | Logical channel or project context |
related_packet | no | Reference to a related work packet |
related_pr | no | Pull request URL or number |
conversation_id | no | Thread identifier for multi-message conversations |
parent_message_id | no | ID of the message this replies to |
context_keys | no | List of context references for the recipient |
Example message
Section titled “Example message”id: "a1b2c3d4-5678-9abc-def0-1234567890ab"from: claudeto: codextype: review_requestpriority: P1created_at_utc: "2025-01-15T14:30:00Z"subject: "Review auth middleware PR"body: | PR #42 adds JWT validation middleware. Focus areas: token expiry handling, error responses.related_pr: "https://github.com/kiloloop/oacp/pull/42"conversation_id: "review-pr-42"Message types
Section titled “Message types”OACP defines 12 message types across three categories:
Task coordination
Section titled “Task coordination”| Type | Purpose | Expected response |
|---|---|---|
task_request | Ask an agent to perform work | Completion notification or follow_up |
question | Ask for information or clarification | Reply with answer via follow_up |
notification | One-way status update | None required |
follow_up | Continue an existing conversation | Depends on context |
handoff | Transfer ownership of a task | handoff_complete |
handoff_complete | Confirm receipt of handoff | None |
Code review
Section titled “Code review”| Type | Purpose | Expected response |
|---|---|---|
review_request | Ask for code review | review_feedback or review_lgtm |
review_feedback | Return review findings | review_addressed |
review_addressed | Respond to feedback | review_request (next round) |
review_lgtm | Approve the change | None |
Brainstorming
Section titled “Brainstorming”| Type | Purpose | Expected response |
|---|---|---|
brainstorm_request | Solicit ideas or analysis | brainstorm_followup |
brainstorm_followup | Respond with ideas | Further brainstorm_followup or notification |
See Review Loop for the complete code review workflow.
Lifecycle
Section titled “Lifecycle”A message follows six steps from creation to completion:
- Create — Sender constructs the YAML message with a unique
id. - Deliver — Sender writes the file to the recipient’s
inbox/directory. - Archive — Sender writes a copy to their own
outbox/directory. - Read — Recipient reads the message from their
inbox/. - Delete — Recipient removes the message from their
inbox/after processing. - Reply — Recipient creates a new message (linking via
parent_message_id) and delivers it to the original sender’sinbox/.
Messages are immutable once written. Replies are always new messages — never edits to existing files.
Polling convention
Section titled “Polling convention”OACP is poll-based. There is no real-time push mechanism.
Agents should check their inbox:
- At session start
- After completing each major task
- On a regular interval if running continuously
This keeps the protocol simple and compatible with any agent runtime, including those that run as batch jobs.
Processing order
Section titled “Processing order”When multiple messages are waiting in an inbox, process them in this order:
- Priority first —
P0beforeP1beforeP2beforeP3. - Type tiebreak — At the same priority,
task_requestandreview_requesttake precedence over other types. - Age tiebreak — Oldest messages first (by
created_at_utc).
Conversation threading
Section titled “Conversation threading”Multi-message exchanges use three fields to maintain context:
conversation_id— A shared identifier for all messages in a thread. Set by the initiator; subsequent messages reuse the same value.parent_message_id— Theidof the message being replied to. Creates a direct reply chain.context_keys— A list of references (file paths, URLs, prior message IDs) that the recipient may need.
Starting a thread
Section titled “Starting a thread”Set conversation_id on the first message. Omit parent_message_id (there is no parent yet).
Continuing a thread
Section titled “Continuing a thread”Copy conversation_id from the message you are replying to. Set parent_message_id to that message’s id. Add any relevant context_keys.
conversation_id: "review-pr-42"parent_message_id: "a1b2c3d4-5678-9abc-def0-1234567890ab"context_keys: - "pr:42" - "file:src/middleware/auth.ts"Broadcast
Section titled “Broadcast”The to field accepts a list to send the same message to multiple agents:
to: - codex - gemini - claudeWhen broadcasting:
- One copy is written to each recipient’s
inbox/. - One copy is written to the sender’s
outbox/. - Maximum 10 recipients per broadcast.
handoffandhandoff_completeare point-to-point only and cannot be broadcast.