Agent Communication Protocol
| Entity Passport | |
| Registry ID | gh-model--kickflip73--agent-communication-protocol |
| License | NOASSERTION |
| Provider | github |
Cite this model
Academic & Research Attribution
@misc{gh_model__kickflip73__agent_communication_protocol,
author = {Kickflip73},
title = {Agent Communication Protocol Model},
year = {2026},
howpublished = {\url{https://github.com/kickflip73/agent-communication-protocol}},
note = {Accessed via Free2AITools Knowledge Fortress}
} ๐ฌTechnical Deep Dive
Full Specifications [+]โพ
Quick Commands
git clone https://github.com/kickflip73/agent-communication-protocol โ๏ธ Nexus Index V2.0
๐ฌ Index Insight
FNI V2.0 for Agent Communication Protocol: Semantic (S:50), Authority (A:0), Popularity (P:35), Recency (R:100), Quality (Q:50).
Verification Authority
๐ What's Next?
Technical Deep Dive
ACP โ Agent Communication Protocol
The missing link between AI Agents.
Send a URL. Get a link. Two agents talk. That's it.
English ยท ็ฎไฝไธญๆ
MCP standardized AgentโTool. ACP standardizes AgentโAgent.
P2P ยท Zero server required ยท curl-compatible ยท works with any LLM framework
Alpha โ Beta bidirectional P2P communication โ no central server, no OAuth
$ # Agent A โ get your link
$ python3 acp_relay.py --name AgentA
โ
Ready. Your link: acp://1.2.3.4:7801/tok_xxxxx
Send this link to any other Agent to connect.
$ # Agent B โ connect with one API call
$ curl -X POST http://localhost:7901/peers/connect \
-d '{"link":"acp://1.2.3.4:7801/tok_xxxxx"}'
{"ok":true,"peer_id":"peer_001"}
$ # Agent B โ send a message
$ curl -X POST http://localhost:7901/message:send \
-d '{"role":"agent","parts":[{"type":"text","content":"Hello AgentA!"}]}'
{"ok":true,"message_id":"msg_abc123","peer_id":"peer_001"}
$ # Agent A โ receive in real-time (SSE stream)
$ curl http://localhost:7901/stream
event: acp.message
data: {"from":"AgentB","parts":[{"type":"text","content":"Hello AgentA!"}]}
Quick Start
Option A โ AI Agent native (2 steps, zero config)
# Step 1: Send this URL to Agent A (any LLM-based agent)
https://raw.githubusercontent.com/Kickflip73/agent-communication-protocol/main/SKILL.md
# Agent A auto-installs, starts, and replies:
# โ
Ready. Your link: acp://1.2.3.4:7801/tok_xxxxx
# Step 2: Send that acp:// link to Agent B
# Both agents are now directly connected. Done.
Option B โ Manual / script
# Install
pip install websockets
# Start Agent A
python3 relay/acp_relay.py --name AgentA
# โ โ
Ready. Your link: acp://YOUR_IP:7801/tok_xxxxx
# In another terminal โ Agent B connects
python3 relay/acp_relay.py --name AgentB \
--join acp://YOUR_IP:7801/tok_xxxxx
# โ โ
Connected to AgentA
Option C โ Docker
docker run -p 7801:7801 -p 7901:7901 \
ghcr.io/kickflip73/agent-communication-protocol/acp-relay \
--name MyAgent
Behind NAT / Firewall / Sandbox?
ACP v1.4 includes a three-level automatic connection strategy โ zero config required:
Level 1 โ Direct connect (public IP or same LAN)
โ fails within 3s
Level 2 โ UDP hole punch (both behind NAT โ NEW in v1.4)
DCUtR-style: STUN address discovery โ relay signaling โ simultaneous probes
Works with ~70% of real-world NAT types (full-cone, port-restricted)
โ fails
Level 3 โ Relay fallback (symmetric NAT / CGNAT โ ~30% of cases)
Cloudflare Worker relay, stateless, no message storage
SSE events reflect the current connection level in real-time: dcutr_started โ dcutr_connected / relay_fallback.GET /status returns connection_type: p2p_direct | dcutr_direct | relay.
To force relay mode (e.g., for backward compatibility), add --relay on startup to get an acp+wss:// link.
โ See NAT Traversal Guide
Routing Topology Declaration (`transport_modes`, v2.4)
Agents declare which routing topologies they support via the transport_modes top-level AgentCard field:
| Value | Meaning |
|---|---|
"p2p" |
Agent supports direct peer-to-peer WebSocket connections |
"relay" |
Agent supports relay-mediated delivery (HTTP relay fallback) |
Default: ["p2p", "relay"] โ both topologies supported; absent means the same.
# Sandbox / NAT-only agent (relay only)
python3 relay/acp_relay.py --name SandboxAgent --transport-modes relay
# Edge agent with public IP (P2P only, no relay dependency)
python3 relay/acp_relay.py --name EdgeAgent --transport-modes p2p
AgentCard snippet:
{
"transport_modes": ["p2p", "relay"],
"capabilities": {
"supported_transports": ["http", "ws"]
}
}
Distinction:
transport_modesdeclares routing topology (which path data takes).capabilities.supported_transportsdeclares protocol bindings (how bytes are framed). They are orthogonal โ see spec ยง5.4.
Architecture
Handshake (humans only do steps 1 and 2)
Human
โ
โโ[โ Skill URL]โโโโโโโโโโโโโโโบ Agent A
โ โ pip install websockets
โ โ python3 acp_relay.py --name A
โ โ โ listens on :7801/:7901
โโโโโโโโโโโโโโ[โก acp://IP:7801/tok_xxx]โโ
โ
โโ[โข acp://IP:7801/tok_xxx]โโโบ Agent B
โ โ POST /connect {"link":"acp://..."}
โ โ
โ โโโโโโโโโโโ WebSocket Handshake โโโโโโโโโโโ
โ โ B โ A : connect(tok_xxx) โ
โ โ A โ B : AgentCard exchange โ
โ โ A, B : connected โ
โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
done โ P2P messages flow directly
P2P Direct Mode (default)
Machine A Machine B
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Host App A โ โ โ โ Host App B โ โ
โ โ (LLM / Script) โ โ โ โ (LLM / Script) โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ HTTP โ โ โ HTTP โ
โ โโโโโโโโโโโโผโโโโโโโโโโโ โ โ โโโโโโโโโโโโผโโโโโโโโโโโ โ
โ โ acp_relay.py โ โ โ โ acp_relay.py โ โ
โ โ :7901 HTTP API โโโโโโผโโโโโผโโโโโค POST /message:send โ โ
โ โ :7901/stream (SSE) โโโโโโผโโโโโผโโโโบโ GET /stream (SSE) โ โ
โ โ :7801 WebSocket โโโโโโชโโโโโชโโโโบโ :7801 WebSocket โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Internet / LAN (no relay server)
| Channel | Port | Direction | Purpose |
|---|---|---|---|
| WebSocket | :7801 |
Agent โ Agent | P2P data channel, direct peer-to-peer |
| HTTP API | :7901 |
Host App โ Agent | Send messages, manage tasks, query status |
| SSE | :7901/stream |
Agent โ Host App | Real-time push of incoming messages |
Host app integration (3 lines):
# Send a message to the remote agent
requests.post("http://localhost:7901/message:send",
json={"role":"agent","parts":[{"type":"text","content":"Hello"}]})
# Listen for incoming messages in real-time (SSE long-poll)
for event in sseclient.SSEClient("http://localhost:7901/stream"):
print(event.data) # {"type":"message","from":"AgentB",...}
Full Connection Strategy (v1.4 โ automatic, zero user config)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Three-Level Connection Strategy โ
โ โ
โ Level 1 โ Direct Connect (best) โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ Agent A โโโโโโโโโ WS direct โโโโโโโบโ Agent B โ โ
โ โโโโโโโโโโโโ (public IP / LAN) โโโโโโโโโโโโ โ
โ โ
โ Level 2 โ UDP Hole Punch (v1.4, both behind NAT) โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ Agent A โโโโบโ Signaling โโโโโโโโโโ Agent B โ โ
โ โ (NAT) โ โ (addr exch) โ โ (NAT) โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ exits after โ โ
โ โโโโโโโโโโโโโ WS direct โโโโโโโโโโโโโโโ โ
โ (true P2P after punch) โ
โ โ
โ Level 3 โ Relay Fallback (~30% symmetric NAT cases) โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ Agent A โโโโบโ Relay โโโโโโโโโบโ Agent B โ โ
โ โโโโโโโโโโโโ โ (stateless) โ โโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโ โ
โ frames only, no message storage โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Signaling server does one-time address exchange only (TTL 30s), forwards zero message frames.
Relay is the last resort, not the main path โ only triggered by symmetric NAT / CGNAT.
Why ACP
| A2A (Google) | ACP | |
|---|---|---|
| Setup | OAuth 2.0 + agent registry + push endpoint | One URL |
| Server required | Yes (HTTPS endpoint you must host) | No |
| Framework lock-in | Yes | Any agent, any language |
| NAT / firewall | You figure it out | Auto: direct โ hole-punch โ relay |
| Message latency | Depends on your infra | 0.6ms avg (P99 2.8ms) |
| Min dependencies | Heavy SDK | pip install websockets |
| Identity | OAuth tokens | Ed25519 + did:acp: DID + CA hybrid (v1.5) |
| Availability signaling | โ (open issue #1667) | โ
availability field (v1.2) |
| Agent identity proof | โ (open issue #1672, 425 comments, still no spec-level resolution) | โ
did:acp: + Ed25519 AgentCard self-sig (v1.8) + mutual auto-verify at handshake (v1.9) + offline pubkey discovery GET /identity/pubkey-discovery (v2.33) + structured per-peer trust score GET /peers/<id>/trust (v2.34) |
| Mutual identity at handshake | โ No protocol-level concept | โ Auto-verified on connect โ both sides confirmed in one round-trip (v1.9) |
| Agent unique identifier | ๐ PR#1079: random UUID (unverifiable ownership) | โ
did:acp:<base58url(pubkey)> โ cryptographic fingerprint, ownership provable |
| LAN agent discovery | โ No spec-level discovery mechanism | โ
GET /peers/discover โ TCP port-scan + AgentCard fingerprint, no mDNS opt-in required (v2.1-alpha) |
| Offline message delivery | โ No offline buffering โ messages dropped silently if peer is offline | โ
Auto-queue on disconnect, auto-flush on reconnect โ GET /offline-queue (v2.0-alpha); --persist-queue SQLite durable persistence across restarts (v2.97) |
| Async task queue | โ #1667 offline-first task handling still in discussion โ no spec endpoint | โ
POST /tasks/queue โ 202 Accepted, task_id + poll_url + sse_url + queued_at; GET /tasks/queue queue status; capabilities.async_task_queue (v2.98) |
| Cancel task semantics | โ Undefined โ CancelTaskRequest missing, async cancel state disputed (#1680, #1684) |
โ
Synchronous + idempotent: 200 on success, 409 ERR_TASK_NOT_CANCELABLE on terminal state (v1.5.2 ยง10) |
| Error response Content-Type | โ Undefined โ application/json vs application/problem+json contradicted within spec (#1685) |
โ
Always application/json; charset=utf-8 โ one content type for all responses, zero ambiguity |
| Webhook security | โ Push notification config API returns credentials in plaintext (#1681, security bug) | โ Webhooks store URL only โ no credentials, no leakage surface |
| AgentCard limitations field | โ Open proposal โ issue #1694 (2026-03-27), not yet merged | โ
limitations: LimitationObject[] โ structured format (v2.20): {kind, code, message, permanent}; stable/runtime split; 6 kind types; --limitations-json CLI; capabilities.limitations_structured=true |
| Skills / capability discovery | โ No structured skill discovery in spec | โ
GET /skills โ Skills-lite ่ฝๅๅ็ฐ๏ผ่ฝป้๏ผๆ JSON Schema ๅผ้๏ผ๏ผAgentCard skills[] ็ปๆๅๅฏน่ฑกๆฐ็ป๏ผv2.10.0๏ผ๏ผๆฏไธช skill ๅซ input_modes/output_modes/examples ๅญๆฎต๏ผv2.11.0๏ผ๏ผ/skills/query ๆฏๆ constraints.input_mode ๆ่พๅ
ฅๆจกๅผ่ฟๆปค๏ผv2.11.0๏ผ๏ผskill ็บงๅซ constraints: {max_file_size_bytes, concurrent_tasks, context_window} โ ไธ็ปด่ฝๅ่พน็ๅฃฐๆ๏ผv2.26๏ผ๏ผskill ็บงๅซ limitations: LimitationObject[] โ ็ป็ฒๅบฆ่ฝๅ่พน็๏ผ?has_limitation=<kind|code> ่ฟๆปค๏ผv2.28๏ผ๏ผGET /skills/<id>/status ่ฟ่กๆถๅฏ็จๆงๆขๆต๏ผv2.29๏ผ๏ผPATCH /skills/<id>/limitations ่ฟ่กๆถๅจๆๆดๆฐ skill limitations๏ผv2.31๏ผ๏ผ้ขๅ
A2A PR#1655 + #1694 |
| Agent capability boundaries | โ limitations[] open proposal (issue #1694, not merged) |
โ
limitations: LimitationObject[] โ ็ปๆๅ่ฝๅ่พน็๏ผv2.20๏ผ๏ผstable/runtime ๅ็ฆป๏ผkind ๅ็ฑป๏ผๆบๅจๅฏ่ทฏ็ฑ |
| Trust signals / provenance | โ trust.signals[] open spec proposal (#1628, still in discussion โ no merged schema) |
โ
trust.signals[] โ 4-type structured trust evidence in AgentCard (v2.14): self_attested / third_party_vouched / onchain_credentials / behavioral; Ed25519-signed; A2A-compatible schema |
| Multi-turn conversation context | โ contextId still proposal-stage โ no query API in spec |
โ
GET /context/<id>/messages โ query full conversation history by context_id (v2.15); supports since_seq incremental fetch, sort=asc|desc, limit; outbound + inbound messages unified |
| Availability scheduling (CRON) | โ #1667 heartbeat agent support still in discussion โ no schedule field | โ
availability.schedule CRON expression + availability.timezone; GET /availability; POST /availability/heartbeat; capabilities.availability_schedule (v2.17) |
| JWKS key discovery | โ IS#1628 proposes JWKS-format key discovery โ still proposal stage, no merged implementation | โ
GET /.well-known/jwks.json โ RFC 7517 JWK Set; kty=OKP, crv=Ed25519, alg=EdDSA per RFC 8037; discoverable via endpoints.jwks + trust.signals[type=jwks].jwks_uri; capabilities.trust_jwks: true (v2.18) |
| Protocol bindings declaration | โ
ยง5.8 Custom Protocol Bindings โ protocol_bindings[] URI array in AgentCard (merged 2026-04-07) |
โ
protocol_bindings[] top-level AgentCard array + GET /protocol-binding endpoint + urn:acp:binding:p2p-relay/v1 URI; backward-compat singular protocol_binding retained (v2.84) |
| Protocol compatibility matrix | โ No cross-protocol compatibility declaration | โ
GET /protocol-binding/compatibility โ 6-entry matrix: websocket (native), http/sse (native), a2a (partial, ยง2/ยง3/ยง5.8 aligned), anp (partial), mcp (none), grpc (none); aligned_sections[] per entry (v2.85) |
| Ed25519 identity setup | โ #1672: still open, no default in spec | โ
Ed25519 keypair auto-generated by default โ zero config, ~/.acp/identity.json; capabilities.identity_default=True; --no-identity to disable (v2.85) |
| Governance metadata | โ Issue #1717 opened 2026-04-09 โ proposal stage (Microsoft agent-governance-toolkit team); no merged schema | โ
governance_metadata in AgentCard (v2.85): governance_score, policies[], attestations[]; PATCH /policy-compliance batch-updates compliance standards (v2.87); capabilities.governance_metadata=true; fully testable without external registry |
| Skill-level authorization tiers | โ RFC #1716 opened 2026-04-09 โ no merged enforcement mechanism; SecurityRequirement only covers auth, not authz | โ
authorization_tier (T0โT3) per-skill (v2.50); capability_token fine-grained delegated invocation rights (v2.74); human_confirmation_required for irreversible T3 skills (v2.51); effective_tier 5-factor dynamic computation (v2.76): tier_rule + depth_floor + reputation_adj + wtrmrk_adj + bilateral_ir_adj |
| Bilateral signed interaction records | โ Issue #1718 opened 2026-04-05 โ proposal stage (viftode4); identifies that unilateral relay-signed records can be forged by a malicious relay | โ
bilateral_ir_log (v2.59โv2.76): caller + relay co-sign each record โ non-repudiable by either party; SHA-256 hash chain for tamper-evidence; sequence_a for ordering; Merkle root attestation (v2.72); AgentCard trust.signals[type=bilateral_ir] (v2.68); GET /ir/test-vectors for cross-impl verification (v2.64); POST /ir/import-evidence (v2.65); feeds into effective_tier as bilateral_ir_adj โ 5th factor (v2.76); 29+ passing tests |
Governance metadata (v2.85/v2.87) โ A2A #1717 (2026-04-09, Microsoft governance team) proposes adding
trust_score,capability_manifest, andpolicy_complianceto Agent Cards. ACP already ships all three:governance_metadata.governance_score,governance_metadata.policies[], andPATCH /policy-compliance(v2.87). No proposal, no committee โ working code with tests.
Skill authorization tiers (v2.50+) โ A2A #1716 (2026-04-09, RFC stage) identifies the same gap ACP solved in v2.50:
SecurityRequirementauthenticates callers but cannot restrict which skills they invoke or with what parameters. ACP'sauthorization_tier(T0โT3) +capability_token+human_confirmation_required+ 5-factoreffective_tierprovides complete skill-boundary authorization โ with 60+ passing tests.
Bilateral signed interaction records (v2.59+) โ A2A #1718 (2026-04-05, viftode4) correctly identifies that unilateral relay-signed records can be forged: if the relay lies, the record is worthless. ACP v2.61 solved this with bilateral co-signing: caller and relay both sign the same canonical payload. A record signed by both parties is non-repudiable by either. Chain of records (SHA-256
previous_hash) is tamper-evident without trusting either party. Bilateral records feed intoeffective_tieras thebilateral_ir_adjfactor (v2.76) โ a corpus of mutual interaction history can lower the authorization floor for a trusted, well-known peer.GET /ir/test-vectors(v2.64) enables cross-implementation verification. 29+ passing tests.
A2A #1672 has 425 comments (as of 2026-04-12) and still no implementation merged into spec. The leading proposal requires a central CA (
getagentid.dev) โ single point of failure, registration bottleneck, privacy leak. ACP v2.85 ships Ed25519 identity default-on: self-generated keypair, no CA, no registration, works offline and air-gapped. ACP v2.93 publishes ACP-RFC-004 โ a full comparison (9 dimensions) and multi-provider DID approach, responding directly to theaeoessthree-layer model articulated in A2A #1712.
A2A #1680 & #1684 โ community debate: when cancel can't complete immediately, return
WORKINGor newCANCELINGstate?CancelTaskRequestschema is missing from spec. ACP v1.5.2 resolves all of this with synchronous, idempotent cancel semantics.
A2A #1685 โ error response Content-Type undefined in spec (PR #1600 removed
application/problem+jsonwithout replacing it). A2A #1681 โ push notification config API exposes credentials in plaintext. ACP avoids both by design: uniformapplication/json+ URL-only webhooks.
Offline delivery (v2.0-alpha / v2.97 / v2.98 / v3.8) โ A2A has no spec-level offline buffering. If you send a message while your peer is restarting, it's gone. ACP automatically queues the message on your local relay (up to 100 per peer), and flushes the queue the moment the peer reconnects.
GET /offline-queueshows what's waiting. v2.97--persist-queueadds SQLite-backed durability: messages survive relay restarts, solving the heartbeat-agent offline window (A2A #1667). v2.98POST /tasks/queuecompletes the offline-first story for task workloads: enqueue a task with 202 Accepted, pick up results later via poll or SSE โ no blocking, no dropped work. v3.8--heartbeat-agent+GET /offline-queue/summarycloses the loop: cron-style agents wake up, call the lightweight summary endpoint (has_messages,total_queued,oldest_queued_at) for a fast pre-check before heavier processing, then stampPOST /availability/heartbeatwhen done.
AgentCard limitations (v2.7 โ v2.28) โ A2A #1694 (opened 2026-03-27) proposes adding a
limitationsfield. ACP v2.7 shipped working code the same day; ACP v2.20 upgrades to structuredLimitationObject[]with stable/runtime split (permanent: bool), 6 kind types (capability|modality|scale|domain|access|other), machine-readable codes. ACP v2.28 extends this to per-skill granularity: every skill object now carries its ownlimitations[], enabling orchestrators to ask "does skill X support audio?" rather than just "does this agent support audio?".GET /skills?has_limitation=modalityreturns only skills with modality-kind limitations;POST /skills/queryresponse includesskill_limitations_declared[]for pre-flight routing decisions. Old clients ignore the optional field โ fully backward-compatible. A2A #1694 is still an open proposal with no merged implementation.
LAN discovery (v2.1-alpha) โ A2A has no spec-level mechanism for agents to find each other on a local network. ACP
GET /peers/discoverscans your /24 subnet in 1โ3 seconds: 64-thread TCP probe on common ACP ports, then/.well-known/acp.jsonfingerprint on every open port. Returns a list of ACP agents with theiracp://links โ ready to connect. No mDNS required on the target side. Find any ACP relay on your LAN, even ones you don't control.
Multi-relay federation (v3.10) โ A2A has no cross-relay message routing mechanism. When agents are on different relay instances (different orgs, different networks), there's no standard way to deliver messages between them. ACP v3.10 adds
POST /federationto connect remote relays as peers, andPOST /federation/routeto route messages to peers on remote relays โ all in ~120 lines of stdlib Python. Federated messages fall back to offline-queue when the target peer is offline, composable with--persist-queuefor durable cross-relay delivery.capabilities.federation: truelets orchestrators discover federation-capable relays via AgentCard.
Numbers
- 0.6ms avg send latency ยท 2.8ms P99
- 1,100+ req/s sequential throughput ยท 1,200+ req/s concurrent (10 threads)
- < 50ms SSE push latency (threading.Event, not polling)
- 1574/1574 unit + integration tests PASS (error handling ยท pressure test ยท NAT traversal ยท ring pipeline ยท transport_modes ยท context query ยท federation ยท Pub/Sub ยท heartbeat-agent ยท task-queue-worker ยท governance-compliance ยท governance-audit)
- 190+ commits ยท 3,300+ lines ยท zero known P0/P1 bugs
API Reference
| Action | Method | Path |
|---|---|---|
| Get your link | GET | /link |
| Connect to a peer | POST | /peers/connect {"link":"acp://..."} |
| Send a message | POST | /message:send {"role":"agent","parts":[...]} |
| Receive in real-time | GET | /stream (SSE) |
| Poll inbox (offline) | GET | /recv |
| Query status | GET | /status |
| List peers | GET | /peers |
| AgentCard | GET | /.well-known/acp.json |
| Update availability | PATCH | /.well-known/acp.json |
| Create task | POST | /tasks |
| Update task | POST | /tasks/{id}:update |
| Cancel task | POST | /tasks/{id}:cancel |
| Submit task evidence | POST | /tasks/{id}/evidence |
| List task evidence | GET | /tasks/{id}/evidence |
| Get latest evidence | GET | /tasks/{id}/evidence/latest |
| Stream task evidence (SSE) | GET | /tasks/{id}/evidence-stream |
| Heartbeat report | POST | /availability/heartbeat |
| Query availability | GET | /availability |
| List federation relays | GET | /federation |
| Add federation relay | POST | /federation {"link":"acp://..."} |
| Route to remote relay | POST | /federation/route {"relay_id":"...","target_peer_id":"..."} |
| Subscribe to topic | POST | /peers/subscribe/{topic} |
| Unsubscribe from topic | POST | /peers/unsubscribe/{topic} |
| Publish to topic | POST | /peers/broadcast/{topic} |
| List active topics | GET | /peers/topics |
| Poll queue summary | GET | /offline-queue/summary |
| Enqueue async task | POST | /tasks/queue {"role":"agent","payload":{...}} |
| Register worker | POST | /tasks/queue/worker {"callback_url":"http://...","peer_id":"...","skill_id":"..."} |
| List workers | GET | /tasks/queue/workers |
| Deregister worker | DELETE | /tasks/queue/worker/{id} |
HTTP default port: 7901 ยท WebSocket port: 7801
AgentCard response example (GET /.well-known/acp.json):
{
"name": "MyAgent",
"acp_version": "2.4.0",
"transport_modes": ["p2p", "relay"],
"capabilities": {
"streaming": true,
"supported_transports": ["http", "ws"]
}
}
transport_modes(v2.4+): declares routing topology โ"p2p"(direct) and/or"relay"(relay-mediated). Default:["p2p", "relay"]. Distinct fromcapabilities.supported_transportswhich declares protocol bindings.
Optional Features
| Feature | Flag | Notes |
|---|---|---|
| Public relay (NAT fallback) | --relay |
Returns acp+wss:// link |
| HMAC message signing | --secret <key> |
Shared secret, no extra deps |
| Ed25519 identity | (default, auto-generated) | pip install cryptography; use --no-identity to disable |
| mDNS LAN discovery | --advertise-mdns |
No zeroconf library needed |
| Docker | docker pull ghcr.io/kickflip73/agent-communication-protocol/acp-relay |
Multi-arch, GHCR CI |
evidence_stream |
(always on) | ไปปๅก่ฏๆฎ SSE ๅฎๆถ่ฎข้
๏ผv2.82๏ผ๏ผGET /tasks/{id}/evidence-stream๏ผๆฏๆ replay + ๅค่ฎข้
่
+ keepalive |
Task State Machine
Track cross-agent task progress:
submitted โ working โ completed โ
โ failed โ
โ input_required โ working (waiting for more input)
API: POST /tasks to create ยท POST /tasks/{id}:update to update status.
Heartbeat / Cron Agents
ACP natively supports offline agents (cron-style agents that wake up periodically), no persistent connection required.
How it works
Cron Agent wakes up every 5 minutes:
1. Start acp_relay.py (get an acp:// link)
2. PATCH /.well-known/acp.json to broadcast availability
3. GET /recv to drain queued messages, process in batch
4. POST /message:send to reply
5. Exit (relay shuts down cleanly)
# Python โ cron agent template
import subprocess, time, requests
relay = subprocess.Popen(["python3", "relay/acp_relay.py", "--name", "MyCronAgent"])
time.sleep(1) # wait for startup
BASE = "http://localhost:7901"
# Broadcast availability
requests.patch(f"{BASE}/.well-known/acp.json", json={
"availability": {
"mode": "cron",
"last_active_at": "2026-03-24T10:00:00Z",
"next_active_at": "2026-03-24T10:05:00Z",
"task_latency_max_seconds": 300,
}
})
# Drain and process queued messages
msgs = requests.get(f"{BASE}/recv?limit=100").json()["messages"]
for m in msgs:
text = m["parts"][0]["content"]
requests.post(f"{BASE}/message:send",
json={"role":"agent","parts":[{"type":"text","content":f"Processed: {text}"}]})
relay.terminate()
Why it matters: A2A #1667 is still discussing heartbeat agent support as a proposal. ACP
/recvsolves this natively โ available today.
Agent Identity (v2.85)
ACP auto-generates an Ed25519 keypair on first run โ no flags required. The keypair is saved to ~/.acp/identity.json and reused across restarts.
| Mode | Flag | capabilities.identity |
Notes |
|---|---|---|---|
| Self-sovereign (default) | (none) | "ed25519" |
Auto-generated keypair; capabilities.identity_default=True (v2.85) |
| Self-sovereign (custom path) | --identity <path> |
"ed25519" |
Load/generate keypair at custom path |
| Hybrid | --ca-cert |
"ed25519+ca" |
Self-sovereign + CA-issued certificate |
| Disabled | --no-identity |
"none" |
For embedded/testing scenarios only (v2.85) |
# Default โ Ed25519 auto-generated, zero config (v2.85+)
python3 relay/acp_relay.py --name MyAgent
# Custom keypair path (backward compat)
python3 relay/acp_relay.py --name MyAgent --identity ~/.acp/my-agent.json
# Hybrid identity (v1.5) โ CA cert file
python3 relay/acp_relay.py --name MyAgent --ca-cert /path/to/agent.crt
# Disable identity (testing/embedded)
python3 relay/acp_relay.py --name MyAgent --no-identity
AgentCard example (hybrid mode):
{
"identity": {
"scheme": "ed25519+ca",
"public_key": "",
"did": "did:acp:",
"ca_cert": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
},
"capabilities": {
"identity": "ed25519+ca"
}
}
Verification strategy (verifier's choice):
- Trust only
did:acp:โ verify Ed25519 signature, ignoreca_cert - Trust only CA โ verify certificate chain, ignore DID
- Require both โ highest security
- Accept either โ highest interoperability
Why it matters: A2A #1672 (44 comments, still in discussion) is converging on the same hybrid model. ACP v1.5 ships it today.
SDKs
| Language | Path | Notes |
|---|---|---|
| Python | sdk/python/ |
pip install acp-client ยท RelayClient, AsyncRelayClient; LangChain adapter: pip install "acp-client[langchain]" (v1.8.0+) |
| Node.js | sdk/node/ |
Zero external deps, TypeScript types included |
| Go | sdk/go/ |
Zero external deps, Go 1.21+ |
| Rust | sdk/rust/ |
v1.3, reqwest + serde |
| Java | sdk/java/ |
Zero external deps, JDK 11+, Spring Boot example included |
What's New
| Version | Highlights |
|---|---|
| v3.13 | Governance Audit Endpoint โ GET /governance/audit with IR structured query + ?peer_id=/?task_id=/?since= filters (A2A #1717 auditEndpoint first implementation) |
| v3.12 | Governance Compliance Report โ GET/POST /governance/compliance + compliance_report / last_verified_at in AgentCard.governance |
| v3.11 | Async Task Queue Workers โ register callback_url workers, auto-dispatch on enqueue, DELETE /tasks/queue/worker/{id} |
โ Full Changelog
Repository Structure
agent-communication-protocol/
โโโ SKILL.md โ Send this URL to any agent to onboard
โโโ relay/
โ โโโ acp_relay.py โ Core daemon (single file, stdlib-first)
โโโ spec/ โ Protocol specification documents
โโโ sdk/ โ Python / Node.js / Go / Rust / Java SDKs
โโโ tests/ โ Compatibility + integration test suites
โโโ docs/ โ Chinese docs, conformance guide, blog drafts
โโโ acp-research/ โ Competitive intelligence, ROADMAP
Show HN
ACP โ P2P protocol for AI Agents to talk directly, no server required
The problem: Most multi-agent setups require a central orchestration server. When Agent A wants to message Agent B, you build infrastructure. When Agent B is behind NAT, you give up and poll.
What ACP does: Agent A runs one command, gets an acp:// link, sends it to Agent B. Agent B pastes the link. They're connected P2P โ through NAT, firewalls, sandboxes โ in under 5 seconds. No server. No registration. No OAuth dance.
# Agent A โ anywhere in the world
python3 acp_relay.py --name AgentA
# โ
Ready. Your link: acp://1.2.3.4:7801/tok_xxxxx
# Agent B โ behind a corporate firewall / in a cloud sandbox
curl -X POST http://localhost:7901/peers/connect \
-d '{"link":"acp://1.2.3.4:7801/tok_xxxxx"}'
# โ
Connected. {"peer_id":"peer_001"}
How it works: Three-level auto-fallback โ direct WebSocket โ UDP hole punch (DCUtR) โ relay. Your agents don't know or care which level they're on. The right level is chosen in < 3s.
ACP vs A2A (Google's protocol): A2A requires OAuth 2.0, an HTTPS endpoint you must host, and an agent registry. ACP requires pip install websockets. A2A is great for enterprise platforms; ACP is for individuals, sandboxed agents, and fast prototyping.
Status: Single-file Python daemon, 1574 tests passing, Apache 2.0. Built in public over ~190 commits. Would love feedback on the P2P design and the acp:// URI scheme.
Contributing
Contributions welcome! See CONTRIBUTING.md.
- Bug reports & feature requests โ GitHub Issues
- Protocol design discussion โ GitHub Discussions
License
๐ Quick Start
# Install
pip install websockets
# Start Agent A
python3 relay/acp_relay.py --name AgentA
# โ โ
Ready. Your link: acp://YOUR_IP:7801/tok_xxxxx
# In another terminal โ Agent B connects
python3 relay/acp_relay.py --name AgentB \
--join acp://YOUR_IP:7801/tok_xxxxx
# โ โ
Connected to AgentA
โ ๏ธ Incomplete Data
Some information about this model is not available. Use with Caution - Verify details from the original source before relying on this data.
View Original Source โ๐ Limitations & Considerations
- โข Benchmark scores may vary based on evaluation methodology and hardware configuration.
- โข VRAM requirements are estimates; actual usage depends on quantization and batch size.
- โข FNI scores are relative rankings and may change as new models are added.
- โ License Unknown: Verify licensing terms before commercial use.
Social Proof
AI Summary: Based on GitHub metadata. Not a recommendation.
๐ก๏ธ Model Transparency Report
Technical metadata sourced from upstream repositories.
๐ Identity & Source
- id
- gh-model--kickflip73--agent-communication-protocol
- slug
- kickflip73--agent-communication-protocol
- source
- github
- author
- Kickflip73
- license
- NOASSERTION
- tags
- a2a, agent-communication-protocol, ai-agents, autonomous-agents, llm, multi-agent-systems, open-standard, protocol, python, agentic-ai, mcp, nat-traversal, p2p, websocket
โ๏ธ Technical Specs
- architecture
- null
- params billions
- null
- context length
- null
- pipeline tag
- text-generation
๐ Engagement & Metrics
- downloads
- 0
- stars
- 6
- forks
- 0
Data indexed from public sources. Updated daily.