Skip to content

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.

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.

Every message is a single YAML file with the following schema:

FieldRequiredDescription
idyesUnique identifier (UUID recommended)
fromyesSender agent name
toyesRecipient agent name (or list for broadcast)
typeyesOne of the 12 message types below
priorityyesP0 through P3
created_at_utcyesISO 8601 timestamp
subjectyesShort summary (one line)
bodyyesMessage content (free-form text or structured YAML)
expires_atnoISO 8601 expiration timestamp
channelnoLogical channel or project context
related_packetnoReference to a related work packet
related_prnoPull request URL or number
conversation_idnoThread identifier for multi-message conversations
parent_message_idnoID of the message this replies to
context_keysnoList of context references for the recipient
id: "a1b2c3d4-5678-9abc-def0-1234567890ab"
from: claude
to: codex
type: review_request
priority: P1
created_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"

OACP defines 12 message types across three categories:

TypePurposeExpected response
task_requestAsk an agent to perform workCompletion notification or follow_up
questionAsk for information or clarificationReply with answer via follow_up
notificationOne-way status updateNone required
follow_upContinue an existing conversationDepends on context
handoffTransfer ownership of a taskhandoff_complete
handoff_completeConfirm receipt of handoffNone
TypePurposeExpected response
review_requestAsk for code reviewreview_feedback or review_lgtm
review_feedbackReturn review findingsreview_addressed
review_addressedRespond to feedbackreview_request (next round)
review_lgtmApprove the changeNone
TypePurposeExpected response
brainstorm_requestSolicit ideas or analysisbrainstorm_followup
brainstorm_followupRespond with ideasFurther brainstorm_followup or notification

See Review Loop for the complete code review workflow.

A message follows six steps from creation to completion:

  1. Create — Sender constructs the YAML message with a unique id.
  2. Deliver — Sender writes the file to the recipient’s inbox/ directory.
  3. Archive — Sender writes a copy to their own outbox/ directory.
  4. Read — Recipient reads the message from their inbox/.
  5. Delete — Recipient removes the message from their inbox/ after processing.
  6. Reply — Recipient creates a new message (linking via parent_message_id) and delivers it to the original sender’s inbox/.

Messages are immutable once written. Replies are always new messages — never edits to existing files.

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.

When multiple messages are waiting in an inbox, process them in this order:

  1. Priority firstP0 before P1 before P2 before P3.
  2. Type tiebreak — At the same priority, task_request and review_request take precedence over other types.
  3. Age tiebreak — Oldest messages first (by created_at_utc).

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 — The id of 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.

Set conversation_id on the first message. Omit parent_message_id (there is no parent yet).

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"

The to field accepts a list to send the same message to multiple agents:

to:
- codex
- gemini
- claude

When broadcasting:

  • One copy is written to each recipient’s inbox/.
  • One copy is written to the sender’s outbox/.
  • Maximum 10 recipients per broadcast.
  • handoff and handoff_complete are point-to-point only and cannot be broadcast.