Skip to content

Commit e4db787

Browse files
committed
docs: comprehensive update for MCP, ANP, federation, and new adapters
Update all docs to reflect current codebase: - architecture.md: add MCP Server, ANP Bridge, federation, WebTransport, did:web/did:dns/VC, Google ADK and OpenAI adapters, A2A v1.0 compat - deployment.md: add MCP/ANP/federation config sections, updated env vars and TOML config, new metrics, WebTransport - protocol.md: add federation.proto (FederationService 2 RPCs), updated P2PExtension fields, WebTransport transport - python-sdk.md: add AgentCard did_web/did_dns/VC fields, did:web functions, ADK/OpenAI adapters, A2A v1.0 compat, OASF module - examples.md: add Google ADK and OpenAI Agents SDK integration examples, updated DID example with did:web - getting-started.md: add TypeScript install, Go version bump, new adapters - README.md: restore Three Ways / Interoperability / Relay sections with updated content, balance comprehensiveness with readability
1 parent 44d07e5 commit e4db787

7 files changed

Lines changed: 370 additions & 196 deletions

File tree

README.md

Lines changed: 62 additions & 156 deletions
Large diffs are not rendered by default.

docs/architecture.md

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,33 +52,38 @@ The daemon is the P2P engine. Internal packages:
5252
|---|---|
5353
| `internal/a2a/` | A2A protocol engine — task state machine, envelope routing, offline queue, streaming |
5454
| `internal/node/` | libp2p host — peer connections, mDNS discovery, DHT, stream multiplexing |
55-
| `internal/crypto/` | Ed25519 key management, Noise_XX integration |
55+
| `internal/crypto/` | Ed25519 key management, Noise_XX integration, DID conversion (did:key, did:web, did:dns), Verifiable Credentials |
5656
| `internal/nat/` | AutoNAT detection, DCUtR hole punching, Circuit Relay v2 client |
5757
| `internal/store/` | BoltDB persistence — tasks, agent cards, offline message queue |
5858
| `internal/config/` | Configuration — TOML file, environment variables, CLI flags |
5959
| `internal/bridge/` | HTTP Bridge — translates HTTP JSON-RPC ↔ P2P A2A envelopes |
60-
| `internal/anycast/` | Anycast router — skill-based addressing, registry + DHT discovery |
61-
| `internal/metrics/` | Prometheus metrics — connections, tasks, routing, bridge, streaming |
60+
| `internal/anycast/` | Anycast router — skill-based addressing, registry + multi-registry federation + DHT discovery |
61+
| `internal/metrics/` | Prometheus metrics — connections, tasks, routing, bridge, streaming, MCP |
62+
| `internal/mcp/` | MCP Server — exposes P2P capabilities as MCP tools (stdio + Streamable HTTP) |
63+
| `internal/anp/` | ANP Bridge — translates ANP HTTP ↔ A2A P2P (JSON-RPC 2.0 + JSON-LD) |
6264
| `pkg/grpcserver/` | gRPC server — 16 RPC methods exposed to the SDK |
6365

6466
The daemon is started and stopped by the SDK. It runs as a local process, listening only on a Unix domain socket (or localhost TCP).
6567

6668
### Relay Server (`agentanycast-relay`)
6769

68-
The relay provides two services:
70+
The relay provides three services:
6971

7072
1. **Circuit Relay v2** — bridges agents across different networks with strict resource limits. The relay **cannot read traffic** — all communication is end-to-end encrypted before reaching the relay.
7173

7274
2. **Skill Registry** — in-memory registry where agents register their skills and discover each other by capability. TTL-based expiration with heartbeat renewal.
7375

76+
3. **Federation** — gossip-based synchronization across multiple relays for global agent discovery. Uses Last-Writer-Wins conflict resolution.
77+
7478
### Proto Definitions (`agentanycast-proto`)
7579

7680
The single source of truth for all interfaces. Contains:
7781

7882
- **`node_service.proto`** — 16 RPC methods between SDK and daemon
7983
- **`registry_service.proto`** — 4 RPC methods for skill registry on relay
84+
- **`federation.proto`** — 2 RPC methods for multi-relay registry synchronization
8085
- **`a2a_models.proto`** — Task, Message, Part, Artifact, A2AEnvelope (11 envelope types)
81-
- **`agent_card.proto`** — A2A-compatible capability descriptor with P2P extension
86+
- **`agent_card.proto`** — A2A-compatible capability descriptor with P2P extension (did:key, did:web, did:dns, VCs)
8287
- **`streaming.proto`** — StreamStart, StreamChunk, StreamEnd for chunked delivery
8388
- **`common.proto`** — Shared types (PeerInfo, NodeInfo, TaskStatus)
8489

@@ -198,7 +203,13 @@ Every node has an **Ed25519 key pair**, generated on first start and persisted i
198203

199204
#### W3C DID Interop
200205

201-
Peer IDs can be converted to W3C Decentralized Identifiers (`did:key:z6Mk...`) for interoperability with DID-based systems. The SDK provides `peer_id_to_did_key()` and `did_key_to_peer_id()` for bidirectional conversion.
206+
Peer IDs can be converted to multiple DID methods for interoperability:
207+
208+
- **`did:key`** — derived directly from the Ed25519 public key (`did:key:z6Mk...`)
209+
- **`did:web`** — web-based DID resolution (`did:web:example.com:agents:myagent`)
210+
- **`did:dns`** — DNS-based DID resolution
211+
212+
The SDK provides bidirectional conversion functions (`peer_id_to_did_key`, `did_web_to_url`, etc.). Agent Cards can also carry Verifiable Credentials for trust attestation.
202213

203214
### Encryption
204215

@@ -232,7 +243,7 @@ Agents behind NATs or firewalls use a three-tier strategy:
232243

233244
### Tier 1: Direct Connection
234245

235-
If both agents are on the same network (or have public IPs), they connect directly via TCP or QUIC.
246+
If both agents are on the same network (or have public IPs), they connect directly via TCP, QUIC, or WebTransport.
236247

237248
### Tier 2: Hole Punching (DCUtR)
238249

@@ -337,19 +348,58 @@ If a message can't be delivered (peer is offline or unreachable), the daemon:
337348

338349
This provides **at-least-once delivery** for A2A envelopes without requiring the application to implement retry logic. Messages expire after a configurable TTL (default 24 hours).
339350

351+
## MCP Server
352+
353+
The daemon can run as an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server, exposing P2P capabilities as tools for AI assistants like Claude Desktop, Cursor, VS Code, ChatGPT, and Gemini CLI.
354+
355+
Two transport modes:
356+
- **stdio** — local integration (`agentanycastd -mcp`)
357+
- **Streamable HTTP** — remote clients (`agentanycastd -mcp-listen :3000`)
358+
359+
Available tools: `toolGetNodeInfo`, `toolListConnectedPeers`, `toolGetAgentCard`, `toolDiscoverAgents`, `toolSendTask`, `toolSendTaskBySkill`, `toolGetTaskStatus`.
360+
361+
The relay also exposes an MCP server with registry-specific tools (`discover_agents`, `list_skills`, `get_relay_info`).
362+
363+
## ANP Bridge
364+
365+
The [ANP (Agent Network Protocol)](https://www.w3.org/community/anp/) bridge enables interoperability with the W3C ANP ecosystem:
366+
367+
- `GET /agent/ad.json` — Agent Description (JSON-LD)
368+
- `GET /agent/interface.json` — OpenRPC specification
369+
- `POST /agent/rpc` — JSON-RPC 2.0 endpoint
370+
371+
## Multi-Relay Federation
372+
373+
Multiple relay servers can synchronize their skill registries using gossip-based federation:
374+
375+
1. Each relay periodically pulls updates from configured peer relays
376+
2. New registrations are pushed to peers
377+
3. Conflicts are resolved using Last-Writer-Wins with version counters
378+
4. Local registrations always take priority over federated ones
379+
380+
This enables global agent discovery across relay clusters without a single point of failure.
381+
340382
## Interoperability
341383

342-
### MCP (Model Context Protocol)
384+
### MCP Tool Mapping
343385

344386
The SDK can map MCP tools to A2A skills and vice versa, enabling agents built on MCP to participate in the AgentAnycast network.
345387

388+
### A2A v1.0 Protocol Compatibility
389+
390+
The Python SDK includes a compatibility layer (`compat/a2a_v1.py`) for bidirectional conversion between internal models and the official A2A v1.0 JSON format.
391+
392+
### OASF (Open Agentic Schema Framework)
393+
394+
Agent Cards can be converted to/from OASF records for publishing to the AGNTCY Agent Directory Service.
395+
346396
### AGNTCY Directory
347397

348398
The SDK can query the AGNTCY agent directory for cross-ecosystem discovery, finding agents registered in external directories.
349399

350400
### Framework Adapters
351401

352-
Built-in adapters for CrewAI and LangGraph wrap existing framework instances as P2P-capable agents, requiring minimal code changes.
402+
Built-in adapters for CrewAI, LangGraph, Google ADK, and OpenAI Agents SDK wrap existing framework instances as P2P-capable agents, requiring minimal code changes.
353403

354404
## gRPC Interface
355405

docs/deployment.md

Lines changed: 86 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ go build -o relay ./cmd/relay
5757
| `--max-reservations` | Max concurrent relay reservations | `128` |
5858
| `--registry-listen` | gRPC address for skill registry | `:50052` |
5959
| `--registry-ttl` | Skill registration TTL | `30s` |
60+
| `--enable-webtransport` | Enable WebTransport (QUIC-based) | `false` |
61+
| `--mcp-listen` | MCP Streamable HTTP listen address | `:8080` |
62+
| `--federation-peers` | Comma-separated peer relay gRPC addresses | (none) |
63+
| `--federation-sync-interval` | Federation gossip sync interval | `10s` |
6064
| `--log-level` | Log level (`debug`, `info`, `warn`, `error`) | `info` |
6165

6266
### Relay Resource Limits
@@ -107,47 +111,63 @@ CLI flags > environment variables > config file > defaults
107111
| Variable | Description | Default |
108112
|---|---|---|
109113
| `AGENTANYCAST_KEY_PATH` | Identity key file path | `~/.agentanycast/key` |
110-
| `AGENTANYCAST_GRPC_LISTEN` | gRPC listen address | `127.0.0.1:50051` |
114+
| `AGENTANYCAST_GRPC_LISTEN` | gRPC listen address | `unix://~/.agentanycast/daemon.sock` |
111115
| `AGENTANYCAST_LOG_LEVEL` | Log level | `info` |
112-
| `AGENTANYCAST_STORE_PATH` | BoltDB store path | `~/.agentanycast/store` |
116+
| `AGENTANYCAST_STORE_PATH` | BoltDB store path | `~/.agentanycast/data` |
113117
| `AGENTANYCAST_BOOTSTRAP_PEERS` | Comma-separated relay multiaddrs | (none) |
114118
| `AGENTANYCAST_ENABLE_MDNS` | Enable mDNS discovery | `true` |
119+
| `AGENTANYCAST_REGISTRY_ADDRS` | Comma-separated registry addresses (federation) | (none) |
120+
| `AGENTANYCAST_MCP_LISTEN` | MCP Streamable HTTP address | (none) |
115121

116122
### Config File
117123

118124
Default: `~/.agentanycast/config.toml`
119125

120126
```toml
121127
key_path = "~/.agentanycast/key"
122-
grpc_listen = "127.0.0.1:50051"
128+
grpc_listen = "unix://~/.agentanycast/daemon.sock"
123129
log_level = "info"
124130
log_format = "json"
125-
store_path = "~/.agentanycast/store"
131+
store_path = "~/.agentanycast/data"
126132
enable_mdns = true
127-
bootstrap_peers = [
128-
"/ip4/203.0.113.50/tcp/4001/p2p/12D3KooW..."
129-
]
133+
enable_quic = true
134+
enable_webtransport = false
135+
enable_relay_client = true
136+
enable_hole_punching = true
137+
offline_queue_ttl = "24h"
138+
bootstrap_peers = ["/ip4/203.0.113.50/tcp/4001/p2p/12D3KooW..."]
130139

131-
# HTTP Bridge — expose P2P agents via HTTP A2A endpoint
132140
[bridge]
133141
enabled = false
134142
listen = ":8080"
135143
# tls_cert = "/path/to/cert.pem"
136144
# tls_key = "/path/to/key.pem"
137-
# cors_origins = ["https://app.example.com"]
145+
# cors_origins = ["*"]
138146

139-
# Anycast — skill-based routing
140147
[anycast]
141-
# registry_addr = "relay.example.com:50052" # Relay's registry gRPC address
142-
enable_dht = false # Enable Kademlia DHT discovery
143-
dht_mode = "auto" # "auto", "server", or "client"
144-
cache_ttl = "30s" # Route cache TTL
145-
auto_register = true # Auto-register skills on startup
148+
routing_strategy = "random"
149+
cache_ttl = "30s"
150+
auto_register = true
151+
# registry_addr = "relay.example.com:50052"
152+
# registry_addrs = ["relay1:50052", "relay2:50052"] # multi-relay federation
153+
enable_dht = false
154+
dht_mode = "auto" # "auto", "server", or "client"
146155

147-
# Prometheus Metrics
148156
[metrics]
149157
enabled = false
150158
listen = ":9090"
159+
160+
[mcp]
161+
enabled = false
162+
listen = ":3000"
163+
164+
[anp]
165+
enabled = false
166+
listen = ":8090"
167+
168+
[identity]
169+
# did_web = "did:web:example.com:agents:myagent"
170+
# did_dns_domain = "example.com"
151171
```
152172

153173
## HTTP Bridge
@@ -222,6 +242,54 @@ enable_dht = true
222242
cache_ttl = "30s"
223243
```
224244

245+
## MCP Server
246+
247+
The daemon can run as an MCP (Model Context Protocol) server for AI tool integration.
248+
249+
### stdio mode (Claude Desktop, Cursor, VS Code, Gemini CLI)
250+
251+
```bash
252+
./agentanycastd -mcp
253+
```
254+
255+
### Streamable HTTP mode (ChatGPT, remote clients)
256+
257+
```toml
258+
[mcp]
259+
enabled = true
260+
listen = ":3000"
261+
```
262+
263+
Or via CLI: `./agentanycastd -mcp-listen :3000`
264+
265+
The relay also exposes an MCP server (default `:8080`) with registry-specific tools for agent discovery.
266+
267+
## ANP Bridge
268+
269+
The ANP (Agent Network Protocol) bridge enables interoperability with the W3C ANP ecosystem:
270+
271+
```toml
272+
[anp]
273+
enabled = true
274+
listen = ":8090"
275+
```
276+
277+
Exposes: `GET /agent/ad.json`, `GET /agent/interface.json`, `POST /agent/rpc`.
278+
279+
## Multi-Relay Federation
280+
281+
Multiple relays can synchronize their registries for global agent discovery:
282+
283+
```bash
284+
# Relay 1
285+
./relay --key ./relay1.key --federation-peers "relay2.example.com:50052"
286+
287+
# Relay 2
288+
./relay --key ./relay2.key --federation-peers "relay1.example.com:50052"
289+
```
290+
291+
Agents registered on Relay 1 become discoverable via Relay 2, and vice versa. Conflicts are resolved using Last-Writer-Wins with version counters.
292+
225293
## Prometheus Metrics
226294

227295
Enable observability with Prometheus:
@@ -247,6 +315,8 @@ Available metrics:
247315
| `agentanycast_stream_chunks_total` | Counter | Streaming chunks sent/received |
248316
| `agentanycast_messages_total` | Counter | A2A messages by type |
249317
| `agentanycast_offline_queue_size` | Gauge | Queued offline messages |
318+
| `agentanycast_connections_by_transport` | Counter | Connections by transport (tcp/quic/webtransport) |
319+
| `agentanycast_mcp_tool_calls_total` | Counter | MCP tool calls by tool and status |
250320

251321
### Running Multiple Nodes on One Machine
252322

docs/examples.md

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,58 @@ asyncio.run(main())
338338

339339
Install: `pip install agentanycast[langgraph]`
340340

341+
## Google ADK Integration
342+
343+
Expose a Google ADK agent as a P2P agent.
344+
345+
```python
346+
import asyncio
347+
from google.adk import Agent
348+
from agentanycast import AgentCard, Skill
349+
from agentanycast.adapters.adk import serve_adk_agent
350+
351+
agent = Agent(name="assistant", model="gemini-2.0-flash", ...)
352+
353+
card = AgentCard(
354+
name="ADKAgent",
355+
description="An agent powered by Google ADK",
356+
skills=[Skill(id="assist", description="General assistance")],
357+
)
358+
359+
async def main():
360+
await serve_adk_agent(agent, card=card, relay="...")
361+
362+
asyncio.run(main())
363+
```
364+
365+
Install: `pip install agentanycast[google-adk]`
366+
367+
## OpenAI Agents SDK Integration
368+
369+
Expose an OpenAI agent as a P2P agent.
370+
371+
```python
372+
import asyncio
373+
from agents import Agent
374+
from agentanycast import AgentCard, Skill
375+
from agentanycast.adapters.openai_agents import serve_openai_agent
376+
377+
agent = Agent(name="assistant", instructions="You are a helpful assistant.", model="gpt-4o")
378+
379+
card = AgentCard(
380+
name="OpenAIAgent",
381+
description="An agent powered by OpenAI",
382+
skills=[Skill(id="assist", description="General assistance")],
383+
)
384+
385+
async def main():
386+
await serve_openai_agent(agent, card=card, relay="...")
387+
388+
asyncio.run(main())
389+
```
390+
391+
Install: `pip install agentanycast[openai-agents]`
392+
341393
## MCP Tool Mapping
342394

343395
Convert MCP (Model Context Protocol) tools into A2A skills:
@@ -369,19 +421,21 @@ Work with W3C Decentralized Identifiers alongside Peer IDs:
369421

370422
```python
371423
from agentanycast.did import peer_id_to_did_key, did_key_to_peer_id
424+
from agentanycast.did import did_web_to_url, url_to_did_web
372425

373-
# Convert Peer ID to DID
374-
did = peer_id_to_did_key("12D3KooWAbCdEf...")
375-
print(did) # "did:key:z6MkhaXgBZ..."
426+
# did:key — derived from Ed25519 public key
427+
did = peer_id_to_did_key("12D3KooWAbCdEf...") # "did:key:z6Mk..."
428+
peer_id = did_key_to_peer_id("did:key:z6Mk...") # "12D3KooWAbCdEf..."
376429

377-
# Convert DID back to Peer ID
378-
peer_id = did_key_to_peer_id("did:key:z6MkhaXgBZ...")
379-
print(peer_id) # "12D3KooWAbCdEf..."
430+
# did:web — web-based DID resolution
431+
url = did_web_to_url("did:web:example.com:agents:myagent")
432+
# "https://example.com/agents/myagent/did.json"
380433

381-
# The AgentCard also includes the DID
434+
# The AgentCard includes all DID methods
382435
async with Node(card=card) as node:
383436
remote_card = await node.get_card("12D3KooW...")
384437
print(remote_card.did_key) # "did:key:z6Mk..."
438+
print(remote_card.did_web) # "did:web:example.com:agents:myagent"
385439
```
386440

387441
## Cross-Network Communication

0 commit comments

Comments
 (0)