1. 为什么我要把 MongoDB 查询封装成 MCP Server
MongoDB 是很多团队存业务数据的第一选择,但大模型默认碰不到它。你问模型「上个月订单量最高的十个城市是哪些」,它只能靠猜。MCP Server 就是解决这个断层的东西:它把数据库查询能力包装成模型能调用的工具,模型负责理解意图、拼参数,MCP Server 负责真正去 MongoDB 里取数。
这篇聚焦 Python + MongoDB + MCP Server 的本地落地,用 fastapi-mcp 把 MongoDB 查询封装成 MCP 工具,再接入 TaoToken 统一 Key/API 通道。适合已经会写 FastAPI、手里有 MongoDB 实例、想让模型直接查库的开发者。整套链路我按「先跑通再优化」的顺序写,你照着复制配置就能验证。
核心检索词先摆清楚:MCP Server 是模型上下文协议的服务端实现,fastapi-mcp 是能把现有 FastAPI 路由自动挂载成 MCP 工具的库,TaoToken 是统一管理模型 Key 和 API 通道的入口。三者组合起来,你不需要改数据库代码,只需要在现有 FastAPI 服务上加几行注册逻辑。
2. TaoToken 前置:Key、通道与 MCP 的关系
MCP Server 本身不负责调用大模型,它只负责暴露工具。真正让模型「用上」这些工具的,是客户端侧的模型通道。TaoToken 在这里的角色是统一 Key 和 API 通道:你不需要在多个模型供应商之间来回切换配置,一个 Key 就能覆盖对话、编码、Agent 等场景。
先拿到 API Key。访问 https://taotoken.net/api-keys 创建,复制保存。注意这个 Key 只在创建时完整显示一次,丢了就重新生成。
然后确认你的接入文档。不同客户端配置格式不一样,文档在 https://taotoken.net/doc 有完整说明。我建议先看文档再动手,避免配置项写错导致 401。
如果你后续要做长期编码或 Agent 任务,可以了解 Coding Plan:https://taotoken.net/coding-plan 。它适合需要持续调用、多轮工具编排的场景。单纯验证模型对话能力的话,用模型对话入口就够了:https://taotoken.net/models 。
这里有个关键认知:MCP Server 和 TaoToken 是两层。MCP Server 跑在本地,暴露工具;TaoToken 提供模型通道,让客户端能调用模型。两者通过客户端的 MCP 配置和模型配置分别对接。很多人第一次配的时候把这两层混在一起,结果工具注册了但模型调不到,或者模型能调但工具没挂上。
3. 可复制配置:config.toml 与 settings.json 骨架
先装依赖。Python 3.10 以上,建议用虚拟环境:
python -m venv venv source venv/bin/activate pip install fastapi uvicorn fastapi-mcp motor pymongomotor是 MongoDB 的异步驱动,fastapi-mcp负责把路由挂成 MCP 工具。装完后先写一个最小可跑的 FastAPI + MongoDB 查询服务:
# mongo_mcp_server.py from fastapi import FastAPI, Query from fastapi_mcp import add_mcp_server from motor.motor_asyncio import AsyncIOMotorClient from typing import Optional import uvicorn app = FastAPI(title="MongoDB MCP Server") client = AsyncIOMotorClient("mongodb://localhost:27017") db = client["shop"] orders = db["orders"] @app.get("/orders/top_cities", summary="按订单量统计城市排名") async def top_cities(limit: int = Query(10, description="返回条数")): pipeline = [ {"$group": {"_id": "$city", "count": {"$sum": 1}}}, {"$sort": {"count": -1}}, {"$limit": limit}, ] result = [] async for doc in orders.aggregate(pipeline): result.append({"city": doc["_id"], "count": doc["count"]}) return {"data": result} mcp_server = add_mcp_server( app, mount_path="/mcp", name="MongoDB MCP", description="MongoDB 查询工具集", base_url="http://localhost:8000", ) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000)启动命令:
python mongo_mcp_server.py服务起来后,MCP 端点挂在http://localhost:8000/mcp。接下来是客户端配置。以支持 MCP 的客户端为例,settings.json骨架如下:
{ "mcpServers": { "mongodb-local": { "url": "http://localhost:8000/mcp", "transport": "sse" } }, "model": { "provider": "taotoken", "apiKey": "你的_TAOTOKEN_KEY", "baseUrl": "https://taotoken.net/api" } }如果你用的客户端走 stdio 而不是 sse,把transport改成stdio,url换成启动命令。config.toml骨架(部分客户端用 TOML):
[mcp_servers.mongodb-local] url = "http://localhost:8000/mcp" transport = "sse" [model] provider = "taotoken" api_key = "你的_TAOTOKEN_KEY" base_url = "https://taotoken.net/api"注意:
base_url不要加 UTM 参数,API 调用只认纯域名。Key 不要提交到 Git,用环境变量或本地配置文件。
4. 验证请求:一次工具调用跑通查询链路
配置写完后,先别急着在客户端里点。用 curl 直接打 MCP 端点,确认工具注册成功:
curl -X POST http://localhost:8000/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'返回里应该能看到top_cities这个工具,带 description 和参数 schema。如果返回空列表,说明add_mcp_server没挂上,检查mount_path和路由装饰器。
然后验证实际查询。在客户端里发一句:「帮我查一下订单量最高的五个城市」。模型会先调top_cities,参数limit=5,MCP Server 执行聚合管道,返回结果。你看到的输出应该是类似:
{"data": [{"city": "上海", "count": 1280}, {"city": "北京", "count": 1150}]}这一步跑通,说明三层链路都通了:客户端 → TaoToken 模型通道 → MCP Server → MongoDB。如果模型没调工具而是直接编答案,检查客户端的 MCP 配置是否生效,以及模型是否支持工具调用。
我试过在同一个客户端里挂两个 MCP Server,一个查 MongoDB,一个查本地文件,模型会根据问题自动选工具。这说明 MCP 的工具体系是可组合的,你不需要把所有查询塞进一个服务。
5. 本篇常见错排查
报错一:ModuleNotFoundError: No module named 'fastapi_mcp'装包时虚拟环境没激活,或者 pip 装到了全局。确认which python指向 venv 里的解释器。
报错二:MCP 端点返回 404mount_path写成了/mcp/带斜杠,或者客户端请求路径不一致。统一用/mcp,不要带尾斜杠。
报错三:MongoDB 连接超时AsyncIOMotorClient的地址写错,或者 MongoDB 没启动。本地测试先用mongodb://localhost:27017,确认mongosh能连上再跑服务。
报错四:模型不调用工具客户端配置里 MCP Server 没启用,或者模型本身不支持 function calling。换一个支持工具调用的模型,或者在 TaoToken 的模型对话入口先验证模型能力。
报错五:401 UnauthorizedTaoToken Key 写错或过期。去 https://taotoken.net/api-keys 重新生成,注意不要有多余空格。
报错六:聚合查询返回空集合名或字段名写错。先在mongosh里手动跑一遍db.orders.aggregate([...]),确认管道正确再放进代码。
6. 接入文档与后续分流
排障和接入细节看文档:https://taotoken.net/doc 。API Key 管理在 https://taotoken.net/api-keys 。验证模型对话能力用 https://taotoken.net/models 。长期编码或 Agent 任务看 https://taotoken.net/coding-plan 。
整套跑下来,最耗时的不是写代码,而是配置对齐。MCP Server 的base_url、客户端的url、TaoToken 的base_url这三个地址容易混。记住:MCP 的base_url是你本地服务的地址,TaoToken 的base_url是模型通道的地址,两者不要写反。
最后留一个实用技巧:把 MongoDB 查询封装成 MCP 工具时,参数尽量用Query加 description,模型靠这个理解怎么传参。description 写得越清楚,模型调用越准。我见过有人把参数写成q不带说明,模型直接传了个自然语言句子进去,查询自然失败。