Skip to content

Commit 4c808e3

Browse files
committed
feat: updating usage guides and bumping pyproject version
1 parent 7ccf954 commit 4c808e3

5 files changed

Lines changed: 38 additions & 366 deletions

File tree

docs/A2A_USAGE_GUIDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
2929
Create a new project directory:
3030

3131
```bash
32-
uv init a2a-pubsub
33-
cd a2a-pubsub
32+
uv init agntcy-a2a
33+
cd agntcy-a2a
3434
```
3535

3636
Install the Agntcy Application SDK and Langgraph:

docs/MCP_USAGE_GUIDE.md

Lines changed: 34 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Additional features incorporating AGNTCY's identity and observability components
2020

2121
### ⚡️ Connecting an MCP client to an MCP server over an abstract transport (SLIM | NATS | MQTT)
2222

23-
A benefit of decoupling protocols from transports is that you can easily create agents that communicate over non http, point-to-point transports such as NATS or Agntcy's SLIM. Below is an example of how to create two A2A agents that communicate over SLIM's PubSub gateway.
23+
A benefit of decoupling protocols from transports is that you can easily create agents that communicate over non http, point-to-point transports such as NATS or Agntcy's SLIM. Below is an example of how to create an MCP client and server that communicate over SLIM's gateway server.
2424

2525
We will use `uv` for package management and virtual environments. If you don't have it installed, you can install it via:
2626

@@ -31,8 +31,8 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
3131
Create a new project directory:
3232

3333
```bash
34-
uv init a2a-pubsub
35-
cd a2a-pubsub
34+
uv init agntcy-mcp
35+
cd agntcy-mcp
3636
```
3737

3838
Install the Agntcy Application SDK and Langgraph:
@@ -44,142 +44,52 @@ uv add agntcy-app-sdk
4444
Next we will create a simple weather agent that responds to weather queries. Create a file named `weather_agent.py` and implement the A2A agent and add a message bridge to a SLIM transport:
4545

4646
```python
47-
from a2a.server.agent_execution import AgentExecutor, RequestContext
48-
from a2a.server.events import EventQueue
49-
from a2a.utils import new_agent_text_message
50-
from a2a.types import (
51-
AgentCapabilities,
52-
AgentCard,
53-
AgentSkill,
54-
)
55-
from a2a.server.apps import A2AStarletteApplication
56-
from a2a.server.request_handlers import DefaultRequestHandler
57-
from a2a.server.tasks import InMemoryTaskStore
5847
from agntcy_app_sdk.factory import AgntcyFactory
48+
from mcp.server.fastmcp import FastMCP
5949

60-
"""
61-
Create the AgentSkill and AgentCard for a simple weather report agent.
62-
"""
63-
64-
skill = AgentSkill(
65-
id="weather_report",
66-
name="Returns weather report",
67-
description="Provides a simple weather report",
68-
tags=["weather", "report"],
69-
examples=["What's the weather like?", "Give me a weather report"],
70-
)
71-
72-
agent_card = AgentCard(
73-
name="Weather Agent",
74-
description="An agent that provides weather reports",
75-
url="",
76-
version="1.0.0",
77-
defaultInputModes=["text"],
78-
defaultOutputModes=["text"],
79-
capabilities=AgentCapabilities(streaming=True),
80-
skills=[skill],
81-
supportsAuthenticatedExtendedCard=False,
82-
)
83-
84-
"""
85-
Create the actual agent logic and executor.
86-
"""
87-
88-
class WeatherAgent:
89-
"""A simple agent that returns a weather report."""
90-
async def invoke(self) -> str:
91-
return "The weather is sunny with a high of 75°F."
92-
93-
class WeatherAgentExecutor(AgentExecutor):
94-
"""Test AgentProxy Implementation."""
95-
96-
def __init__(self):
97-
self.agent = WeatherAgent()
98-
99-
async def execute(
100-
self,
101-
context: RequestContext,
102-
event_queue: EventQueue,
103-
) -> None:
104-
result = await self.agent.invoke()
105-
event_queue.enqueue_event(new_agent_text_message(result))
106-
107-
async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
108-
raise Exception("cancel not supported")
109-
110-
"""
111-
Create the A2A server and transport bridge to server the Weather Agent.
112-
"""
113-
114-
async def main():
115-
# create an app-sdk factory to create the transport and bridge
116-
factory = AgntcyFactory()
50+
# create an MCP server instance
51+
mcp = FastMCP()
11752

118-
request_handler = DefaultRequestHandler(
119-
agent_executor=WeatherAgentExecutor(),
120-
task_store=InMemoryTaskStore(),
121-
)
122-
123-
server = A2AStarletteApplication(
124-
agent_card=agent_card, http_handler=request_handler
125-
)
53+
# add a tool to the MCP server
54+
@mcp.tool()
55+
async def get_forecast(location: str) -> str:
56+
return "Temperature: 30°C\n" "Humidity: 50%\n" "Condition: Sunny\n"
12657

127-
transport = factory.create_transport("SLIM", endpoint="http://localhost:46357")
128-
bridge = factory.create_bridge(server, transport=transport)
129-
await bridge.start(blocking=True)
58+
# create an Agntcy factory transport instance
59+
transport = factory.create_transport("SLIM", endpoint="http://localhost:46357")
60+
# transport = factory.create_transport("NATS", endpoint="localhost:4222")
13061

131-
if __name__ == "__main__":
132-
import asyncio
133-
asyncio.run(main())
62+
# serve the MCP server via a message bridge
63+
bridge = factory.create_bridge(mcp, transport=transport, topic="my_weather_agent.mcp")
64+
await bridge.start(blocking=block)
13465
```
13566

13667
Next we will create a simple client agent that queries the weather agent. Create a file named `weather_client.py` and implement the A2A client with a SLIM transport:
13768

13869
```python
139-
from a2a.types import (
140-
SendMessageRequest,
141-
MessageSendParams,
142-
Message,
143-
Part,
144-
TextPart,
145-
Role,
146-
)
147-
14870
from agntcy_app_sdk.factory import AgntcyFactory
149-
from agntcy_app_sdk.factory import ProtocolTypes
150-
from agntcy_app_sdk.protocols.a2a.protocol import A2AProtocol
151-
from weather_agent import agent_card
15271

15372
factory = AgntcyFactory()
15473
transport = factory.create_transport("SLIM", endpoint="http://localhost:46357")
155-
156-
async def main():
157-
# create an app-sdk factory to create the transport and bridge
158-
factory = AgntcyFactory()
159-
160-
a2a_topic = A2AProtocol.create_agent_topic(agent_card)
161-
162-
# create a client to connect to the A2A server
163-
client = await factory.create_client(ProtocolTypes.A2A.value, agent_topic=a2a_topic, transport=transport)
164-
165-
message = "Hello, Weather Agent, how is the weather?"
166-
request = SendMessageRequest(
167-
params=MessageSendParams(
168-
message=Message(
169-
messageId="0",
170-
role=Role.user,
171-
parts=[Part(TextPart(text=message))],
172-
),
173-
)
74+
# transport = factory.create_transport("NATS", endpoint="localhost:4222")
75+
76+
# Create a MCP client
77+
print("[test] Creating MCP client...")
78+
mcp_client = factory.create_client(
79+
"MCP",
80+
agent_topic="my_weather_agent.mcp",
81+
transport=transport_instance,
82+
)
83+
async with mcp_client as client:
84+
# Build message request
85+
tools = await client.list_tools()
86+
print("[test] Tools available:", tools)
87+
88+
result = await client.call_tool(
89+
name="get_forecast",
90+
arguments={"location": "Colombia"},
17491
)
175-
176-
# send a message to the agent
177-
response = await client.send_message(request)
178-
print(response)
179-
180-
if __name__ == "__main__":
181-
import asyncio
182-
asyncio.run(main())
92+
print(f"Tool call result: {result}")
18393
```
18494

18595
A few notes about the code above:

0 commit comments

Comments
 (0)