Agent Control Protocol: How AI Agents Talk to Each Other
Inside the inter-agent communication system that lets autonomous AI agents delegate tasks, hand off context, and coordinate without a central controller.
Agents aren't isolated
A single AI agent is useful. A team of agents is powerful — but only if they can communicate. The hard part isn't making agents talk. It's making them talk without flooding each other with noise, losing context, or creating infinite delegation loops.
Klawty's Agent Control Protocol (ACP) handles this with a SQLite-backed message queue, typed message contracts, and entity-scoped context threads.
Message types
Every inter-agent message has a type that determines routing and priority:
| Type | Purpose | Example |
|------|---------|---------|
| task_handoff | Delegate a task to another agent | Client ops receives an invoice email, hands off to finance |
| notification | Inform without requiring action | Finance notifies orchestrator that an invoice was processed |
| data_request | Request specific information | Sales asks BI for a client's purchase history |
| alert | Urgent — requires immediate attention | Safety watchdog flags a failed health check |
Messages are stored in SQLite with status tracking: pending, read, processed, failed. Each agent drains its queue at the start of every cycle.
A real handoff: invoice processing
Here's what happens when a client sends an invoice by email:
1. Client ops agent polls Gmail (every 15 min)
2. Finds email with PDF attachment from supplier
3. Classifies: invoice → not my domain → hand off Message: {
type: "task_handoff",
from: "client-ops",
to: "finance",
payload: {
task_type: "process_invoice",
source: "email",
sender: "[email protected]",
subject: "Invoice #2847",
attachments: ["invoice-2847.pdf"]
}
}
4. Finance agent picks up the message next cycle (15 min)
5. Extracts line items, cross-references supplier DB
6. Creates a PROPOSE action to route for payment
7. Safety watchdog validates (amount, supplier, no duplicate)
8. Sends notification back:
Message: {
type: "notification",
from: "finance",
to: "orchestrator",
payload: {
action: "invoice_processed",
invoice_id: "2847",
amount: "€3,450.00",
status: "awaiting_approval"
}
}
9. Orchestrator logs completion, updates daily metrics
Total time from email arrival to processed invoice: one cycle (15 minutes). No human touched it. The human only sees the proposal notification — approve or reject with one click.
Context threads
The biggest problem with multi-agent systems is context loss. Agent A knows about a client interaction. Agent B picks up a related task but has no history. The result: repeated work, contradictory responses, missed context.
Klawty solves this with context threads — entity-scoped conversation containers that persist across agent cycles and agent boundaries.
Thread: client/maples-construction
├── 2026-03-18 09:14 — client-ops: Initial inquiry received (kitchen renovation)
├── 2026-03-18 09:30 — client-ops: Sent intro email with portfolio link
├── 2026-03-19 11:00 — sales: Lead scored at 82 (qualified)
├── 2026-03-19 11:15 — sales: Follow-up call scheduled for March 21
├── 2026-03-20 08:45 — client-ops: Client replied with budget range (€45-60K)
└── 2026-03-20 09:00 — sales: Updated deal stage to "proposal"Thread: invoice/ergotec-feb
├── 2026-03-01 08:30 — client-ops: Invoice email received from Ergotec
├── 2026-03-01 09:00 — finance: Extracted: €2,180, materials, PO #4412
├── 2026-03-01 09:05 — safety: Validated against supplier DB, approved
└── 2026-03-01 09:20 — finance: Routed for payment, confirmation pending
When any agent picks up a task related to "maples-construction," it gets the full thread injected into its context. Zero-delay handoffs. No waiting for a nightly memory distiller to consolidate knowledge — the thread is live and shared.
Cross-agent proposals
Some actions require coordination, not just communication. When an agent wants to do something risky — send an email, deploy code, modify a financial record — it creates a proposal.
The proposal enters a 6-state lifecycle:
pending → sentinel_review → approved → executing → completed
↘ rolled_back (within 15 min)
The safety agent validates every proposal against business rules. The orchestrator manages the execution queue. The human gets a 15-minute window to intervene. This isn't just safety — it's coordination. Multiple agents can have proposals in flight simultaneously, and the system ensures they don't conflict.
Adding a new agent
Here's the part that matters for developers: adding a new agent to this system is writing one file.
<!-- agents/researcher/AGENT.md -->
---
name: researcher
model_tier: workhorse
cycle: 30m
tools:
allow: [web_search, web_fetch, file_read, file_write, recall_memory, store_memory]
deny: [shell_exec, send_email]
channel: research-updates
---<h1 class="font-extrabold text-2xl mt-10 mb-4">Researcher</h1>
You are a research specialist. Your job is to...
The runtime discovers the agent, registers it in the message queue, assigns it a cycle, and starts routing messages. No JavaScript. No configuration beyond the AGENT.md file. The protocol handles discovery, registration, and communication automatically.
That's the point of an agent OS — you describe what you want, and the infrastructure handles how.