11# AgentAnycast Python SDK
22
3- Python SDK for AgentAnycast -- decentralized A2A agent-to-agent communication over P2P .
3+ ** Build P2P agents in Python. ** Discover, communicate, and collaborate with AI agents across any network -- encrypted, decentralized, NAT-traversing .
44
5+ [ ![ PyPI] ( https://img.shields.io/pypi/v/agentanycast?color=3776AB )] ( https://pypi.org/project/agentanycast/ )
56[ ![ Python] ( https://img.shields.io/badge/Python-3.10+-3776AB?logo=python&logoColor=white )] ( https://python.org )
67[ ![ License] ( https://img.shields.io/badge/License-Apache%202.0-blue )] ( LICENSE )
78
8- > ** AgentAnycast is fully decentralized.** On a local network, it works with zero configuration. For cross-network communication, just deploy your own relay with a single command.
9-
10- ## Installation
11-
129``` bash
1310pip install agentanycast
1411```
1512
16- With framework adapters:
17-
18- ``` bash
19- pip install agentanycast[crewai] # CrewAI integration
20- pip install agentanycast[langgraph] # LangGraph integration
21- pip install agentanycast[google-adk] # Google ADK integration
22- pip install agentanycast[openai-agents] # OpenAI Agents SDK integration
23- pip install agentanycast[claude] # Claude Agent SDK integration
24- pip install agentanycast[strands] # AWS Strands Agents integration
25- ```
26-
27- ## How It Works
28-
29- ```
30- ┌─────────────┐ mDNS / Relay ┌─────────────┐
31- │ Agent A │◄──────────────────────────────►│ Agent B │
32- │ (Python) │ E2E encrypted (Noise) │ (Python) │
33- └──────┬──────┘ └──────┬──────┘
34- │ gRPC │ gRPC
35- ┌──────┴──────┐ ┌──────┴──────┐
36- │ agentanycastd│ │ agentanycastd│
37- │ (daemon) │ │ (daemon) │
38- └─────────────┘ └──────────────┘
39- ```
40-
41- - ** Local network (LAN):** Agents discover each other automatically via mDNS. No relay needed.
42- - ** Cross-network (WAN):** Deploy your own relay server, then point agents to it. One command.
43-
4413## Quick Start
4514
46- ### CLI
47-
48- ``` bash
49- # Start an echo agent
50- agentanycast demo
51-
52- # Discover agents by skill
53- agentanycast discover translate
54-
55- # Send a task to a specific agent
56- agentanycast send 12D3KooW... " Hello!"
57-
58- # Check node status
59- agentanycast status
60- ```
61-
62- ### Python API
63-
64- ** Server agent:**
15+ ** Create an agent:**
6516
6617``` python
6718from agentanycast import Node, AgentCard, Skill
6819
6920card = AgentCard(
7021 name = " EchoAgent" ,
7122 description = " Echoes back any message" ,
72- skills = [Skill(id = " echo" , description = " Echo messages " )],
23+ skills = [Skill(id = " echo" , description = " Echo the input " )],
7324)
7425
7526async with Node(card = card) as node:
@@ -78,16 +29,13 @@ async with Node(card=card) as node:
7829 text = task.messages[- 1 ].parts[0 ].text
7930 await task.complete(artifacts = [{" parts" : [{" text" : f " Echo: { text} " }]}])
8031
32+ print (f " Agent running — Peer ID: { node.peer_id} " )
8133 await node.serve_forever()
8234```
8335
84- ** Client agent:**
36+ ** Send a task to another agent:**
8537
8638``` python
87- from agentanycast import Node, AgentCard
88-
89- card = AgentCard(name = " Client" , description = " A client agent" , skills = [])
90-
9139async with Node(card = card) as node:
9240 handle = await node.send_task(
9341 peer_id = " 12D3KooW..." ,
@@ -97,145 +45,150 @@ async with Node(card=card) as node:
9745 print (result.artifacts[0 ].parts[0 ].text) # "Echo: Hello!"
9846```
9947
100- ### Three Ways to Send a Task
48+ ## Three Ways to Send a Task
10149
10250``` python
103- # 1. Direct — by Peer ID
51+ # Direct — by Peer ID
10452await node.send_task(peer_id = " 12D3KooW..." , message = msg)
10553
106- # 2. Anycast — by skill (relay resolves the target)
54+ # Anycast — by skill (relay resolves the target)
10755await node.send_task(skill = " translate" , message = msg)
10856
109- # 3. HTTP Bridge — to standard HTTP A2A agents
57+ # HTTP Bridge — to standard HTTP A2A agents
11058await node.send_task(url = " https://agent.example.com" , message = msg)
11159```
11260
113- ### Skill Discovery
61+ ## CLI
11462
115- ``` python
116- # Find all agents offering a skill
117- agents = await node.discover(" translate" )
63+ ``` bash
64+ agentanycast demo # Start an echo agent
65+ agentanycast discover translate # Find agents by skill
66+ agentanycast send 12D3KooW... " Hello!" # Send a task
67+ agentanycast status # Check node status
68+ agentanycast info # Show Peer ID, DID, version
69+ ```
70+
71+ ## How It Works
11872
119- # With tag filtering
120- agents = await node.discover(" translate" , tags = {" lang" : " fr" })
12173```
74+ ┌─────────────┐ mDNS / Relay ┌─────────────┐
75+ │ Agent A │<------------------------------>│ Agent B │
76+ │ (Python) │ E2E encrypted (Noise) │ (Python) │
77+ └──────┬──────┘ └──────┬──────┘
78+ | gRPC | gRPC
79+ ┌──────┴──────┐ ┌──────┴──────┐
80+ │ agentanycastd│ │ agentanycastd│
81+ │ (Go daemon)│<---------- libp2p ------------>│ (Go daemon) │
82+ └─────────────┘ └──────────────┘
83+ ```
84+
85+ - ** LAN** -- agents discover each other via mDNS. Zero configuration.
86+ - ** WAN** -- deploy a [ self-hosted relay] ( https://github.com/AgentAnycast/agentanycast-relay ) and point agents to it.
87+ - The Go daemon is ** auto-downloaded and managed** by the SDK. No manual setup.
12288
12389## Framework Adapters
12490
125- Expose existing agent frameworks as P2P agents with one function call:
91+ Turn existing frameworks into P2P agents with one function call:
92+
93+ ``` bash
94+ pip install agentanycast[crewai] # CrewAI
95+ pip install agentanycast[langgraph] # LangGraph
96+ pip install agentanycast[google-adk] # Google ADK
97+ pip install agentanycast[openai-agents] # OpenAI Agents SDK
98+ pip install agentanycast[claude] # Claude Agent SDK
99+ pip install agentanycast[strands] # AWS Strands Agents
100+ ```
126101
127102``` python
128- # CrewAI
129103from agentanycast.adapters.crewai import serve_crew
130- await serve_crew(crew, card = card, relay = " ..." )
131-
132- # LangGraph
133104from agentanycast.adapters.langgraph import serve_graph
134- await serve_graph(compiled_graph, card = card, relay = " ..." )
135-
136- # Google ADK
137105from agentanycast.adapters.adk import serve_adk_agent
138- await serve_adk_agent(agent, card = card, relay = " ..." )
139-
140- # OpenAI Agents SDK
141106from agentanycast.adapters.openai_agents import serve_openai_agent
107+ from agentanycast.adapters.claude_agent import serve_claude_agent
108+ from agentanycast.adapters.strands import serve_strands_agent
109+
110+ await serve_crew(crew, card = card, relay = " ..." )
111+ await serve_graph(graph, card = card, relay = " ..." )
112+ await serve_adk_agent(agent, card = card, relay = " ..." )
142113await serve_openai_agent(agent, card = card, relay = " ..." )
114+ await serve_claude_agent(prompt_template = " ..." , card = card)
115+ await serve_strands_agent(agent, card = card)
116+ ```
143117
144- # Claude Agent SDK
145- from agentanycast.adapters.claude_agent import serve_claude_agent
146- await serve_claude_agent(
147- prompt_template = " You are a helpful assistant. User query: {input} " ,
148- card = AgentCard(name = " claude-agent" , skills = [Skill(id = " chat" )]),
149- relay = " /ip4/relay.example.com/tcp/4001/p2p/12D3KooW..." ,
150- )
118+ ## Skill Discovery
151119
152- # AWS Strands
153- from agentanycast.adapters.strands import serve_strands_agent
154- agent = Agent(model = " us.anthropic.claude-sonnet-4-20250514" )
155- await serve_strands_agent(
156- agent,
157- card = AgentCard(name = " strands-agent" , skills = [Skill(id = " reasoning" )]),
158- relay = " /ip4/relay.example.com/tcp/4001/p2p/12D3KooW..." ,
159- )
120+ ``` python
121+ agents = await node.discover(" translate" )
122+ agents = await node.discover(" translate" , tags = {" lang" : " fr" })
160123```
161124
162125## Interoperability
163126
164- ### W3C DID
165-
166127``` python
128+ # W3C DID
167129from agentanycast.did import peer_id_to_did_key, did_key_to_peer_id
168- from agentanycast.did import did_web_to_url, url_to_did_web
169-
170130did = peer_id_to_did_key(" 12D3KooW..." ) # "did:key:z6Mk..."
171131pid = did_key_to_peer_id(" did:key:z6Mk..." ) # "12D3KooW..."
172132
173- url = did_web_to_url(" did:web:example.com:agents:myagent" )
174- # "https://example.com/agents/myagent/did.json"
175- ```
176-
177- ### MCP (Model Context Protocol)
178-
179- ``` python
133+ # MCP Tool <-> A2A Skill mapping
180134from agentanycast.mcp import mcp_tools_to_agent_card
181-
182135card = mcp_tools_to_agent_card(mcp_tools, name = " MCPAgent" )
183- ```
184-
185- ### A2A v1.0 Protocol Compatibility
186136
187- ``` python
137+ # A2A v1.0 JSON format
188138from agentanycast.compat.a2a_v1 import task_to_a2a_json, task_from_a2a_json
189139
190- # Convert internal Task ↔ official A2A v1.0 JSON format
191- a2a_json = task_to_a2a_json(task)
192- task = task_from_a2a_json(a2a_json)
193- ```
194-
195- ### OASF (Open Agentic Schema Framework)
196-
197- ``` python
198- from agentanycast.compat.oasf import card_to_oasf_record, card_from_oasf_record
199-
200- # Convert AgentCard ↔ OASF records for AGNTCY Agent Directory
201- record = card_to_oasf_record(card, authors = [" org" ])
202- card = card_from_oasf_record(record)
140+ # OASF / AGNTCY Directory
141+ from agentanycast.compat.oasf import card_to_oasf_record
142+ from agentanycast.compat.agntcy import AGNTCYDirectory
203143```
204144
205- ### AGNTCY Directory
145+ ## API Reference
206146
207- ``` python
208- from agentanycast.compat.agntcy import AGNTCYDirectory
147+ ### Node
209148
210- directory = AGNTCYDirectory(base_url = " https://directory.agntcy.org" )
211- agents = await directory.search(" translation" )
212- ```
149+ | Method | Description |
150+ | ---| ---|
151+ | ` Node(card, relay?, home?, ...) ` | Create a node with an AgentCard and optional config |
152+ | ` async with Node(...) as node ` | Context manager -- starts/stops daemon automatically |
153+ | ` send_task(peer_id?, skill?, url?, message=) ` | Send a task using any addressing mode |
154+ | ` discover(skill, tags?) ` | Find agents by skill with optional tag filtering |
155+ | ` on_task(handler) ` | Register handler for incoming tasks |
156+ | ` serve_forever() ` | Block and process incoming tasks until stopped |
213157
214- ## API Reference
158+ ### Core Types
215159
216160| Class | Description |
217161| ---| ---|
218- | ` Node ` | Main entry point. Manages daemon lifecycle, sends and receives tasks. |
219- | ` AgentCard ` | Describes an agent's identity, capabilities, and metadata. |
220- | ` Skill ` | Defines a single skill an agent can perform. |
221- | ` TaskHandle ` | Returned by ` send_task() ` . Call ` wait() ` to block until the remote agent responds. |
222- | ` IncomingTask ` | Passed to task handlers. Provides the incoming message and methods to respond. |
162+ | ` AgentCard ` | Agent identity, capabilities, and metadata |
163+ | ` Skill ` | A single capability an agent can perform |
164+ | ` TaskHandle ` | Returned by ` send_task() ` . Call ` wait() ` for the result. |
165+ | ` IncomingTask ` | Passed to task handlers. Provides message data and response methods. |
223166
224- ## Node Options
167+ ### Node Options
225168
226169| Parameter | Description | Default |
227170| ---| ---| ---|
228- | ` card ` | Your agent 's ` AgentCard ` | Required |
229- | ` relay ` | Relay server multiaddr for cross-network communication | ` None ` (LAN only) |
171+ | ` card ` | Agent 's ` AgentCard ` | Required |
172+ | ` relay ` | Relay multiaddr for cross-network communication | ` None ` (LAN only) |
230173| ` daemon_path ` | Path to a local ` agentanycastd ` binary | Auto-download |
231174| ` daemon_addr ` | Address of an externally managed daemon | Auto-managed |
232175| ` key_path ` | Path to Ed25519 identity key file | ` <home>/key ` |
233- | ` home ` | Data directory for daemon state. Use different values to run multiple nodes on the same machine. | ` ~/.agentanycast ` |
176+ | ` home ` | Data directory. Use different values for multiple nodes. | ` ~/.agentanycast ` |
177+
178+ ## Development
179+
180+ ``` bash
181+ pip install -e " .[dev]" # Install in editable mode with dev deps
182+ pytest # Run all tests
183+ ruff check . # Lint
184+ ruff format . # Format
185+ mypy src/ # Type check (strict)
186+ ```
234187
235188## Requirements
236189
237190- Python 3.10+
238- - The [ agentanycastd] ( https://github.com/AgentAnycast/agentanycast-node ) daemon (auto-managed by the SDK, or bring your own )
191+ - The [ agentanycastd] ( https://github.com/AgentAnycast/agentanycast-node ) daemon (auto-managed by the SDK)
239192
240193## License
241194
0 commit comments