|
| 1 | +<p align="center"><a href="https://github.com/tadata-org/fastapi_mcp"><img src="https://github.com/user-attachments/assets/609d5b8b-37a1-42c4-87e2-f045b60026b1" alt="fastapi-to-mcp" height="100"/></a></p> |
| 2 | +<h1 align="center">FastAPI-MCP</h1> |
| 3 | +<p align="center">一个零配置工具,用于自动将 FastAPI 端点公开为模型上下文协议(MCP)工具。</p> |
| 4 | +<div align="center"> |
| 5 | + |
| 6 | +[](https://pypi.org/project/fastapi-mcp/) |
| 7 | +[](https://pypi.org/project/fastapi-mcp/) |
| 8 | +[](#) |
| 9 | + |
| 10 | +[](https://github.com/tadata-org/fastapi_mcp/actions/workflows/ci.yml) |
| 11 | +[](https://codecov.io/gh/tadata-org/fastapi_mcp) |
| 12 | + |
| 13 | +</div> |
| 14 | + |
| 15 | +<p align="center"><a href="https://github.com/tadata-org/fastapi_mcp"><img src="https://github.com/user-attachments/assets/1cba1bf2-2fa4-46c7-93ac-1e9bb1a95257" alt="fastapi-mcp-usage" height="400"/></a></p> |
| 16 | + |
| 17 | +## 特点 |
| 18 | + |
| 19 | +- **直接集成** - 直接将 MCP 服务器挂载到您的 FastAPI 应用 |
| 20 | +- **零配置** - 只需指向您的 FastAPI 应用即可工作 |
| 21 | +- **自动发现** - 所有 FastAPI 端点并转换为 MCP 工具 |
| 22 | +- **保留模式** - 保留您的请求模型和响应模型的模式 |
| 23 | +- **保留文档** - 保留所有端点的文档,就像在 Swagger 中一样 |
| 24 | +- **灵活部署** - 将 MCP 服务器挂载到同一应用,或单独部署 |
| 25 | + |
| 26 | +## 安装 |
| 27 | + |
| 28 | +我们推荐使用 [uv](https://docs.astral.sh/uv/),一个快速的 Python 包安装器: |
| 29 | + |
| 30 | +```bash |
| 31 | +uv add fastapi-mcp |
| 32 | +``` |
| 33 | + |
| 34 | +或者,您可以使用 pip 安装: |
| 35 | + |
| 36 | +```bash |
| 37 | +pip install fastapi-mcp |
| 38 | +``` |
| 39 | + |
| 40 | +## 基本用法 |
| 41 | + |
| 42 | +使用 FastAPI-MCP 的最简单方法是直接将 MCP 服务器添加到您的 FastAPI 应用中: |
| 43 | + |
| 44 | +```python |
| 45 | +from fastapi import FastAPI |
| 46 | +from fastapi_mcp import FastApiMCP |
| 47 | + |
| 48 | +app = FastAPI() |
| 49 | + |
| 50 | +mcp = FastApiMCP( |
| 51 | + app, |
| 52 | + |
| 53 | + # 可选参数 |
| 54 | + name="我的 API MCP", |
| 55 | + description="我的 API 描述", |
| 56 | + base_url="http://localhost:8000", |
| 57 | +) |
| 58 | + |
| 59 | +# 直接将 MCP 服务器挂载到您的 FastAPI 应用 |
| 60 | +mcp.mount() |
| 61 | +``` |
| 62 | + |
| 63 | +就是这样!您的自动生成的 MCP 服务器现在可以在 `https://app.base.url/mcp` 访问。 |
| 64 | + |
| 65 | +> **关于`base_url`的注意事项**:虽然`base_url`是可选的,但强烈建议您明确提供它。`base_url` 告诉 MCP 服务器在调用工具时向何处发送 API 请求。如果不提供,库将尝试自动确定 URL,这在部署环境中内部和外部 URL 不同时可能无法正确工作。 |
| 66 | +
|
| 67 | +## 工具命名 |
| 68 | + |
| 69 | +FastAPI-MCP 使用 FastAPI 路由中的`operation_id`作为 MCP 工具的名称。如果您不指定`operation_id`,FastAPI 会自动生成一个,但这些名称可能比较晦涩。 |
| 70 | + |
| 71 | +比较以下两个端点定义: |
| 72 | + |
| 73 | +```python |
| 74 | +# 自动生成的 operation_id(类似于 "read_user_users__user_id__get") |
| 75 | +@app.get("/users/{user_id}") |
| 76 | +async def read_user(user_id: int): |
| 77 | + return {"user_id": user_id} |
| 78 | + |
| 79 | +# 显式 operation_id(工具将被命名为 "get_user_info") |
| 80 | +@app.get("/users/{user_id}", operation_id="get_user_info") |
| 81 | +async def read_user(user_id: int): |
| 82 | + return {"user_id": user_id} |
| 83 | +``` |
| 84 | + |
| 85 | +为了获得更清晰、更直观的工具名称,我们建议在 FastAPI 路由定义中添加显式的`operation_id`参数。 |
| 86 | + |
| 87 | +要了解更多信息,请阅读 FastAPI 官方文档中关于 [路径操作的高级配置](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/) 的部分。 |
| 88 | + |
| 89 | +## 高级用法 |
| 90 | + |
| 91 | +FastAPI-MCP 提供了多种方式来自定义和控制 MCP 服务器的创建和配置。以下是一些高级用法模式: |
| 92 | + |
| 93 | +### 自定义模式描述 |
| 94 | + |
| 95 | +```python |
| 96 | +from fastapi import FastAPI |
| 97 | +from fastapi_mcp import FastApiMCP |
| 98 | + |
| 99 | +app = FastAPI() |
| 100 | + |
| 101 | +mcp = FastApiMCP( |
| 102 | + app, |
| 103 | + name="我的 API MCP", |
| 104 | + base_url="http://localhost:8000", |
| 105 | + describe_all_responses=True, # 在工具描述中包含所有可能的响应模式 |
| 106 | + describe_full_response_schema=True # 在工具描述中包含完整的 JSON 模式 |
| 107 | +) |
| 108 | + |
| 109 | +mcp.mount() |
| 110 | +``` |
| 111 | + |
| 112 | +### 自定义公开的端点 |
| 113 | + |
| 114 | +您可以使用 Open API 操作 ID 或标签来控制哪些 FastAPI 端点暴露为 MCP 工具: |
| 115 | + |
| 116 | +```python |
| 117 | +from fastapi import FastAPI |
| 118 | +from fastapi_mcp import FastApiMCP |
| 119 | + |
| 120 | +app = FastAPI() |
| 121 | + |
| 122 | +# 仅包含特定操作 |
| 123 | +mcp = FastApiMCP( |
| 124 | + app, |
| 125 | + include_operations=["get_user", "create_user"] |
| 126 | +) |
| 127 | + |
| 128 | +# 排除特定操作 |
| 129 | +mcp = FastApiMCP( |
| 130 | + app, |
| 131 | + exclude_operations=["delete_user"] |
| 132 | +) |
| 133 | + |
| 134 | +# 仅包含具有特定标签的操作 |
| 135 | +mcp = FastApiMCP( |
| 136 | + app, |
| 137 | + include_tags=["users", "public"] |
| 138 | +) |
| 139 | + |
| 140 | +# 排除具有特定标签的操作 |
| 141 | +mcp = FastApiMCP( |
| 142 | + app, |
| 143 | + exclude_tags=["admin", "internal"] |
| 144 | +) |
| 145 | + |
| 146 | +# 结合操作 ID 和标签(包含模式) |
| 147 | +mcp = FastApiMCP( |
| 148 | + app, |
| 149 | + include_operations=["user_login"], |
| 150 | + include_tags=["public"] |
| 151 | +) |
| 152 | + |
| 153 | +mcp.mount() |
| 154 | +``` |
| 155 | + |
| 156 | +关于过滤的注意事项: |
| 157 | +- 您不能同时使用`include_operations`和`exclude_operations` |
| 158 | +- 您不能同时使用`include_tags`和`exclude_tags` |
| 159 | +- 您可以将操作过滤与标签过滤结合使用(例如,使用`include_operations`和`include_tags`) |
| 160 | +- 当结合过滤器时,将采取贪婪方法。匹配任一标准的端点都将被包含 |
| 161 | + |
| 162 | +### 与原始 FastAPI 应用分开部署 |
| 163 | + |
| 164 | +您不限于在创建 MCP 的同一个 FastAPI 应用上提供 MCP 服务。 |
| 165 | + |
| 166 | +您可以从一个 FastAPI 应用创建 MCP 服务器,并将其挂载到另一个应用上: |
| 167 | + |
| 168 | +```python |
| 169 | +from fastapi import FastAPI |
| 170 | +from fastapi_mcp import FastApiMCP |
| 171 | + |
| 172 | +# 您的 API 应用 |
| 173 | +api_app = FastAPI() |
| 174 | +# ... 在 api_app 上定义您的 API 端点 ... |
| 175 | + |
| 176 | +# 一个单独的 MCP 服务器应用 |
| 177 | +mcp_app = FastAPI() |
| 178 | + |
| 179 | +# 从 API 应用创建 MCP 服务器 |
| 180 | +mcp = FastApiMCP( |
| 181 | + api_app, |
| 182 | + base_url="http://api-host:8001", # API 应用将运行的 URL |
| 183 | +) |
| 184 | + |
| 185 | +# 将 MCP 服务器挂载到单独的应用 |
| 186 | +mcp.mount(mcp_app) |
| 187 | + |
| 188 | +# 现在您可以分别运行两个应用: |
| 189 | +# uvicorn main:api_app --host api-host --port 8001 |
| 190 | +# uvicorn main:mcp_app --host mcp-host --port 8000 |
| 191 | +``` |
| 192 | + |
| 193 | +### 在 MCP 服务器创建后添加端点 |
| 194 | + |
| 195 | +如果您在创建 MCP 服务器后向 FastAPI 应用添加端点,您需要刷新服务器以包含它们: |
| 196 | + |
| 197 | +```python |
| 198 | +from fastapi import FastAPI |
| 199 | +from fastapi_mcp import FastApiMCP |
| 200 | + |
| 201 | +app = FastAPI() |
| 202 | +# ... 定义初始端点 ... |
| 203 | + |
| 204 | +# 创建 MCP 服务器 |
| 205 | +mcp = FastApiMCP(app) |
| 206 | +mcp.mount() |
| 207 | + |
| 208 | +# 在 MCP 服务器创建后添加新端点 |
| 209 | +@app.get("/new/endpoint/", operation_id="new_endpoint") |
| 210 | +async def new_endpoint(): |
| 211 | + return {"message": "Hello, world!"} |
| 212 | + |
| 213 | +# 刷新 MCP 服务器以包含新端点 |
| 214 | +mcp.setup_server() |
| 215 | +``` |
| 216 | + |
| 217 | +## 示例 |
| 218 | + |
| 219 | +请参阅 [examples](examples) 目录以获取完整示例。 |
| 220 | + |
| 221 | +## 使用 SSE 连接到 MCP 服务器 |
| 222 | + |
| 223 | +一旦您的集成了 MCP 的 FastAPI 应用运行,您可以使用任何支持 SSE 的 MCP 客户端连接到它,例如 Cursor: |
| 224 | + |
| 225 | +1. 运行您的应用。 |
| 226 | + |
| 227 | +2. 在 Cursor -> 设置 -> MCP 中,使用您的 MCP 服务器端点的URL(例如,`http://localhost:8000/mcp`)作为 sse。 |
| 228 | + |
| 229 | +3. Cursor 将自动发现所有可用的工具和资源。 |
| 230 | + |
| 231 | +## 使用 [mcp-proxy stdio](https://github.com/sparfenyuk/mcp-proxy?tab=readme-ov-file#1-stdio-to-sse) 连接到 MCP 服务器 |
| 232 | + |
| 233 | +如果您的 MCP 客户端不支持 SSE,例如 Claude Desktop: |
| 234 | + |
| 235 | +1. 运行您的应用。 |
| 236 | + |
| 237 | +2. 安装 [mcp-proxy](https://github.com/sparfenyuk/mcp-proxy?tab=readme-ov-file#installing-via-pypi),例如:`uv tool install mcp-proxy`。 |
| 238 | + |
| 239 | +3. 在 Claude Desktop 的 MCP 配置文件(`claude_desktop_config.json`)中添加: |
| 240 | + |
| 241 | +在 Windows 上: |
| 242 | +```json |
| 243 | +{ |
| 244 | + "mcpServers": { |
| 245 | + "my-api-mcp-proxy": { |
| 246 | + "command": "mcp-proxy", |
| 247 | + "args": ["http://127.0.0.1:8000/mcp"] |
| 248 | + } |
| 249 | + } |
| 250 | +} |
| 251 | +``` |
| 252 | +在 MacOS 上: |
| 253 | +```json |
| 254 | +{ |
| 255 | + "mcpServers": { |
| 256 | + "my-api-mcp-proxy": { |
| 257 | + "command": "/Full/Path/To/Your/Executable/mcp-proxy", |
| 258 | + "args": ["http://127.0.0.1:8000/mcp"] |
| 259 | + } |
| 260 | + } |
| 261 | +} |
| 262 | +``` |
| 263 | +通过在终端运行`which mcp-proxy`来找到 mcp-proxy 的路径。 |
| 264 | + |
| 265 | +4. Claude Desktop 将自动发现所有可用的工具和资源 |
| 266 | + |
| 267 | +## 开发和贡献 |
| 268 | + |
| 269 | +感谢您考虑为 FastAPI-MCP 做出贡献!我们鼓励社区发布问题和拉取请求。 |
| 270 | + |
| 271 | +在开始之前,请参阅我们的 [贡献指南](CONTRIBUTING.md)。 |
| 272 | + |
| 273 | +## 社区 |
| 274 | + |
| 275 | +加入 [MCParty Slack 社区](https://join.slack.com/t/themcparty/shared_invite/zt-30yxr1zdi-2FG~XjBA0xIgYSYuKe7~Xg),与其他 MCP 爱好者联系,提问,并分享您使用 FastAPI-MCP 的经验。 |
| 276 | + |
| 277 | +## 要求 |
| 278 | + |
| 279 | +- Python 3.10+(推荐3.12) |
| 280 | +- uv |
| 281 | + |
| 282 | +## 许可证 |
| 283 | + |
| 284 | +MIT License. Copyright (c) 2024 Tadata Inc. |
0 commit comments