Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions samples/python/agents/a2a_mcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ All the 3 ADK agents use the same python code but are instantiated with differen
cd samples/python/agents/a2a_mcp
uv venv # (if not already done)
source .venv/bin/activate
# Runs on port 10000 by default, change as needed by setting the --host and --port parameters.
uv run a2a-mcp --run mcp-server --transport sse
# Runs on port 10100 by default, change as needed by setting the --host and --port parameters.
uv run --env-file .env a2a-mcp --run mcp-server --transport sse
```

2. Start the Orchestrator Agent:
Expand All @@ -177,7 +177,7 @@ All the 3 ADK agents use the same python code but are instantiated with differen
uv venv # (if not already done)
source .venv/bin/activate
# Note: Change the host and port as needed.
uv run src/a2a_mcp/agents/ --agent-card agent_cards/orchestrator_agent.json --port 10101
uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/orchestrator_agent.json --port 10101
```

3. Start the Planner Agent:
Expand All @@ -189,7 +189,7 @@ All the 3 ADK agents use the same python code but are instantiated with differen
uv venv # (if not already done)
source .venv/bin/activate
# Note: Change the host and port as needed.
uv run src/a2a_mcp/agents/ --agent-card agent_cards/planner_agent.json --port 10102
uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/planner_agent.json --port 10102
```

4. Start the Airline Ticketing Agent:
Expand All @@ -201,7 +201,7 @@ All the 3 ADK agents use the same python code but are instantiated with differen
uv venv # (if not already done)
source .venv/bin/activate
# Note: Change the host and port as needed.
uv run src/a2a_mcp/agents/ --agent-card agent_cards/air_ticketing_agent.json --port 10103
uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/air_ticketing_agent.json --port 10103
```

5. Start the Hotel Reservations Agent:
Expand All @@ -213,7 +213,7 @@ All the 3 ADK agents use the same python code but are instantiated with differen
uv venv # (if not already done)
source .venv/bin/activate
# Note: Change the host and port as needed.
uv run src/a2a_mcp/agents/ --agent-card agent_cards/hotel_booking_agent.json --port 10104
uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/hotel_booking_agent.json --port 10104
```

6. Start the Car Rental Reservations Agent:
Expand All @@ -225,10 +225,21 @@ All the 3 ADK agents use the same python code but are instantiated with differen
uv venv # (if not already done)
source .venv/bin/activate
# Note: Change the host and port as needed.
uv run src/a2a_mcp/agents/ --agent-card agent_cards/car_rental_agent.json --port 10105
uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/car_rental_agent.json --port 10105
```

7. Start the cli:

In a new terminal window

```bash
cd samples/python/agents/a2a_mcp
uv venv # (if not already done)
source .venv/bin/activate

uv run --env-file .env src/a2a_mcp/mcp/client.py --resource "resource://agent_cards/list" --find_agent "I would like to plan a trip to France."
```

7. Follow the steps in hosts/cli to start the cli app.

### File/Directory Descriptions

Expand Down
2 changes: 1 addition & 1 deletion samples/python/agents/a2a_mcp/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description = "A2A - MCP Sample"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"a2a-sdk>=0.2.9",
"a2a-sdk[sql]>=0.2.11",
"click>=8.1.8",
"fastmcp>=1.0",
"google-adk>=1.0.0",
Expand Down
11 changes: 9 additions & 2 deletions samples/python/agents/a2a_mcp/src/a2a_mcp/agents/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@

from a2a.server.apps import A2AStarletteApplication
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.tasks import InMemoryPushNotifier, InMemoryTaskStore
from a2a.server.tasks import InMemoryTaskStore
from a2a.server.tasks import InMemoryPushNotificationConfigStore, BasePushNotificationSender

from a2a.types import AgentCard
from a2a_mcp.common import prompts
from a2a_mcp.common.agent_executor import GenericAgentExecutor
Expand Down Expand Up @@ -68,10 +70,15 @@ def main(host, port, agent_card):
agent_card = AgentCard(**data)

client = httpx.AsyncClient()
push_notification_config_store = InMemoryPushNotificationConfigStore()
push_notification_sender = BasePushNotificationSender(client,
config_store=push_notification_config_store)

request_handler = DefaultRequestHandler(
agent_executor=GenericAgentExecutor(agent=get_agent(agent_card)),
task_store=InMemoryTaskStore(),
push_notifier=InMemoryPushNotifier(client),
push_config_store=push_notification_config_store,
push_sender=push_notification_sender
)

server = A2AStarletteApplication(
Expand Down
12 changes: 9 additions & 3 deletions samples/python/agents/a2a_mcp/src/a2a_mcp/mcp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ async def search_flights(session: ClientSession) -> CallToolResult:
Returns:
The result of the tool call.
"""
# TODO: Implementation pending
logger.info("Calling 'search_flights' tool'")
return await session.call_tool(
name='search_flights',
Expand All @@ -144,6 +145,7 @@ async def search_hotels(session: ClientSession) -> CallToolResult:
Returns:
The result of the tool call.
"""
# TODO: Implementation pending
logger.info("Calling 'search_hotels' tool'")
return await session.call_tool(
name='search_hotels',
Expand All @@ -160,14 +162,14 @@ async def query_db(session: ClientSession) -> CallToolResult:

Args:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The docstring for query_db lists a query parameter, but the function signature async def query_db(session: ClientSession) does not accept it. This discrepancy between the documentation and the implementation is misleading.

Since the function currently uses a hardcoded SQL query for testing purposes, the query parameter should be removed from the docstring to accurately reflect the function's signature.

Copy link
Contributor Author

@kyoto7250 kyoto7250 Jul 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is any need to change the existing implementation,
and I'd like to hear the maintainers' opinions on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The argument description for query is inaccurate, as it refers to search_hotels tool, which is not relevant in this context. It should refer to the query_db tool instead.

Suggested change
Args:
query: The natural language query to send to the 'query_db' tool.

session: The active ClientSession.
query: The natural language query to send to the 'search_hotels' tool.
query: The natural language query to send to the 'query_db' tool.

Returns:
The result of the tool call.
"""
logger.info("Calling 'search_hotels' tool'")
logger.info("Calling 'query_db' tool'")
return await session.call_tool(
name='query_db',
name='query_travel_data',
arguments={
'query': "SELECT id, name, city, hotel_type, room_type, price_per_night FROM hotels WHERE city='London'",
},
Expand All @@ -186,6 +188,8 @@ async def main(host, port, transport, query, resource, tool):
transport: Connection transport ('sse' or 'stdio').
query: Optional query string for the 'find_agent' tool.
resource: Optional resource URI to read.
tool: Optional tool name to execute. Valid options are:
'search_flights', 'search_hotels', or 'query_db'.
"""
logger.info('Starting Client to connect to MCP')
async with init_session(host, port, transport) as session:
Expand Down Expand Up @@ -220,6 +224,8 @@ async def main(host, port, transport, query, resource, tool):
@click.option('--transport', default='stdio', help='MCP Transport')
@click.option('--find_agent', help='Query to find an agent')
@click.option('--resource', help='URI of the resource to locate')
@click.option('--tool_name', type=click.Choice(['search_flights', 'search_hotels', 'query_db']),
help='Tool to execute: search_flights, search_hotels, or query_db')
def cli(host, port, transport, find_agent, resource, tool_name):
"""A command-line client to interact with the Agent Cards MCP server."""
asyncio.run(main(host, port, transport, find_agent, resource, tool_name))
Expand Down
Loading