Skip to content
 
 

Repository files navigation

A2A Multi-Agent Customer Support System

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.

Architecture

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.

What each agent does

  • 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 SequentialAgent orchestrator 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.

Design decisions

  • 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 SequentialAgent guarantees 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.

Tech stack

Google ADK · A2A Protocol · Model Context Protocol (MCP) · SQLite · Gemini · Python 3.12

Running it

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 start

UCLA Extension — Agentic AI Course, Week 4

About

Three-agent customer support system communicating over Google's A2A protocol — Google ADK, MCP-backed data layer, agent-level tool privilege isolation

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages