mcp-multi-tool-lab
README.md
# mcp-multi-tool-lab
一個輕量的多 provider MCP 測試資料/fixture:單一process掛載兩個 provider(`eva_air` 航空、`uk_railway` 鐵路),每個 provider 各暴露 5 個 MCP tool,資料全為記憶體內的假資料。設計目的是提供一個「MCP 後面有多個 tool」的可重複部署測試環境,方便驗證 MCP client 的 tool discovery、tool call 與多 provider 路由。
不含真實業務邏輯、資料庫或任何內部/機敏資料。
## 結構
```
agent.py # OpenAI Agents SDK 層:把兩個 provider 接成 Agent 的 mcp_servers
mcp_multi_tool_lab/
server.py # 用 Starlette 把兩個 provider 掛在 /<slug>/mcp 底下
providers/
eva_air.py # 航空 provider:5 個 tool + 記憶體假資料
uk_railway.py # 鐵路 provider:5 個 tool + 記憶體假資料
```
## Provider 與 Tool 清單
| Provider slug | MCP URL | Tools |
|---|---|---|
| `eva_air` | `http://localhost:8000/eva_air/mcp` | `eva_air_search_flights`、`eva_air_create_provisional_booking`、`eva_air_pay_booking`、`eva_air_list_my_bookings`、`eva_air_dry_run_cancel` |
| `uk_railway` | `http://localhost:8000/uk_railway/mcp` | `uk_railway_search_trains`、`uk_railway_create_provisional_booking`、`uk_railway_pay_booking`、`uk_railway_list_my_bookings`、`uk_railway_dry_run_cancel` |
## 安裝與啟動
```bash
poetry install
poetry run python -m mcp_multi_tool_lab.server
```
伺服器預設監聽 `http://localhost:8000`。
## 連線方式
### 用 MCP client 連(建議)
```python
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async with streamablehttp_client("http://localhost:8000/eva_air/mcp") as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
print([t.name for t in tools.tools])
```
### 用 curl 連(了解底層原理)
```bash
curl -N http://localhost:8000/eva_air/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
```
## 快速試用範例
1. `eva_air_search_flights(origin="TPE", destination="NRT", date="2026-08-10")`
2. `eva_air_create_provisional_booking(flight_id="BR001", passenger_name="Alice")`
3. `eva_air_pay_booking(booking_id="EVA-0001")`
4. `eva_air_dry_run_cancel(booking_id="EVA-0001")`
`uk_railway` 系列 tool 用法相同,把 flight 換成 train 即可。
## OpenAI Agents SDK 層
`agent.py` 用 [`openai-agents`](https://github.com/openai/openai-agents-python) SDK 把兩個 provider 各接成一個 `Agent`:
| Agent | MCP server | Tools |
|---|---|---|
| `AirlineAgent` | `eva_air`(`agents.mcp.MCPServerStreamableHttp` 指向 `/eva_air/mcp`) | `format_itinerary` + eva_air 的 5 個 MCP tool |
| `RailwayAgent` | `uk_railway`(指向 `/uk_railway/mcp`) | `format_itinerary` + uk_railway 的 5 個 MCP tool |
跑之前記得先啟動 `mcp_multi_tool_lab.server`(見上方「安裝與啟動」),`agent.py` 才能連得到這兩個 MCP server。
## 注意事項
- 所有資料都是進程內記憶體儲存,重啟伺服器即清空,不適合當持久化測試。
- 這是獨立、通用的測試資料專案,跟任何內部產品或公司內部 repo 沒有從屬關係。
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues