实战:HTTP 服务器部署
stdio 传输只能服务本机进程;要让远程客户端、多台机器共享同一个服务器,需要把它部署成 HTTP 服务。官方推荐的 HTTP 传输是 Streamable HTTP(旧的 SSE 传输已弃用)。FastMCP 直接提供 streamable_http_app() 生成 ASGI 应用,交给 uvicorn 即可对外服务。
服务器代码:FastMCP + streamable_http_app
# server_http.py:可被 uvicorn 加载的 FastMCP 服务器
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo", instructions="远程演示服务器:提供计算与天气查询")
@mcp.tool()
def add(a: int, b: int) -> int:
"""两数相加"""
return a + b
@mcp.tool()
def weather(city: str) -> str:
"""返回城市的天气(示意数据)"""
return f"{city}:晴,26℃"
app = mcp.streamable_http_app() # 导出 ASGI 应用,供 uvicorn 使用
pip install "mcp" uvicorn
uvicorn server_http:app --host 0.0.0.0 --port 8000
# 输出:INFO: Uvicorn running on http://0.0.0.0:8000
脚本里直接运行 mcp.run() 走的是 stdio;此处把 app 导出给 uvicorn 才是 HTTP 形态。FastMCP 的底层是官方 Server,需要完全掌控协议细节时可用底层 API,以官方文档为准。
挂到 /mcp 子路径
app 默认挂在根路径。若想统一放在 /mcp,用 Starlette/FastAPI 挂载,客户端连接的是完整 URL:
# main.py:把服务器挂载到 /mcp 子路径
from starlette.applications import Starlette
from starlette.routing import Mount
from server_http import app as mcp_app
app = Starlette(routes=[Mount("/mcp", app=mcp_app)])
uvicorn main:app --host 0.0.0.0 --port 8000
# 输出:INFO: Uvicorn running on http://0.0.0.0:8000
# 此时客户端地址为 http://127.0.0.1:8000/mcp
CORS 与鉴权中间件
浏览器里的宿主应用受 CORS 限制,需要放行;生产环境必须在网关上做鉴权(如 Bearer Token),仅做演示示意:
# secure_main.py:FastAPI 承载 /mcp,加 CORS 与 Bearer 校验
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from server_http import app as mcp_app
app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=["*"],
allow_methods=["*"], allow_headers=["*"])
AUTH_TOKEN = "换成随机强令牌" # 生产应来自环境变量
@app.middleware("http")
async def check_auth(request: Request, call_next):
if request.headers.get("Authorization") != f"Bearer {AUTH_TOKEN}":
return JSONResponse({"detail": "unauthorized"}, status_code=401)
return await call_next(request)
app.mount("/mcp", mcp_app)
鉴权的成熟做法(令牌校验、过期、IP 白名单)以官方文档与你的部署实践为准,常见选择是放在 nginx 或 API 网关统一处理。
docker-compose 起服务
把服务器打包成容器,团队部署与升级更一致。目录里准备 Dockerfile 与 docker-compose.yml:
FROM python:3.12-slim
RUN pip install mcp uvicorn fastapi
COPY . /app
WORKDIR /app
CMD ["uvicorn", "secure_main:app", "--host", "0.0.0.0", "--port", "8000"]
services:
mcp-demo:
build: .
ports:
- "8000:8000"
environment:
- AUTH_TOKEN=换成随机强令牌
docker compose up -d --build
# 输出:[+] Running 2/2 ... mcp-demo Started
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8000/
# 输出:404(FastAPI 根路径无路由但服务在响应,说明容器已起来)
客户端远程连接
远程 HTTP 客户端用 streamablehttp_client(见第 11 章);宿主的 mcpServers 配置则写成远程类型:
{
"mcpServers": {
"remote-demo": {
"type": "http",
"url": "http://127.0.0.1:8000/mcp",
"headers": { "Authorization": "Bearer 换成随机强令牌" }
}
}
}
type/url/headers 的字段写法各宿主不完全一致,以各家文档为准。 小结:HTTP 部署 = FastMCP 导出 streamable_http_app() + uvicorn 运行,按需挂到 /mcp 并用中间件加 CORS 与 Bearer 鉴权;docker-compose 负责镜像化运维,客户端用远程 URL 或宿主 mcpServers 配置接入即可。