FastMCP 实战——从本地 stdio 到生产级 HTTP + 鉴权 + 后台任务

本地跑得好好的 MCP Server,一部署到服务器就懵了:stdio transport 根本没法远程访问,HTTP 模式直接裸奔,工具调用一超时就断连。这些坑,FastMCP 2.14 都给你填好了。

stdio 够用吗?不够

FastMCP 默认用 stdio transport------进程间通过标准输入输出通信。本地开发很香,Claude Desktop 直接配个启动命令就能用:

json 复制代码
{
  "mcpServers": {
    "calculator": {
      "command": "python",
      "args": ["/path/to/server.py"]
    }
  }
}

但一上生产就卡了:stdio 只能单机单进程,远程客户端接不进来,没法做负载均衡,日志全混在标准输出里。你需要 HTTP transport。

HTTP Transport 基础版

FastMCP 2.0 开始支持 HTTP,把 mcp.run() 改成 mcp.run(transport="http", port=8000) 就行:

python 复制代码
from fastmcp import FastMCP

mcp = FastMCP("Calculator")

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

if __name__ == "__main__":
    mcp.run(transport="http", port=8000, host="0.0.0.0")

客户端连 http://your-server:8000/mcp 就能调工具了。但这是裸奔------任何人都能调你的 API。

生产第一课:加鉴权

FastMCP 2.11 引入了完整的 OAuth 2.1 支持。最简单的方案是 JWT 验证:你的网关或认证服务签发 JWT,MCP Server 只验证不签发。

python 复制代码
from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import JWTVerifier

# 配置 JWT 验证器(对接你的 IdP 的 JWKS endpoint)
verifier = JWTVerifier(
    jwks_url="https://your-idp.com/.well-known/jwks.json",
    issuer="https://your-idp.com",
    audience="your-mcp-server"
)

mcp = FastMCP("SecureCalculator", auth=verifier)

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

if __name__ == "__main__":
    mcp.run(transport="http", port=8000, host="0.0.0.0")

客户端请求时带上 Authorization: Bearer <token> 头,FastMCP 自动验证签名、过期时间、audience。验证失败直接返回 401,工具不会执行。

踩坑1:JWKS 缓存失效

JWTVerifier 默认缓存 JWKS 公钥 5 分钟。如果你的 IdP 频繁轮换密钥,会出现短暂的验证失败窗口。解决办法:

python 复制代码
verifier = JWTVerifier(
    jwks_url="https://your-idp.com/.well-known/jwks.json",
    issuer="https://your-idp.com",
    audience="your-mcp-server",
    cache_maxsize=128,  # 增加缓存容量
    cache_ttl=300       # 5分钟TTL(可调)
)

生产环境建议开启密钥轮换的 grace period,新旧密钥共存一段时间。

Streamable HTTP:告别 SSE 的断连噩梦

FastMCP 2.14 支持了 MCP 规范新增的 Streamable HTTP transport。之前的 SSE (Server-Sent Events) transport 有个硬伤:长时间工具调用(比如跑个 5 分钟的数据分析)容易被中间代理(nginx、CDN)超时断连。

Streamable HTTP 用双向流 + chunked encoding 解决了这个问题:

python 复制代码
from fastmcp import FastMCP

mcp = FastMCP("DataAnalyzer")

@mcp.tool
async def analyze_large_dataset(file_path: str) -> str:
    # 模拟长时间运行的任务
    import asyncio
    await asyncio.sleep(300)  # 5分钟
    return "Analysis complete"

if __name__ == "__main__":
    # 同时支持 SSE 和 Streamable HTTP,向后兼容
    mcp.run(transport="http", port=8000)

FastMCP 的 HTTP transport 现在同时处理 SSE 和 Streamable HTTP 请求,客户端根据自己的能力选协议。老客户端继续用 SSE,新客户端用 Streamable HTTP。

踩坑2:Nginx 代理配置

Streamable HTTP 要求代理不能缓冲响应体,否则又回到超时断连的老路。Nginx 配置:

nginx 复制代码
location /mcp {
    proxy_pass http://localhost:8000;
    proxy_buffering off;           # 关键:禁用缓冲
    proxy_request_buffering off;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    chunked_transfer_encoding on;
}

Background Tasks:工具调用不再阻塞

FastMCP 2.14 引入了 MCP 规范的后台任务支持。之前如果工具执行时间长,客户端只能傻等;现在可以让工具在后台跑,客户端轮询进度或等通知。

python 复制代码
from fastmcp import FastMCP

mcp = FastMCP("AsyncCalculator")

@mcp.tool(task=True)  # 标记为后台任务
async def compute_fibonacci(n: int) -> int:
    """计算第 n 个斐波那契数(假装很慢)"""
    import asyncio
    await asyncio.sleep(10)
    
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

if __name__ == "__main__":
    mcp.run(transport="http", port=8000)

客户端调用 compute_fibonacci 时,FastMCP 立即返回一个 task_id,任务在后台执行。客户端可以:

  • 轮询任务状态(GET /mcp/tasks/{task_id}
  • 等待任务完成并获取结果

默认用内存队列(重启丢失),生产环境建议用 Redis:

python 复制代码
from fastmcp import FastMCP
from docket.brokers import RedisBroker

broker = RedisBroker("redis://localhost:6379/0")
mcp = FastMCP("AsyncCalculator", task_broker=broker)

# 其余代码不变

Redis broker 支持水平扩展:多个 FastMCP 实例共享任务队列,任何实例都能处理任务。

踩坑3:任务清理

后台任务完成后会保留在队列里,时间长了内存爆炸。FastMCP 2.14.5 修了内存泄漏,但你还需要配置任务过期:

python 复制代码
from docket.brokers import MemoryBroker

broker = MemoryBroker(
    result_ttl=3600  # 任务结果保留1小时后删除
)
mcp = FastMCP("AsyncCalculator", task_broker=broker)

Redis broker 自带 TTL,不用额外配置。

生产清单

把这些坑踩一遍,总结出生产部署检查清单:

  1. 网络绑定host="0.0.0.0" 允许外部访问,但必须配鉴权
  2. 鉴权方式:JWT 验证器(对接 IdP)或 OAuth 提供商(WorkOS、Auth0)
  3. Transport:用 HTTP,自动支持 SSE + Streamable HTTP
  4. 代理配置:Nginx 禁用 buffering,支持 chunked encoding
  5. 后台任务 :长时间工具标记 task=True,生产用 Redis broker
  6. 监控日志:FastMCP 输出结构化日志,接入 ELK/Grafana
  7. 错误处理:工具函数抛异常会返回错误消息,不会让服务崩溃

代码全景

最后贴个生产级配置的完整示例:

python 复制代码
import asyncio
from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import JWTVerifier
from docket.brokers import RedisBroker

# JWT 鉴权
verifier = JWTVerifier(
    jwks_url="https://your-idp.com/.well-known/jwks.json",
    issuer="https://your-idp.com",
    audience="calculator-mcp"
)

# Redis 后台任务队列
broker = RedisBroker("redis://localhost:6379/0")

mcp = FastMCP("ProductionCalculator", auth=verifier, task_broker=broker)

@mcp.tool
def add(a: int, b: int) -> int:
    """快速工具:同步返回"""
    return a + b

@mcp.tool(task=True)
async def heavy_compute(n: int) -> int:
    """慢速工具:后台执行"""
    await asyncio.sleep(30)
    return n * n

if __name__ == "__main__":
    mcp.run(transport="http", port=8000, host="0.0.0.0")

配套 Nginx:

nginx 复制代码
upstream mcp_backend {
    server 127.0.0.1:8000;
    server 127.0.0.1:8001;  # 水平扩展
}

server {
    listen 443 ssl;
    server_name mcp.example.com;

    location /mcp {
        proxy_pass http://mcp_backend;
        proxy_buffering off;
        proxy_request_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding on;
    }
}

从本地 stdio 到生产 HTTP,FastMCP 的路径很清晰:先让工具跑起来,再加鉴权,最后上后台任务。每个特性都解决实际痛点,不是堆概念。

MCP Server 不是玩具,生产部署要考虑安全、可靠、可扩展。FastMCP 2.14 把这些都做成了开箱即用的功能,剩下的就是你的业务逻辑了。

相关推荐
算力百科小智2 小时前
手机漫剧 App 与电脑平台对比哪个更强
aigc
captain_AIouo2 小时前
Captain AI全功能矩阵覆盖OZON运营每一个关键节点
大数据·人工智能·经验分享·矩阵·aigc
Pkmer3 小时前
深度优先遍历遇上 AI:用 LangChain Agent 实现 26 个字母的趣味自我介绍
langchain·aigc
DigitalOcean3 小时前
AI 推理引擎四大模式:无服务推理、专用推理、批量推理与智能路由,怎么选?
llm·aigc·agent
魔术师Grace3 小时前
只换两个词,GPT image2 出品牌大片
aigc
weixin_435208163 小时前
大模型 Agent 面试高频100题——基础篇
人工智能·深度学习·自然语言处理·面试·职场和发展·aigc
JackieZhengChina4 小时前
清华大学《AIGC报告5.0》|生成式人工智能行业深度研究报告(2026年版)(文末附完整PDF报告)
人工智能·aigc
Rolei_zl4 小时前
AIGC(生成式AI)试用 50 -- 随想next AI?
aigc
captain_AIouo4 小时前
全方位降本增效,Captain AI重构OZON运营成本结构
大数据·人工智能·经验分享·重构·aigc