A three-agent customer support system where independently-running agents communicate over Google's A2A (Agent-to-Agent) protocol — not in-process function calls — using Google ADK and an MCP-backed database layer.
User Query │ ▼ Host Agent (SequentialAgent, port 10022) │ ├─► Customer Data Agent (port 10020) ──► MCP Server (port 8080) ──► SQLite │ via RemoteA2aAgent (A2A / JSON-RPC) 15 tools, full access │ └─► Support Agent (port 10021) ──► MCP Server (filtered tool_filter) via RemoteA2aAgent (A2A / JSON-RPC) 10 tools, no admin ops
Each agent is its own running server. The Host Agent doesn't call the other two directly — it discovers and delegates to them via A2A's AgentCard protocol, fetched from each agent's .well-known/agent-card.json endpoint, then communicates over JSON-RPC.
- Customer Data Agent — system of record, full read/write access to customer and ticket data via all 15 MCP tools (lookup, create, update, disable/activate accounts, ticket ops, stats/search).
- Support Agent — customer-facing troubleshooting for login, payment, performance, and data-export issues, grounded in real account data. Deliberately restricted to a filtered 10-tool set that excludes every admin/destructive operation (
disable_customer,delete_ticket, etc.) — enforced at the process level, not just by convention, since it's a genuinely separate server with its own toolset. - Host Agent — a
SequentialAgentorchestrator that calls the Customer Data Agent first, then the Support Agent, so support guidance is grounded in the customer's actual account/ticket context rather than generic advice.
- Sequential over parallel by design, not default. The task has a real ordering dependency — support guidance is more useful once account context is available — so a fixed-order
SequentialAgentguarantees that data without custom coordination logic. - Tool-level privilege separation. Splitting the MCP tool_filter between the two data-facing agents means the Support Agent literally cannot call an admin tool — it's not running in a process that has access to it, rather than a filtered set of functions sharing memory with the admin-capable agent.
- Trade-off acknowledged: this buys process isolation and independent scalability at the cost of added latency and operational complexity (three servers, JSON-RPC serialization, network calls instead of function calls) versus a single in-process agent.
Google ADK · A2A Protocol · Model Context Protocol (MCP) · SQLite · Gemini · Python 3.12
conda create -n a2a-agents python=3.12 -y
conda activate a2a-agents
pip install -r requirements.txt
cp .env.example .env # add GOOGLE_API_KEY
# Set up the database
cd database && python database_setup.py && cd ..
# Start the MCP server
cd mcp_server && python app.py &
# Start all three agents (ports 10020, 10021, 10022)
python run_agents.py --mode startUCLA Extension — Agentic AI Course, Week 4