Overview
Core Components
A2AService
Location:src/a2a_handler/service.py
The A2AService class is the heart of Handler’s architecture. It provides a unified interface for all A2A protocol operations, wrapping the official a2a-sdk with a simplified API designed for Handler’s use cases.
Key responsibilities:
- Wraps the a2a-sdk
Clientwith a simplified interface - Manages agent card fetching and caching
- Handles authentication credential application
- Provides both streaming and non-streaming message sending
- Manages task operations (get, cancel, resubscribe)
- Configures push notification support
- Extracts text content from various response types
SendResult- Wraps task/message responses with helper propertiesStreamEvent- Wraps streaming events (status, artifact, message)TaskResult- Wraps task state and details
is_complete, needs_input, and needs_auth.
TUI Application
Location:src/a2a_handler/tui/
The Terminal User Interface is built with Textual, providing a rich interactive experience for agent communication.
Architecture:
- Component-based architecture with custom Textual widgets
- Real-time streaming response display
- Session persistence across restarts
- Theme support (light/dark)
- Command palette integration
- Maximizable panels for focused viewing
A2AService instance per connected agent, reusing it for all operations in that session.
CLI Interface
Location:src/a2a_handler/cli/
The command-line interface uses rich-click for beautiful, readable output.
Command structure:
- Each command group is a separate module
- Commands create their own
A2AServiceinstances - Short-lived operations (no persistent state)
- Supports both JSON and formatted output
- Session integration for context continuity
MCP Server
Location:src/a2a_handler/mcp/server.py
The Model Context Protocol server exposes Handler’s A2A capabilities as tools that can be used by AI assistants like Claude Desktop.
Architecture:
- Built with FastMCP
- Exposes 15+ tools for complete A2A protocol coverage
- Integrates with Handler’s session management
- Supports both stdio and SSE transports
- Agent Discovery -
validate_agent_card,get_agent_card - Messaging -
send_message - Task Management -
get_task,cancel_task - Push Notifications -
set_task_notification,get_task_notification - Session Management -
list_sessions,get_session_info,clear_session_data - Authentication -
set_agent_credentials,clear_agent_credentials
A2AService instance with the specified configuration. This ensures clean state isolation between operations.
Local Server Agent
Location:src/a2a_handler/server/
Handler includes a reference implementation of an A2A server agent for testing and development.
Components:
1. Agent (agent.py)
- Built with Google Agent Development Kit (ADK)
- Uses LiteLLM for model abstraction
- Defaults to Ollama for local inference
- Configurable via environment variables
2. Application (app.py)
- Built with Starlette ASGI framework
- Custom A2A implementation with full push notification support
- API key authentication middleware
- Integrates Google ADK with a2a-sdk
create_a2a_application function is a custom implementation that fixes push notification support. Google ADK’s built-in to_a2a() function doesn’t properly wire up push notification stores, causing operations to fail. Handler’s implementation manually constructs the request handler with all required stores.
3. Agent Card (card.py)
- Generates dynamic agent cards based on configuration
- Supports streaming and push notifications
- Declares skills and capabilities
Session Management
Location:src/a2a_handler/session.py
Sessions persist state between Handler invocations:
context_id- For conversation continuitytask_id- For task operationscredentials- For authenticated agents
- Persisted to
~/.handler/sessions.json - JSON-serialized with Pydantic models
- Thread-safe with file locking
agent_url, allowing multiple concurrent conversations with different agents.
Authentication
Location:src/a2a_handler/auth.py
Supports multiple authentication schemes:
- Bearer tokens (
Authorization: Bearer <token>) - API keys (
X-API-Key: <key>orAuthorization: ApiKey <key>)
A2AService:
Push Notifications
Location:src/a2a_handler/webhook.py
Handler can receive async task updates via webhooks:
Server:
- Built with Starlette
- Validates authentication tokens
- Logs received notifications
- Can be extended with custom handlers
A2AService can configure push notifications when creating a client:
Validation
Location:src/a2a_handler/validation.py
Agent card validation with detailed error reporting:
- Schema validation against A2A protocol spec
- Field-level error messages
- Support for both URL and file-based validation
Design Principles
1. Service Layer Abstraction
All interfaces (TUI, CLI, MCP) use the sameA2AService layer. This ensures:
- Consistent behavior across interfaces
- Single source of truth for protocol logic
- Easy testing and maintenance
- No code duplication
2. Lazy Initialization
A2AService uses lazy initialization for expensive operations:
- Agent cards are fetched once and cached
- SDK clients are created on first use
- HTTP clients are reused within a session
3. Type Safety
Full type hints throughout the codebase:- Python 3.11+ with modern type syntax
- Pydantic models for data validation
- a2a-sdk types exposed through wrappers
- Type checking with
ty check
4. Async-First
All I/O operations are async:httpx.AsyncClientfor HTTP- Async iterators for streaming
asynciofor concurrency- Textual’s async workers for TUI
5. Error Handling
Graceful degradation and clear error messages:- Exceptions bubble up with context
- Logging at appropriate levels
- User-friendly error display in TUI
- JSON error responses in CLI
Extension Points
Adding New CLI Commands
- Create a new module in
cli/ - Define commands with rich-click
- Use
A2AServicefor protocol operations - Add to main CLI group in
cli/__init__.py
Adding New TUI Components
- Create a new widget in
tui/components/ - Inherit from Textual base classes
- Add styling to
app.tcss - Compose into main app
Adding New MCP Tools
- Add a new
@mcp.tool()decorated function - Use
A2AServicefor A2A operations - Return JSON-serializable results
- Document in tool docstring
Customizing the Server Agent
- Modify
create_llm_agent()inserver/agent.py - Update agent card in
server/card.py - Add custom tools or skills
- Configure via environment variables
Testing Architecture
Location:tests/
- Unit tests with pytest
- Async tests with pytest-asyncio
- Mock HTTP responses for deterministic tests
- Integration tests against local server
Dependencies
Core:a2a-sdk- Official A2A protocol implementationhttpx- Async HTTP clientpydantic- Data validation and serialization
textual- Terminal UI frameworktextual-serve- Web serving support
rich-click- Rich CLI frameworkrich- Terminal formatting
starlette- ASGI web frameworkuvicorn- ASGI servergoogle-adk- Google Agent Development Kitlitellm- LLM provider abstraction
mcp- Model Context Protocol SDKfastmcp- FastMCP framework
Configuration
Location:src/a2a_handler/common/config.py
User configuration directory:
- Linux/macOS:
~/.handler/ - Stores: sessions, themes, logs
OLLAMA_MODEL- Default Ollama modelOLLAMA_API_BASE- Ollama API endpoint- Other LiteLLM provider configuration
Logging
Location:src/a2a_handler/common/logging.py
Levels:
ERROR(default) - Errors onlyINFO- Key operationsDEBUG- Detailed protocol traces
- CLI: stderr with rich formatting
- TUI: In-app log panel
- MCP: stdio (JSON-RPC compatible)
Next Steps
- Contributing Guide - How to contribute to Handler
- API Reference - Detailed API documentation
- Examples - Code examples and recipes