This document formalizes our internal Agent Protocol, nicknamed CAP:
- JSON schema for agent definitions
- Message types for agent↔agent and user interactions
- Complete example illustrating PMAgent, AnalystAgent, and QAAgent collaboration
CAP is designed to enable autonomous AI agents to:
- Define Roles and Capabilities (Agent Definition)
- Exchange Information (Messaging)
- Delegate Subtasks (Delegation)
- Ensure Quality (Oversight)
- Leverage External Data & Tools (MCP Integration)
- Orchestrate Complex Workflows (Workflow Patterns)
- Track and Handle Errors (Observability & Error Handling)
Each part is detailed below before formal schema and examples.
Agents are uniquely identified by an id and primed by a system_prompt. They declare:
- allowed_agents: which other agents they may hand off tasks to.
- delegate_rules: natural-language conditions describing when to delegate to each.
- overseer: an optional agent responsible for reviewing completed tasks.
- mcp_bindings: which external MCP servers and tools they may use.
This clear separation of roles ensures each agent focuses on its domain (planning, analysis, QA) while the protocol enforces boundaries and permissions.
Agents and users communicate freely using the unified Message format. Any active participant—whether an agent instance or the user—may send a message to any other participant at any time. There are no protocol-enforced restrictions on who can message whom. This supports open-ended clarifications, brainstorming, feedback loops, and interactive question-and-answer flows among multiple agents or between agents and the user.
Delegation is a controlled sub-process distinct from general messaging. Only agents listed in an agent’s allowed_agents may receive a delegation_notice from that agent. Furthermore, delegation occurs only when the agent’s delegate_rules conditions are met. Key points:
- Scoped Handoffs: An agent can delegate tasks only to its permitted targets (as defined in
allowed_agents). Messages may flow freely, but handoff of responsibility requires explicit permission. - Parallelism: Agents may spawn multiple instances of the same agent type in parallel. Each instance has its own
idand conversation context, enabling concurrent processing of different subtasks. - Auditable Workflow: Each
delegation_noticerecordssender_id,recipient_id,task_id, and acontext_summary. This makes delegation lineage transparent and traceable across parallel or hierarchical task trees.
When an agent decides work exceeds its scope, it issues a delegation_notice:
- context_summary: concise description of what has been done and what remains.
- attachments: necessary artifacts to start the subtask.
Delegation is explicit, auditable, and reusable, allowing hierarchical and parallel task trees.
Quality control uses the same Message type:
- The designated overseer monitors another agent’s completed subtasks.
- To request clarifications or flag issues, the overseer sends a standard message with inquiries in
contentand optional attachments. - Only after overseer approval does the result return to the original delegator.
Agents interact with external data and tools via MCP by including tool_call_result attachments:
- Data queries, document reads, summaries input directly into messages.
- Ensures agents share concrete context rather than opaque references, and permissions are enforced by binding definitions.
Complex tasks are orchestrated by:
- Orchestrator spawning initial agents for planning or direct handling.
- Parallel Execution: multiple agents can work on subtasks concurrently.
- Interactive Loops: agents may ask follow-ups to users or each other as subtasks evolve.
This flexibility supports dynamic, multi-step processes with clear handoffs and collaboration.
Every message carries metadata (task_id, sender_id, recipient_id, type, timestamp) for audit and tracing.
- Error Responses signal failures, timeouts, or permission issues.
- Recipients or the orchestrator can retry, reassign, or escalate based on standardized error codes.
Each agent is defined by a JSON manifest with the following schema:
{
"$id": "https://example.com/schemas/agent.schema.json",
"type": "object",
"required": [
"id",
"system_prompt",
"allowed_agents",
"delegate_rules",
"mcp_bindings"
],
"properties": {
"id": {
"type": "string",
"description": "Unique agent identifier (agent_id)"
},
"system_prompt": {
"type": "string",
"description": "Initial LLM directive"
},
"allowed_agents": {
"type": "array",
"items": { "type": "string" },
"description": "List of agent_ids this agent may delegate tasks to"
},
"delegate_rules": {
"type": "object",
"description": "Maps each allowed agent_id to a natural-language delegation condition",
"patternProperties": {
"^[A-Za-z0-9_-]+$": {
"type": "object",
"required": ["when_to_delegate"],
"properties": {
"when_to_delegate": {
"type": "string",
"description": "Natural-language rule for delegation trigger"
}
}
}
}
},
"overseer": {
"type": ["string", "null"],
"description": "agent_id responsible for reviewing this agent’s completed tasks"
},
"mcp_bindings": {
"type": "array",
"items": {
"type": "object",
"required": ["server_id", "scopes", "allowed_tools"],
"properties": {
"server_id": { "type": "string" },
"description": { "type": "string" },
"scopes": { "type": "array", "items": { "type": "string" } },
"allowed_tools": { "type": "array", "items": { "type": "string" } }
}
},
"description": "Permissions for MCP servers by server_id"
}
}
}Key fields:
id: Unique agent identifier (not type name).system_prompt: LLM instructions.allowed_agents: agent_ids for delegation.delegate_rules: delegation conditions per target agent_id.overseer: agent_id that must vet this agent’s outputs.mcp_bindings: MCP server permissions (server_id, scopes, allowed_tools).
All communications use a unified Message envelope, with specialized variants for delegation and error handling.
{
"type": "message",
"task_id": "string",
"sender_id": "string",
"recipient_id": "string",
"content": "string",
"attachments": [
{
"type": "tool_call_result",
"server_id": "DocsServer",
"tool": "read_file",
"result": "..."
},
{ "type": "file", "path": "/tmp/report.csv" },
{ "type": "python_object", "object": {} },
{ "type": "text_snippet", "text": "..." }
]
}- sender_id/recipient_id: Agent instance IDs or "user".
- attachments:
- tool_call_result:
{server_id, tool, result} - file:
{path or URL} - python_object: Arbitrary serialized Python object
- text_snippet: Unstructured text block
- tool_call_result:
{
"type": "delegation_notice",
"task_id": "string",
"sender_id": "string",
"recipient_id": "string",
"context_summary": "string",
"attachments": [
/* same as Base Message */
]
}Indicates handoff of responsibility for a subtask.
{
"type": "error_response",
"task_id": "string",
"sender_id": "string",
"recipient_id": "string",
"error_code": 123,
"error_message": "string"
}Used to report failures, timeouts, or permission errors; recipients or the orchestrator handle retries or escalation.
Below are JSON manifests for example agents.
{
"id": "pm-1",
"system_prompt": "You are the ProjectManager agent. Break down incoming tasks and delegate to specialists.",
"allowed_agents": ["analyst-1"],
"delegate_rules": {
"analyst-1": {
"when_to_delegate": "When a subtask requires deep data analysis or domain expertise beyond planning."
}
},
"overseer": null,
"mcp_bindings": [
{
"server_id": "DocsServer",
"description": "Read specifications and generate summaries.",
"scopes": ["read:docs", "write:summary"],
"allowed_tools": ["list_documents", "read_file", "create_summary"]
},
{
"server_id": "DataServer",
"description": "Access raw sales data.",
"scopes": ["read:data"],
"allowed_tools": ["query_data"]
}
]
}{
"id": "analyst-1",
"system_prompt": "You are AnalystAgent, responsible for detailed data analysis and reporting.",
"allowed_agents": ["qa-1"],
"delegate_rules": {
"qa-1": {
"when_to_delegate": "When analysis is complete and requires quality verification before reporting."
}
},
"overseer": "qa-1",
"mcp_bindings": [
{
"server_id": "DataServer",
"description": "Access raw data for deep analysis.",
"scopes": ["read:data", "write:analysis"],
"allowed_tools": ["query_data", "process_data"]
}
]
}{
"id": "qa-1",
"system_prompt": "You are QAAgent, responsible for verifying completeness and accuracy of others’ work.",
"allowed_agents": [],
"delegate_rules": {},
"overseer": null,
"mcp_bindings": [
{
"server_id": "SummaryServer",
"description": "Generate human-readable summaries for review and approval.",
"scopes": ["write:summary"],
"allowed_tools": ["create_summary"]
}
]
}The following is an example detailing a user prompt and the protocol workflow exchanges it ensues.
{
"type": "delegation_notice",
"task_id": "T1",
"sender_id": "orchestrator",
"recipient_id": "pm-1",
"context_summary": "User request: analyze last quarter’s sales trends",
"attachments": []
}PMAgent uses MCP to fetch docs, then refines the problem:
{
"type": "message",
"task_id": "T1",
"sender_id": "pm-1",
"recipient_id": "user",
"content": "To clarify, do you want regional breakdowns, customer segments, or overall trend insight?",
"attachments": [
{
"type": "tool_call_result",
"server_id": "DocsServer",
"tool": "read_file",
"result": "...project spec..."
}
]
}User replies:
{
"type": "message",
"task_id": "T1",
"sender_id": "user",
"recipient_id": "pm-1",
"content": "Regional breakdown by major market would be helpful."
}PMAgent performs in-depth research and refines the problem before handing it off:
- Research Findings:
- Two major clients ("ClientA", "ClientB") churned in Q4.
- Noted company promotional campaigns in December and a major product launch in October.
- Trend Definitions (examples for guidance):
- Declining sales of specific products post-client churn.
- Rising sales in complementary product categories.
- Correlations between client departures and regional revenue drops.
- Seasonal or promotional effects on sales volume.
- Clarified Objectives: AnalystAgent should:
- Quantify the impact of ClientA and ClientB churn on total Q4 sales.
- Identify the top 5 products with highest increases or decreases in sales.
- Discover any additional patterns or anomalies that could be classified as "sales trends".
- Attachments include:
- Tool call results from MCP:
{ "type": "tool_call_result", "server_id": "DataServer", "tool": "query_data", "result": { "range": "Q4", "filters": { "clients": ["ClientA", "ClientB"], "all_products": true } } } - Project spec from DocsServer:
{ "type": "tool_call_result", "server_id": "DocsServer", "tool": "read_file", "result": "...project spec..." } - Text snippet summarizing research:
{ "type": "text_snippet", "text": "Client churn: ClientA & ClientB; December promotions; October product X launch." }
- Tool call results from MCP:
Then PMAgent sends the delegation notice:
{
"type": "delegation_notice",
"task_id": "T1.1",
"sender_id": "pm-1",
"recipient_id": "analyst-1",
"context_summary": "The user asked us to analyze last quarter’s sales trends. I've done some reasearch and broke down his question into the following tasks I want you to persue - please analyze the impact of ClientA and ClientB departures on Q4 sales, list the top 5 increasing/decreasing products, and identify any other meaningful sales trends (seasonality, promotions).",
"attachments": [
{
"type": "tool_call_result",
"server_id": "DataServer",
"tool": "query_data",
"result": {
"range": "Q4",
"filters": { "clients": ["ClientA", "ClientB"], "all_products": true }
}
},
{
"type": "tool_call_result",
"server_id": "DocsServer",
"tool": "read_file",
"result": "...project spec..."
},
{
"type": "text_snippet",
"text": "Client churn: ClientA & ClientB; December promotions; October product X launch."
}
]
}AnalystAgent may ask follow-ups:
{
"type":"message",
"task_id":"T1.1",
"sender_id":"analyst-1",
"recipient_id":"pm-1",
"content":"In my analysis, I found some irregularities related to ... Some regular sellers we had stopped activites every 2 months or so, in a consistant matter. Should I analyze further?",
"attachments": [...]
}PMAgent clarifies:
{
"type": "message",
"task_id": "T1.1",
"sender_id": "pm-1",
"recipient_id": "analyst-1",
"content": "Yes, in your research, make sure to try to find an explanation to this behaviour in our data. I'd also like to know if its a new behavoir this querter or if it existed last year, how does it compare if it did?"
}After analysis, AnalystAgent sends results to QA:
{
"type":"delegation_notice",
"task_id":"T1.1.1",
"sender_id":"analyst-1",
"recipient_id":"qa-1",
"context_summary":"Analysis complete; please verify data accuracy and relevance.",
"attachments":[
{"type":"file","path":"/tmp/eda_report_findings_with_explanations.md"},
{"type":"python_object","object":{"insights":[...],"figures":{...}}}
]
}QAAgent reviews and critiques it all, constantly doubting himself, and inquires if needed:
{
"type":"oversight_inquiry",
"task_id":"T1.1.1",
"sender_id":"qa-1",
"recipient_id":"analyst-1",
"inquiry":"The report seems detailed and thorough, and your calculations seem correct. However, the total for Europe seems low, and it doesn't align with the minimum total I querried; please confirm data source and any filters applied."
"attachments":[
{"type":"file","path":"/tmp/qa_eda_report_findings_with_explanations.md"},
]
}AnalystAgent responds:
{
"type": "message",
"task_id": "T1.1.1",
"sender_id": "analyst-1",
"recipient_id": "qa-1",
"content": "Confirmed: using 'sales_clean' table, no filters except status='closed'."
}QAAgent approves:
{
"type": "message",
"task_id": "T1.1.1",
"sender_id": "qa-1",
"recipient_id": "pm-1",
"content": "Verified. Analysis is complete and accurate."
}{
"type": "message",
"task_id": "T1",
"sender_id": "pm-1",
"recipient_id": "orchestrator",
"content": "Here is the verified Q4 sales trend report with regional and product breakdown."
}- Each message carries
task_id,sender_id,recipient_id,type, and timestamp. - ErrorResponse messages are used for failures:
{ "type": "error_response", "task_id": "...", "sender_id": "agent-x", "recipient_id": "agent-y", "error_code": 504, "error_message": "MCP timeout." } - Orchestrator or agents may retry, reassign, or escalate based on error codes.
End of Agent Protocol Specification