An MCP server for the Agent2Agent (A2A) protocol
Project description
A2A MCP Server
A Model Context Protocol (MCP) server that connects Claude and other LLMs to the Agent2Agent (A2A) Protocol. This server enables LLMs to interact with multiple A2A-compatible agents through a unified, structured interface.
The A2A protocol standardizes agent communication by introducing concepts like Agent Cards, Tasks, Artifacts, Context, and more. This MCP server bridges the gap between MCP-compatible LLMs (like Claude Desktop) and any A2A-compatible agent, allowing you to build powerful multi-agent workflows.
โจ Features
- Multi-Agent Support - Connect to multiple A2A agents simultaneously from a single MCP server
- Conversation Management - Track multi-turn conversations with automatic context and task state tracking
- Structured Responses - Get JSON-formatted responses with task metadata, agent messages, and artifacts
- Smart Response Minimization - Automatically minimize large datasets (shows first/last items) to avoid overwhelming LLMs
- Powerful Artifact Filtering - Filter artifacts using regex, JSON path, or field extraction without additional LLM calls
- Name Conflict Resolution - Automatically handles duplicate agent names with intelligent suffixing
- Parallel Agent Loading - Fetches and initializes agent cards in parallel for fast startup
- Custom Headers Support - Add authentication headers per-agent or globally
- Type-Safe - Written in Python with full type hints and strict mypy checking
๐ Requirements
- Python 3.13+
- uv package manager
- An MCP-compatible client (like Claude Desktop)
- At least one A2A-compatible agent (see A2A Net for examples)
๐ฆ Installation
This project uses uv for fast, reliable dependency management.
# Clone the repository
git clone https://github.com/A2ANet/a2a-mcp.git
cd a2a-mcp
# Install dependencies
uv sync
โก Quick Start
1. Configure Your Agents
Set the A2A_AGENT_CARDS environment variable with your agent configuration:
export A2A_AGENT_CARDS='[
{
"url": "https://a2anet.com/agent/YOUR_AGENT_ID/agent-card.json",
"custom_headers": {
"X-API-Key": "your-api-key-here"
}
}
]'
For multiple agents:
export A2A_AGENT_CARDS='[
{
"url": "https://a2anet.com/agent/twitter/agent-card.json",
"custom_headers": {"X-API-Key": "twitter-key"}
},
{
"url": "https://a2anet.com/agent/analytics/agent-card.json",
"custom_headers": {"Authorization": "Bearer analytics-token"}
}
]'
2. Test the Server
# Run the server
uv run python main.py
You should see:
Successfully initialized 2 agent(s):
- Twitter Agent: Find and analyze tweets by keyword, author, or URL
Skills: Find Tweets, Filter Table, Generate Table
- Analytics Agent: Analyze data and generate insights
Skills: Data Analysis, Visualization, Reporting
A2A MCP Server is ready
3. Add to Claude Desktop
Edit your Claude Desktop configuration file:
macOS/Linux: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"a2a": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/a2a-mcp",
"run",
"python",
"main.py"
],
"env": {
"A2A_AGENT_CARDS": "[{\"url\": \"https://a2anet.com/agent/YOUR_ID/agent-card.json\", \"custom_headers\": {\"X-API-KEY\": \"your-key\"}}]"
}
}
}
}
Restart Claude Desktop and the A2A tools will be available!
๐ Usage
Available Tools
The MCP server provides three main tools:
1. send_message_to_agent
Send a message to an A2A agent and receive a structured response.
Parameters:
agent_name(string, required): Name of the agent (fromlist_available_agents)message(string, required): Your message or requestcontext_id(string, optional): Context ID to continue a conversation
Example: Start a new conversation
send_message_to_agent(
agent_name="Twitter Agent",
message="Find tweets about AI from the last week"
)
Response:
{
"task_id": "task-abc123",
"context_id": "ctx-xyz789",
"task_state": "completed",
"agent_message": "I found 50 tweets about AI from the last week.",
"artifacts": [
{
"artifact_id": "art-456",
"name": "AI Tweets",
"description": "Search results for tweets about AI",
"parts": [
{
"type": "data",
"data": {
"_type": "minimized_list",
"length": 50,
"first": {
"text": "AI is transforming healthcare...",
"author": "@techexpert",
"likes": 142
},
"last": {
"text": "Latest AI research breakthrough...",
"author": "@airesearcher",
"likes": 89
}
}
}
]
}
],
"tips": [
"Use view_artifact to see full artifact content or apply filters (regex, json_path, field)",
"Task completed successfully. You can start a new conversation or view artifacts for details."
]
}
Example: Continue a conversation
send_message_to_agent(
agent_name="Twitter Agent",
message="Show only tweets from verified accounts",
context_id="ctx-xyz789"
)
2. view_artifact
View and filter artifacts with powerful filtering options.
Parameters:
agent_name(string, required): Agent that created the artifactcontext_id(string, required): Context ID from the conversationartifact_id(string, required): Artifact ID to viewfilter_type(string, optional): Filter type -"none","regex","json_path", or"field"filter_value(string, optional): Filter pattern or path
Example: View full artifact
view_artifact(
agent_name="Twitter Agent",
context_id="ctx-xyz789",
artifact_id="art-456"
)
Example: Extract usernames with regex
view_artifact(
agent_name="Twitter Agent",
context_id="ctx-xyz789",
artifact_id="art-456",
filter_type="regex",
filter_value="@\\w+"
)
Response:
{
"artifact_id": "art-456",
"filter_type": "regex",
"pattern": "@\\w+",
"matches": ["@techexpert", "@airesearcher", "@mlpractitioner"],
"match_count": 3,
"tips": [
"Regex patterns are applied to the entire artifact. Use capturing groups to extract specific parts."
]
}
Example: Extract specific field with JSON path
view_artifact(
agent_name="Twitter Agent",
context_id="ctx-xyz789",
artifact_id="art-456",
filter_type="json_path",
filter_value="tweets[0].author.name"
)
Response:
{
"artifact_id": "art-456",
"filter_type": "json_path",
"path": "tweets[0].author.name",
"results": ["Tech Expert"],
"result_count": 1,
"tips": [
"Try accessing nested fields with paths like 'data[0].field' or 'items[*].name'"
]
}
3. list_available_agents
List all available A2A agents with their capabilities.
Example:
list_available_agents()
Response:
{
"agents": [
{
"name": "Twitter Agent",
"description": "Find and analyze tweets by keyword, author, or URL",
"skills": ["Find Tweets", "Filter Table", "Generate Table"],
"url": "https://a2anet.com/agent/twitter/agent-card.json"
},
{
"name": "Analytics Agent",
"description": "Analyze data and generate insights from various sources",
"skills": ["Data Analysis", "Visualization", "Reporting"],
"url": "https://a2anet.com/agent/analytics/agent-card.json"
}
],
"count": 2,
"tips": [
"Use the agent name exactly as shown when calling send_message_to_agent",
"Check the skills list to understand what each agent can do"
]
}
๐งฉ Core Concepts
The A2A Protocol
The A2A Protocol is like HTTP for AI agents. Just as HTTP standardized web communication, A2A standardizes agent-to-agent communication with concepts like:
- Agent Card: Metadata about an agent (name, description, skills, endpoints)
- Context: A conversation thread with persistent message history
- Task: A unit of work with states (submitted, working, completed, failed, etc.)
- Message: A communication between user and agent with multiple parts
- Artifact: Structured outputs (documents, data, images) generated by agents
- Parts: Components of messages/artifacts (TextPart, DataPart, FilePart)
Architecture
โโโโโโโโโโโโโโโโโโโ
โ Claude Desktop โ
โ (MCP Client) โ
โโโโโโโโโโฌโโโโโโโโโ
โ MCP Protocol
โ
โโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโ
โ A2A MCP Server โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ AgentManager โ โ Fetches agent cards
โ โ - Parallel loading โ โ Creates A2A clients
โ โ - Name conflict res. โ โ Manages headers
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ConversationManager โ โ Tracks conversations
โ โ - Context tracking โ โ Stores artifacts
โ โ - Task state โ โ Message history
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Response Minimizer โ โ Minimizes large data
โ โ - List truncation โ โ Shows first/last
โ โ - Nested handling โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ArtifactFilter โ โ Regex filtering
โ โ - JSON path queries โ โ Field extraction
โ โ - Field extraction โ โ Pattern matching
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโ
โ A2A Protocol (HTTP/JSON)
โ
โ โโโโโโโโโโโโโโโโโโโ
โโโโโโโถ Twitter Agent โ
โ โโโโโโโโโโโโโโโโโโโ
โ โโโโโโโโโโโโโโโโโโโ
โโโโโโโถ Analytics Agent โ
โ โโโโโโโโโโโโโโโโโโโ
โ โโโโโโโโโโโโโโโโโโโ
โโโโโโโถ Your Agent โ
โโโโโโโโโโโโโโโโโโโ
Project Structure
a2a-mcp/
โโโ main.py # Entry point, initialization
โโโ src/
โ โโโ __init__.py # Package initialization
โ โโโ types.py # Data models (AgentInfo, ConversationState)
โ โโโ config.py # Configuration loading (env/file)
โ โโโ agent_manager.py # Agent card fetching & client management
โ โโโ conversation_manager.py # Conversation state tracking
โ โโโ response_minimizer.py # Large response minimization
โ โโโ artifact_filter.py # Artifact filtering (regex/json_path/field)
โ โโโ server.py # MCP server & tool handlers
โโโ pyproject.toml # Project config, dependencies
โโโ README.md # This file
Key Components
AgentManager
Manages the lifecycle of A2A agent connections:
- Fetches agent cards in parallel for fast startup
- Creates and configures A2A clients with custom headers
- Resolves name conflicts (e.g., "Twitter Agent" โ "Twitter Agent (2)")
- Provides agent discovery and lookup
ConversationManager
Tracks conversation state across multiple turns:
- Manages context IDs for conversation continuity
- Stores task IDs and task states
- Maintains message history
- Caches both full and minimized artifacts
Response Minimizer
Prevents context overflow by intelligently minimizing large responses:
- Lists with 3+ items show only first and last
- Nested structures are minimized recursively
- Preserves structure with
_type: "minimized_list" - Keeps originals available via
view_artifact
ArtifactFilter
Provides fast, efficient filtering without LLM involvement:
- Regex: Pattern matching across text and JSON
- JSON Path: Extract nested fields (e.g.,
users[0].profile.name) - Field: Get top-level fields only
- None: Return full artifact
๐ง Configuration
Environment Variables
# Required: JSON array of agent card configurations
export A2A_AGENT_CARDS='[
{
"url": "https://a2anet.com/agent/YOUR_AGENT_ID/agent-card.json",
"custom_headers": {
"X-API-Key": "your-key",
"Authorization": "Bearer token"
}
}
]'
# Optional: Global headers applied to all agents
export A2A_GLOBAL_HEADERS='{"User-Agent": "A2A-MCP-Server/1.0"}'
Configuration File (Alternative)
Create a config.json file:
{
"agent_cards": [
{
"url": "https://a2anet.com/agent/1/agent-card.json",
"custom_headers": {
"X-API-Key": "secret123"
}
}
],
"global_headers": {
"User-Agent": "A2A-MCP-Server/1.0"
}
}
Then modify main.py:
config = A2AMCPConfig.from_file("config.json")
๐ ๏ธ Development
Type Checking
uv run mypy src main.py
Linting and Formatting
# Check code quality
uv run ruff check .
# Auto-fix issues
uv run ruff check --fix .
# Format code
uv run ruff format .
Running Tests
# Coming soon
uv run pytest
๐ Troubleshooting
Server Not Starting
Problem: Server fails to start or shows configuration error
Solutions:
- Verify
A2A_AGENT_CARDSis valid JSON - Check that agent card URLs are accessible
- Ensure custom headers are properly formatted
- Review logs in stderr for detailed error messages
# Test your configuration
uv run python main.py 2>&1 | grep -i error
Agent Not Found
Problem: "Agent 'X' not found" when calling send_message_to_agent
Solutions:
- Use
list_available_agentsto see loaded agents - Check agent card URL in
A2A_AGENT_CARDS - Verify authentication headers if required
- Check stderr logs for agent fetch errors
# Check which agents loaded successfully
uv run python main.py 2>&1 | grep "Successfully initialized"
Name Conflicts
Problem: Multiple agents have the same name
Solution: The server automatically renames duplicates:
- First agent: "Twitter Agent"
- Second agent: "Twitter Agent (2)"
- Third agent: "Twitter Agent (3)"
Use the renamed version when calling tools.
Response Too Large
Problem: Agent returns huge datasets that overwhelm the LLM
Solution: The server automatically minimizes large responses. For lists with 3+ items, only first and last are shown. Use view_artifact with filters to extract specific data:
# Instead of viewing the full artifact
view_artifact(..., filter_type="json_path", filter_value="items[0].summary")
๐ Examples
Example 1: Multi-Turn Conversation
# Step 1: Send initial message
response = send_message_to_agent(
agent_name="Twitter Agent",
message="Find tweets about Python from today"
)
# Extract context_id from response
context_id = response["context_id"]
# Step 2: Continue conversation
response = send_message_to_agent(
agent_name="Twitter Agent",
message="Filter to show only tweets with more than 100 likes",
context_id=context_id
)
# Step 3: View specific artifact
view_artifact(
agent_name="Twitter Agent",
context_id=context_id,
artifact_id=response["artifacts"][0]["artifact_id"],
filter_type="json_path",
filter_value="tweets[*].text"
)
Example 2: Using Multiple Agents
# List available agents
agents = list_available_agents()
# Use different agents for different tasks
twitter_response = send_message_to_agent(
agent_name="Twitter Agent",
message="Find recent tweets about 'climate change'"
)
analytics_response = send_message_to_agent(
agent_name="Analytics Agent",
message="Analyze sentiment trends in climate discussions"
)
Example 3: Advanced Filtering
# Get artifact
response = send_message_to_agent(
agent_name="Data Agent",
message="Get user database"
)
artifact_id = response["artifacts"][0]["artifact_id"]
context_id = response["context_id"]
# Extract all email addresses with regex
emails = view_artifact(
agent_name="Data Agent",
context_id=context_id,
artifact_id=artifact_id,
filter_type="regex",
filter_value=r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"
)
# Extract nested user data with JSON path
user_names = view_artifact(
agent_name="Data Agent",
context_id=context_id,
artifact_id=artifact_id,
filter_type="json_path",
filter_value="users[*].profile.displayName"
)
๐บ๏ธ Roadmap
- Multi-agent support
- Conversation management
- Response minimization
- Artifact filtering (regex, JSON path, field)
- Structured JSON responses
- Tips and guidance in responses
- File part support (images, documents)
- Streaming responses
- Agent push notifications
- Built-in caching layer
- Retry logic with exponential backoff
- Agent health monitoring
- Conversation persistence (SQLite/PostgreSQL)
- WebSocket support
- CI/CD pipeline
- Comprehensive test suite
- Docker support
- Contributing guidelines
๐ License
Apache 2.0 - See LICENSE file for details
๐ค Join the A2A Net Community
A2A Net is a community for discovering and sharing AI agents built on open standards.
- ๐ Website: https://a2anet.com/
- ๐ค Discord: https://discord.gg/674NGXpAjU
- ๐ A2A Protocol Spec: https://a2a-protocol.org/latest/
- ๐ GitHub: https://github.com/A2ANet
Share your A2A agents, ask questions, stay up-to-date with the latest A2A news, and be the first to hear about releases, tutorials, and more!
๐ Acknowledgments
- Built with the A2A SDK
- Powered by the MCP Protocol
- Inspired by the vision of standardized agent communication
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file a2anet_mcp-0.1.2.tar.gz.
File metadata
- Download URL: a2anet_mcp-0.1.2.tar.gz
- Upload date:
- Size: 65.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: python-httpx/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb3971069dfff7e3aeac15b10cc214d803d3c2d9a909a7c2d68262f3b9970070
|
|
| MD5 |
d51d69f9e989652ef27f11fe72eee72b
|
|
| BLAKE2b-256 |
f08ffdaa289710fff6be16cbc6181665f3c537f093aec45c5d1b3a1ac332d0be
|
File details
Details for the file a2anet_mcp-0.1.2-py3-none-any.whl.
File metadata
- Download URL: a2anet_mcp-0.1.2-py3-none-any.whl
- Upload date:
- Size: 25.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: python-httpx/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df5213eb5ca4c79eeaffdebd22353e86d61d49b2ae0b85363db66a960065cb3c
|
|
| MD5 |
509b5b66e043861c7e83003e81fb2601
|
|
| BLAKE2b-256 |
ea79ef961e3c96eaf4873e7c63dbed4338ad0d516ea0b12cbfc7783ef46e6d94
|