自述-MCP服务器(书籍+交换)
最小的MCP-样式API暴露:
- 静态
books由电子表格数据集(Excel/CSV)支持的资源 - 动态的
exchange由汇率表(Excel/CSV)支持的资源,具有反向和2跳推导功能 - 资源发现 通过
/resources
快速入门(本地)
# 1) Create & activate venv
python -m venv .venv
. .venv/bin/activate # Windows: .venv\Scripts\activate
# 2) Install deps
pip install -r requirements.txt
# 3) Run
uvicorn app.main:app --reload
# open http://127.0.0.1:8000/docs认证
这 /books 和 /exchange 端点受API密钥保护。对这些端点的请求必须在 X-API-Key 头球
示例使用 curl:
curl -X 'GET' \
'http://127.0.0.1:8000/books' \
-H 'accept: application/json' \
-H 'X-API-Key: your-secret-key'如果密钥丢失或无效,API将返回 401 Unauthorized 错误。
配置
路径和API密钥可以通过环境变量(pydantic-settings)更改:
BOOKS_PATH(默认值:data/BooksDatasetClean.xlsx)RATES_PATH(默认值:data/exchange_rates_dataset.xlsx)API_KEY(默认值:default-secret-key)
示例(Linux/macOS):
BOOKS_PATH=data/books.csv \
RATES_PATH=data/rates.csv \
API_KEY="your-secret-key" \
uvicorn app.main:app --reload示例(Windows命令提示符):
set BOOKS_PATH=data/books.csv
set RATES_PATH=data/rates.csv
set API_KEY="your-secret-key"
uvicorn app.main:app --reload码头工人
docker build -t mcp-server .
docker run --rm -p 8000:8000 \
-e BOOKS_PATH="data/BooksDatasetClean.xlsx" \
-e RATES_PATH="data/exchange_rates_dataset.xlsx" \
-e API_KEY="your-secret-key" \
mcp-server资源发现
GET /resources
{
"resources": [
{"name":"books","type":"static","endpoints":["/books","/books/{id}"]},
{"name":"exchange","type":"dynamic","endpoints":["/exchange"]}
]
}书籍API
列表和筛选器
GET /books?author=&genre=&year=&title_contains=&limit=&offset=
{
"total": 1234,
"limit": 50,
"offset": 0,
"items": [
{"id":"1","title":"...","author":"...","year":1993,"genre":"History"}
]
}按ID获取
GET /books/{id}
{"id":"1","title":"...","author":"...","year":1993,"genre":"History"}列映射:
Title→titleAuthors→author(以“By”开头的条带)Category→genre(逗号前的第一个标记)Publish Date (Year)→yearID→ 如果不存在,则合成增量id
Exchange API
GET /exchange?from=USD&to=EUR&amount=100
{"from_currency":"USD","to_currency":"EUR","rate":0.92,"amount":100.0,"converted":92.0}错误示例:
- 400:
{"detail":"Unsupported currency: XXX"} - 400:
{"detail":"No rate path from XXX to YYY"} - 422查询参数缺失/无效
设计选择
- 服务边界:路由器很薄;数据逻辑存在
services/. - ID合成:数据集没有稳定的id→ 我们生成确定性
1..N负载。 - 类型规范化:逗号前的第一个标记使其保持粗糙和可过滤。
- 交换图:加载定向边,添加反向+身份,允许通过公共枢轴进行简单的2跳。
- 可扩展性:使用相同的服务接口将Excel/CSV转换为DB。
______________________________________________________________________
测试(pytest)
测试的结构
- 测试生成 微小温度CSV 在运行时,它们不依赖于大型Excel文件。
conftest.py设置环境变量 之前 导入应用程序,以便启动时加载临时文件。- 我们涵盖:发现、图书列表/过滤/获取/404、交换成功/身份/无效。
运行测试
pip install -r requirements.txt
pip install pytest httpx anyio
pytest -q______________________________________________________________________
提交清单
- \[x\] 两种资源(静态书籍、动态交换)
- \[x\] 资源发现
/resources - \[x\] 列表、按id获取、过滤器(作者/流派/年份)、部分标题、分页
- \[x\] 输入验证交换,反向+身份+2跳
- \[x\] 错误处理:400/404/422
- \[x\] 模块化代码+Dockerfile
- \[x\] 自述文件 (此文件)
- \[x\] 测试 (pytest套件)
