mcpField
F
FastMCP - FastAPI MCP Framework & Runner

FastMCP - FastAPI MCP Framework & Runner

本地服务
github.com/Manas-maker开发工具04 周前更新

关于 FastMCP - FastAPI MCP Framework & Runner

FastMCP 是面向 FastAPI 的 MCP 框架,可将现有路由转换为工具,也支持自定义工具和 stdio 运行。适合构建 FastAPI 后端与 MCP 客户端之间的服务。

主要功能

  1. 01反射 FastAPI 路由为工具
  2. 02注册自定义 AI 工具
  3. 03渐进式工具发现
  4. 04桥接 ASGI 身份验证
  5. 05交互式浏览器与聊天界面
  6. 06stdio 命令行运行器

适用场景

  1. 01向 MCP 客户端开放选定的 FastAPI 端点
  2. 02为大型服务按需查找工具
  3. 03沿用 FastAPI 依赖项执行授权
  4. 04通过桌面 AI 客户端连接本地服务

MCP 相关

它提供 MCP 服务,可通过 ASGI 挂载或 stdio 运行。MCP 客户端可调用反射生成的路由工具和自定义工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"manas-maker-fast": {
"command": "uvx",
"args": [
"mcp-fastapi"
],
"env": {
"FASTMCP_LOG_LEVEL": "<FASTMCP_LOG_LEVEL>"
}
}
}
}
启动命令uvx mcp-fastapi
需要配置的环境变量
FASTMCP_LOG_LEVELLog verbosity level (DEBUG, INFO, WARNING, ERROR)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypimcp-fastapi0.1.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Fast-MCP:从 ASGI 到 Model Context Protocol

fast-mcp

原生支持 FastAPI 的 Model Context Protocol(MCP)框架,具备自动路由反射、ASGI 作用域桥接、动态渐进式工具发现、弹性错误恢复,以及交互式聊天内 MCP Apps(SEP-1865)。

PyPI Tests Documentation Python FastAPI Glama


亮点

  • ⚡ 混合双重身份 ASGI 挂载: 通过标准 ASGI 在进程内直接挂载到任何现有的 FastAPI 实例——无需外部代理,也不会产生挂起的子进程。
  • 🔌 本地 stdio 命令行运行器与桌面 AI 桥接: 运行 fast-mcp stdio main:app 或 python -m fast_mcp stdio main:app,即可通过标准输入输出管道连接桌面 AI 客户端(Claude Desktop、Cursor),无需进行网络配置。
  • 🔍 路由反射: 选择加入的标签(tags=["mcp"])会自动将 FastAPI 端点、Pydantic 模型、文档字符串、路径/查询/正文参数转换为 MCP 工具。
  • 🛠️ 自定义 AI 工具(@mcp.tool): 除反射路由外,还可定义专为 AI 定制的复合工具,并自动提取架构和文档字符串。
  • 🔐 ASGI 作用域桥接: 在 MCP 握手期间捕获的客户端授权标头(Authorization: Bearer <token>、Cookie、API 密钥)会桥接到内存中的 ASGI Request,无需更改代码即可原生解析 FastAPI 的 Depends() 和 Security() 提供程序。
  • 🧠 动态渐进式工具发现: 通过渐进式发现(dynamic_discovery=True)、search_tools(query: str) 元工具和零依赖的 KeywordTagRouter,保护 Agent 的上下文窗口。
  • 🛡️ 弹性错误恢复与精简 JSON: 将路由 HTTPException 和 Pydantic 验证错误捕获并转换为信息丰富的 CallToolResult(isError=True) 响应,让大模型能够自行纠正,而不会导致协议失败。默认采用紧凑、节省 Token 的精简 JSON 输出,并提供自定义 @mcp.serializer 格式化钩子。
  • 🖥️ 双重 UI 与聊天内 MCP Apps(SEP-1865): 提供位于 /mcp/docs 的嵌入式浏览器检查器,并通过 _meta.ui.resourceUri、内置 inspect() 工具和 @mcp.app() 装饰器,原生支持在桌面 AI 客户端(Claude Desktop、Cursor、VS Code)中使用聊天内交互式 iframe。

安装

pip install mcp-fastapi

或者使用 uv:

uv add mcp-fastapi

快速开始

from fastapi import FastAPI, Depends, Header, HTTPException
from pydantic import BaseModel, Field
from fast_mcp import FastMCP

app = FastAPI(title="Store API")
mcp = FastMCP(app=app, name="store-mcp")

# 1. Existing FastAPI route reflected automatically via tags=["mcp"]
class Product(BaseModel):
    id: int
    name: str
    price: float

@app.get("/products/{product_id}", tags=["mcp"])
async def get_product(product_id: int) -> Product:
    """Fetch product details by ID."""
    if product_id == 404:
        raise HTTPException(status_code=404, detail="Product not found")
    return Product(id=product_id, name="Smart Widget", price=29.99)

# 2. Custom AI tool with native dependency injection
def verify_token(authorization: str = Header(...)) -> str:
    if not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Invalid token")
    return authorization.split(" ")[1]

@mcp.tool(name="order_status", description="Check customer order status")
def check_order(order_id: str, user: str = Depends(verify_token)) -> dict:
    return {"order_id": order_id, "customer": user, "status": "Shipped"}

# 3. Mount MCP endpoints (/mcp/sse, /mcp/messages, /mcp/docs)
mcp.mount()

使用标准 ASGI 服务器运行:

uvicorn main:app --reload

核心功能

1. 路由反射

带有 tags=["mcp"] 标签的路由(可通过 route_tag 配置)会在调用 mcp.mount() 时自动检查:

  • 端点文档字符串(Google、Sphinx、NumPy 格式)会转换为工具描述和参数文档。
  • Pydantic 请求模型、查询参数和路径变量会转换为 MCP 输入架构。
  • 未标记的端点仍是标准 HTTP 路由,不会泄露给大模型。
@app.post("/items/create", tags=["mcp"])
async def create_item(item: ItemModel) -> ItemModel:
    """Create a new catalog item.

    Args:
        item: The catalog item specification.
    """
    return item
2. 自定义 AI 工具(@mcp.tool)

注册无需专用 REST 端点的 AI 专用工具:

# Bare decorator
@mcp.tool
def calculate_quote(quantity: int, discount: float = 0.0) -> float:
    return quantity * 100.0 * (1.0 - discount)

# Parameterized decorator
@mcp.tool(name="inventory_lookup", description="Lookup stock levels", tags=["inventory"])
async def check_inventory(sku: str) -> dict:
    return {"sku": sku, "in_stock": True, "count": 42}
3. ASGI 作用域桥接与原生身份验证

来自 MCP 客户端 SSE 握手或消息请求的传入标头(Authorization: Bearer ...、Cookie、API 密钥)会被捕获到活动请求上下文中:

from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials

security = HTTPBearer()

@mcp.tool
async def user_profile(creds: HTTPAuthorizationCredentials = Depends(security)) -> dict:
    token = creds.credentials
    return {"user": "alice", "token_verified": True}

如果身份验证失败或未提供标头,fast-mcp 会将生成的 HTTPException(401) 解包为 CallToolResult(is_error=True),这样 Agent 会收到可执行操作的身份验证错误,而不是导致传输崩溃。

4. 动态渐进式工具发现

避免大型 FastAPI 应用中的数百个端点使大模型上下文窗口膨胀:

mcp = FastMCP(
    app=app,
    dynamic_discovery=True,  # Or set dynamic_discovery_threshold=20
    baseline_tools=["search_tools", "get_system_status"],
    baseline_tag="baseline",
)
  • 启用后,tools/list 仅公开基线工具和 search_tools(query: str) 元工具。
  • 调用 search_tools(query="invoice") 会执行可插拔的 ToolRouter(默认使用零依赖的 KeywordTagRouter,按分词后的名称/标签/描述进行排序),并返回匹配工具的完整 JSON 架构。
5. 弹性错误拦截与自定义序列化器
  • 异常捕获: HTTPException(400、404、422)和 Pydantic 验证错误会返回简洁清晰的消息,并将 isError=True。
  • 精简输出: 响应会序列化为精简的 JSON({"id":1,"name":"widget"}),从而节省提示词令牌。
  • 自定义序列化器: 将返回类型格式化为定制的 Markdown 或摘要:
class Report(BaseModel):
    title: str
    metrics: dict[str, int]

@mcp.serializer(Report)
def format_report(report: Report) -> str:
    md = f"### {report.title}\n"
    for k, v in report.metrics.items():
        md += f"- **{k}**: {v}\n"
    return md
6. 双 UI:浏览器检查器与聊天内 MCP 应用(SEP-1865)
嵌入式浏览器检查器

在任何浏览器中打开 http://localhost:8000/mcp/docs,即可检查已注册的工具、查看架构并交互式执行测试调用,无需外部 Node.js CLI。(使用 FastMCP(app, enable_ui=False) 禁用。)

聊天内 MCP 应用(SEP-1865)

直接在现代桌面 AI 客户端(Claude Desktop、Cursor、VS Code)中渲染丰富的交互式 HTML/JS 小组件:

# Built-in server inspector tool
# Agent calling `inspect()` receives an interactive iframe pointed to ui://fast-mcp/inspector

# Authoring custom in-chat widgets:
@mcp.app(
    name="dashboard",
    resource_uri="ui://store/dashboard",
    html="""
    <div style="font-family: sans-serif; padding: 1rem; border-radius: 8px; background: #f0f4f8;">
        <h2>Store Live Metrics</h2>
        <p>Active Users: <strong>1,420</strong></p>
    </div>
    """
)
def live_dashboard() -> str:
    return '<iframe src="ui://store/dashboard" width="100%" height="400"></iframe>'
7. 本地 stdio CLI 运行器与桌面 AI 桥接

通过标准输入/输出(stdio)管道,将桌面 AI 客户端(Claude Desktop、Cursor)直接连接到 FastAPI 后端或 FastMCP 实例,无需配置网络,也不会出现端口冲突或外部代理。

命令行用法
# Run stdio runner pointing to FastAPI app or FastMCP instance
fast-mcp stdio main:app

# Or via Python module invocation
python -m fast_mcp stdio main:app

# Target attribute defaults to 'app' or 'mcp' if omitted:
fast-mcp stdio main

# The 'stdio' subcommand can also be omitted as default:
fast-mcp main:app
Claude Desktop 配置(claude_desktop_config.json)

配置 Claude Desktop 以直接启动 FastMCP 服务:

{
  "mcpServers": {
    "my-fast-mcp-app": {
      "command": "fast-mcp",
      "args": ["stdio", "main:app"]
    }
  }
}

也可以使用 uv 自动管理虚拟环境:

{
  "mcpServers": {
    "my-fast-mcp-app": {
      "command": "uv",
      "args": ["run", "fast-mcp", "stdio", "main:app"]
    }
  }
}
程序化 stdio 运行器

也可以在 Python 中以编程方式运行 stdio 模式:

import asyncio
from fast_mcp import FastMCP, run_stdio

mcp = FastMCP(name="my-stdio-server")

@mcp.tool()
def add(a: int, b: int) -> int:
    return a + b

if __name__ == "__main__":
    asyncio.run(run_stdio(mcp))

测试与验证

fast-mcp 使用 httpx.AsyncClient 和 ASGITransport,通过 ASGI 协议边界测试外部行为:

# Run full test suite
pytest

# Run tests with coverage
pytest --cov=fast_mcp --cov-report=term-missing

规范与架构文档


许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。