Model or dataset
phoenix-zhou/multi-agent avatar
phoenix-zhou/multi-agent

phoenix-zhou/multi-agent: an A2A and MCP travel assistant you run yourself

A multi-agent travel assistant system built using the **Agent2Agent (A2A)** protocol and **MCP (Model Context Protocol)**

310 stars8 forksPythonLicense varies

At a glance

What is it?
A Python multi-agent travel assistant that routes weather, ticket and booking requests through A2A agents backed by MCP tool servers and a MySQL database. The architecture is the point; the setup cost is the price.
Who is it for?
Adopt it if you want a runnable reference for A2A agent-to-agent calls and MCP tool servers rather than a product to deploy. Skip it if you need a single-process assistant or cannot run MySQL.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 37 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 17, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What phoenix-zhou/multi-agent actually solves

Most travel-assistant demos are one script with one prompt. This repository splits the job into layers that talk over two protocols. The orchestrator identifies intent and rewrites the query. A2A agents own domain skills. MCP servers own database access. If you are learning how A2A agent cards and MCP tool servers fit together in a working Python codebase, that separation is the value here, not the travel domain itself.

The README describes the target user indirectly: someone with a MySQL instance, an OpenAI-compatible LLM endpoint and the patience to start six services. The README is written in Chinese, with a README_EN.md also present at the repository root. There is no packaged release and no homepage, so the expected workflow is cloning the repository and running it from source.

How the A2A and MCP layers divide the work

The README's architecture diagram shows three tiers. The orchestrator (app.py for Streamlit, main.py for CLI) does intent recognition, query rewriting and final summarization with an LLM. Below it sit three A2A agents: WeatherQueryAssistant on port 5005, TicketQueryAssistant on port 5006 and TicketOrderAssistant on port 5007. Below those sit three MCP servers: WeatherTools on port 8002, TicketTools on port 8001 and OrderTools on port 8003. All three MCP servers read from a MySQL database named travel_rag with tables weather_data, train_tickets, flight_tickets and concert_tickets.

The processing flow in the README is explicit. User input goes to intent recognition, which maps to one of weather, flight, train, concert, order, attraction or out_of_scope. Attraction requests skip the agents entirely and go straight to LLM generation. Everything else routes to an A2A agent that generates SQL with the database schema supplied as prompt context, calls an MCP tool, and returns results that the orchestrator summarizes.

Two design choices stand out. First, query rewriting happens in the orchestrator, so downstream agents receive self-contained sentences and never see conversation history. Second, the booking agent calls the ticket query agent before invoking the order tool. The README describes this as checking remaining seats first, then passing that information into the MCP order tool. That is genuine agent-to-agent cooperation rather than three independent services behind one router.

The weak point is SQL generation by an LLM against a live database. The README says agents return input_required when information is missing and refuse unrelated questions, but it does not describe any validation of the generated SQL beyond that. Treat the schema-as-prompt approach as a demo pattern, not a hardened query layer.

Installing phoenix-zhou/multi-agent and asking it one question

The README targets Python 3.9 or later and lists two pip commands. Run them from the repository root.

bash
# Python 3.9+
pip install streamlit langchain langchain-openai python-a2a mcp
pip install langchain-mcp-adapters mysql-connector-python requests schedule pytz

Next, create the database and load the sample ticket data. The README runs the first script through the mysql client and pipes the second into the travel_rag database.

bash
# 执行建库建表脚本
mysql -u root -p < sql/sql_data.sql

# 导入票务示例数据
mysql -u root -p travel_rag < sql/insert2.sql

The README notes that importing real weather rows means running `python utils/spider_weather.py` with a QWeather API key configured. Before starting anything, edit config.py with your LLM and database details. The README shows the LLM block with a SiliconFlow base URL and a Qwen model name, and a MySQL block with host, user, password and database.

python
# 大模型配置
self.base_url = 'https://api.siliconflow.cn/v1'
self.api_key = 'sk-xxx'               # 替换为你的 API Key
self.model_name = 'Qwen/Qwen2.5-72B-Instruct'

# 数据库配置
self.host = 'localhost'
self.user = 'root'
self.password = '123456'
self.database = 'travel_rag'

Start the services in the README's order: the three MCP servers first, then the three A2A agents, then one orchestrator. The Streamlit front end runs on its default port 8501; the CLI version takes over your terminal instead. In the CLI, the README says typing `cards` prints every agent's card, including skills, description and address, and `quit` exits.

bash
# ① 启动 MCP Server(数据层)
python mcp_server/mcp_weather_server.py   # 端口 8002
python mcp_server/mcp_ticket_server.py    # 端口 8001
python mcp_server/mcp_order_server.py     # 端口 8003

# ② 启动 A2A Agent(智能体层)
python a2a_server/weather_server.py       # 端口 5005
python a2a_server/ticket_server.py        # 端口 5006
python a2a_server/order_server.py         # 端口 5007

# ③ 启动总控中心(二选一)
python main.py                            # CLI 交互版
streamlit run app.py                      # Web 聊天版

Once running, the README's example utterances include a weather question, a train ticket lookup and a booking request, plus a combined multi-intent line such as asking about tomorrow's weather while also checking flights to Guangzhou.

Where the design breaks down

The most visible constraint is operational: six services plus a database. The README gives a strict start order, MCP servers first, then A2A agents, then the orchestrator, and every service is a separate Python process with a hard-coded port. There is no process manager, no Dockerfile and no docker-compose file in the repository layout. Restarting the stack means running the commands again by hand.

Configuration is another friction point. The README's config.py example contains a placeholder API key and a literal database password of 123456. That is illustrative, but it means credentials sit in a Python file rather than environment variables. The README does not document an environment-variable path.

The third limitation is data freshness. Weather answers depend on the weather_data table, which the README says is populated by utils/spider_weather.py using the QWeather API, described as a 30-day forecast source. Ticket and concert data come from the sample SQL files. Nothing in the README describes a scheduled refresh for ticket inventory, so the booking agent can only confirm seats that exist in your local tables.

Finally, the licence is unknown. The repository metadata does not carry one, and the README does not mention it. For anything beyond local experimentation, that is a blocker to resolve before you build on the code.

When a single agent or a workflow engine is the better fit

LangGraph is the natural comparison, and the related searches around multi-agent orchestration point at it. The difference is where coordination lives. LangGraph keeps agents inside one process as graph nodes with shared state, so a run is a single Python program and debugging means reading one trace. This repository puts coordination on the network: agent cards, HTTP calls between ports, MCP tool invocations. You gain independent deployability and a protocol boundary you can swap implementations across. You lose the ability to step through a request in one debugger session.

If your assistant answers weather questions and nothing else, this is the wrong tool. A single script calling one weather API needs none of the six services. The A2A layer earns its place when different teams or runtimes own different skills, or when you specifically want to learn the protocol. The README's own attraction flow concedes the point: attraction recommendations bypass agents and MCP entirely and go straight to the LLM.

Maintenance status and what upgrades cost

The repository is not archived. Its last push was on 2026-08-11, roughly five weeks before this writing, so the code is recent. There are no tagged releases, which means there is no upgrade path to follow: you track the main branch, and any change to a port, a prompt template in main_prompts.py or an MCP tool signature arrives without a version number to pin against.

Upgrade cost concentrates in three files. config.py holds the LLM endpoint, key, model name and MySQL credentials. main_prompts.py holds the intent taxonomy, so adding a new intent means editing the prompt and the routing map together. The A2A and MCP servers each pin their own port in code, so moving a service means editing the server file and every caller that references it.

On licensing: the repository carries no licence identifier and the README is silent on the subject. Absent an explicit licence, the default position is that no rights are granted beyond what the hosting platform's terms allow. That is a question for whoever owns the code, not something to infer.

Editorial conclusion

Adopt it if you want a runnable reference for A2A agent-to-agent calls and MCP tool servers rather than a product to deploy. Skip it if you need a single-process assistant or cannot run MySQL. Before committing, read config.py to see which credentials it expects, and check the repository for a licence file, because the README does not state one.

Frequently asked questions

What is meant by multi-agent in phoenix-zhou/multi-agent?

It means several independent agent processes that communicate over the A2A protocol rather than one program with multiple prompts. The repository runs three A2A agents (weather, ticket query, ticket order) plus three MCP tool servers, coordinated by an orchestrator that performs intent recognition.

How do I set up phoenix-zhou/multi-agent?

Install the pip packages listed in the README, load sql/sql_data.sql and sql/insert2.sql into MySQL, edit config.py with your LLM and database credentials, then start the three MCP servers, the three A2A agents and finally main.py or app.py.

Is a single agent or a multi-agent setup the right choice here?

The README's own flow shows attraction recommendations going straight from the orchestrator LLM to the user, skipping agents and MCP. The multi-agent structure is used for weather, ticket and booking requests where SQL generation and database access are involved.

How do I use the multi-agent setup in phoenix-zhou/multi-agent?

Start the services in the README's order, then type requests such as a weather question or a train ticket query. In the CLI version, typing cards shows each agent's card with its skills and address, and quit exits.

Official sources

  1. Issues
  2. phoenix-zhou/multi-agent on GitHub
  3. README
Community notes

Community notes