A2A Agents
Example agent implementations for the A2A Protocol with production-ready patterns and declarative configuration.
🚀 Quick Start (New Builder API)
Create a production-ready agent in just ~30 lines of code instead of ~300!
1. Define your agent (agent.toml)
[]
= "My Agent"
= "A helpful agent"
[[]]
= "my_skill"
= "My Skill"
= "What this skill does"
2. Implement your handler
use AsyncMessageHandler;
use async_trait;
;
3. Build and run!
use AgentBuilder;
use InMemoryTaskStorage;
async
That's it! The framework handles servers, agent cards, authentication, and more.
📚 See complete Builder API documentation →
Overview
This crate provides two approaches for building agents:
✨ New: Declarative Builder API (Recommended)
- 90% less boilerplate - ~30 lines vs ~300 lines
- TOML configuration - Define agents declaratively
- Environment-aware - Built-in env var interpolation
- Type-safe - Configuration validated at load time
- Production-ready - Batteries included
Examples:
examples/minimal_agent.rs- Echo agent (~50 lines)examples/reimbursement_builder.rs- Full-featured agent
Traditional Approach
The original hexagonal architecture approach with manual wiring:
- Hexagonal Architecture: Clean separation between domain logic and adapters
- Framework Integration: Uses
DefaultRequestProcessorand storage backends - Protocol Compliance: Full A2A protocol support with HTTP transport
- Modern Patterns: Async/await, builder patterns, and structured error handling
🔌 Model Context Protocol (MCP) Integration
You can expose any declarative A2A Agent as a Model Context Protocol (MCP) server over stdio transport. This allows MCP-compatible clients (like Claude Desktop) to invoke the agent's skills as local tools.
The bridge dispatches tool calls to the agent's message handler in-process, which means:
- No backing HTTP server is required (you can set
http_port = 0for a pure-stdio server). - Authentication checks are bypassed for local stdio calls (secure by design as it is run locally by the client), while HTTP endpoints can still use standard Bearer/OAuth2 token auth.
1. Enable the MCP Server in agent.toml
Add the [features.mcp_server] section to your config:
[]
= "My MCP Agent"
= "1.0.0"
[]
= "127.0.0.1"
= 0 # Can be 0 for pure-stdio mode
[]
= true
= true
= "Custom MCP Service Name" # Optional override
= "2.0.0" # Optional override
2. Run the MCP Agent
Compile and run your agent with the mcp-server Cargo feature enabled:
3. Claude Desktop Configuration
To connect Claude Desktop to your agent, add the following to your Claude Desktop configuration file (usually located at %APPDATA%\Claude\claude_desktop_config.json on Windows):
Architecture
ReimbursementMessageHandler
The core business logic implementing AsyncMessageHandler:
- Processes reimbursement requests using the A2A message format
- Generates interactive forms for expense submissions
- Validates and approves reimbursement requests
- Returns structured responses with proper task states
ModernReimbursementServer
The server implementation using framework components:
- Integrates with
DefaultBusinessHandlerfor request processing - Uses
InMemoryTaskStoragefor task persistence - Configures
SimpleAgentInfowith agent capabilities - Supports both HTTP transport
Usage
Quick Start - Unified Demo (Recommended)
Run the complete demo with both agent backend and web frontend in a single command:
# Run everything (agent backend + web UI)
# Open your browser to http://localhost:3000
This starts:
- Agent Backend on
http://localhost:8080(HTTP) - Web Frontend on
http://localhost:3000
The frontend automatically connects to the local agent and provides an interactive interface for submitting expenses and viewing tasks.
Advanced Usage
Run specific components:
# Run only the agent backend (HTTP)
# Run only the web frontend (point it to an existing agent)
AGENT_HTTP_URL=http://localhost:8080
# Customize ports
# Run only HTTP transport for agent
Available Endpoints
Agent Backend:
- HTTP API:
http://localhost:8080(ConnectRPC) - Agent Card:
http://localhost:8080/agent-card
Web Frontend:
- Main UI:
http://localhost:3000 - Task List:
http://localhost:3000/tasks - Expense Form:
http://localhost:3000/expense/new
Example Conversation
Here's an example conversation with the reimbursement agent:
-
User: "Can you reimburse me $50 for the team lunch yesterday?"
-
Agent: Returns a form
-
User: Submits the filled form
-
Agent: "Your reimbursement request has been approved. Request ID: request_id_1234567"
Current Limitations
This example implementation demonstrates the framework architecture but has simplified business logic:
- Message Processing: Basic pattern matching instead of LLM integration
- Storage: In-memory storage (framework supports SQLx for production)
- Authentication: Not implemented (framework supports Bearer/OAuth2)
- Form Processing: Simple JSON forms without complex validation
Future Enhancements
See TODO.md for the comprehensive modernization roadmap including:
- Phase 2: Production features (SQLx storage, authentication)
- Phase 3: AI/LLM integration for natural language processing
- Phase 4: Additional agent examples (document analysis, research assistant)
- Phase 5: Comprehensive testing and documentation
- Phase 6: Docker support and production deployment
Framework Features Demonstrated
- ✅ AsyncMessageHandler trait implementation
- ✅ DefaultBusinessHandler integration
- ✅ InMemoryTaskStorage for task persistence
- ✅ SimpleAgentInfo for agent metadata
- ✅ HTTP transport support
- ✅ Structured error handling with A2AError
- ✅ Modern async/await patterns
- ✅ Builder patterns for complex objects