TellWorldAI 世界档案
问档案English

首页›实践›实践

实践

把 MCP 服务器部署成 HTTP 服务(FastMCP)

用 FastMCP 把 MCP 服务器部署成 HTTP 服务:直接运行与 ASGI 两种方式、端点路径、认证、多 worker 与无状态模式,以及上线前的检查。

这篇适合谁,读完能做到什么

适合已经能在本机跑通 FastMCP 服务器、想让远程客户端访问它的读者。读完你应该能分清直接运行和 ASGI 两种 HTTP 部署方式,知道 /mcp 端点在哪里,明白多 worker 和无状态模式的关系,并知道上线前要检查什么。

先在本机运行

FastMCP 服务器的运行指南主要面向本地开发和测试;把服务部署到一个 URL 上,要看 HTTP 部署指南[1][2]。

调用 FastMCP 实例的 run() 方法即可启动服务器。它会阻塞,直到服务器被停止[1]。文档建议把 run() 放进 if __name__ == "__main__": 块中,这样只有直接执行脚本时才会启动,被导入时不会启动[1]:

from fastmcp import FastMCP

mcp = FastMCP(name="MyServer")

@mcp.tool
def hello(name: str) -> str:
    return f"Hello, {name}!"

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

不带参数调用 run() 时,服务器使用默认的 STDIO 传输。在 STDIO 方式下,每个会话都由客户端启动一个新的服务器进程并管理其生命周期;服务器从标准输入读取 MCP 消息,把响应写到标准输出[1]。这也意味着 STDIO 服务器不会长期运行,它是按需被客户端启动的[1]。

切换到 HTTP 传输

HTTP 传输会把 MCP 服务器变成一个可以通过 URL 访问的 Web 服务,使用 Streamable HTTP 协议,并且能同时服务多个客户端[1]。文档把 Streamable HTTP 列为网络部署的推荐选择[1]。

在 run() 中指定传输方式和网络参数即可,例如:

from fastmcp import FastMCP

mcp = FastMCP("MyServer")

@mcp.tool
def hello(name: str) -> str:
    return f"Hello, {name}!"

if __name__ == "__main__":
    # Start an HTTP server on port 8000
    mcp.run(transport="http", host="127.0.0.1", port=8000)

这样服务器就可以通过 http://localhost:8000/mcp 访问。/mcp 就是客户端连接的 MCP 端点[1]。SSE 传输属于旧的做法,文档建议新项目一律使用 HTTP 传输,不要用 SSE[1]。

两种 HTTP 部署方式

直接运行是最快上线的办法:直接用 mcp.run(transport="http", host="0.0.0.0", port=8000) 启动,由 FastMCP 处理全部 Web 服务器配置。它适合内部工具、开发环境和不需要高级服务器功能的简单部署[2]。

ASGI 应用则更适合生产环境。FastMCP 可以生成一个标准的 ASGI 应用,交给 Uvicorn、Gunicorn 或 Hypercorn 等 ASGI 服务器运行。需要多个 worker、自定义中间件,或与已有 Web 应用集成时,这种方式更合适[2]。下面的例子用 mcp.http_app() 创建应用[2]:

from fastmcp import FastMCP

mcp = FastMCP("My Server")

@mcp.tool
def process_data(input: str) -> str:
    """Process data on the server"""
    return f"Processed: {input}"

# Create ASGI application
app = mcp.http_app()

用 Uvicorn 运行:uvicorn app:app --host 0.0.0.0 --port 8000,服务器仍然可以通过 http://localhost:8000/mcp 访问[2]。

修改端点路径

默认的端点是 /mcp。如果要和已有接口的路径规划保持一致,可以改成其他路径,例如 mcp.run(transport="http", host="0.0.0.0", port=8000, path="/api/mcp"),或者 mcp.http_app(path="/api/mcp")[2]。

认证

远程 MCP 服务器强烈建议启用认证;有些 LLM 客户端在连接远程服务器时必须有认证,否则拒绝连接[2]。

多 worker 与无状态模式

默认情况下,Streamable HTTP 传输会在每个服务器实例的内存里保存会话。部署多个实例时,这会带来问题:请求可能被负载均衡器转发到另一个不持有该会话的实例上,于是请求失败[2]。粘性会话(session affinity)在很多 MCP 客户端上并不可靠,因为这些客户端不会正确转发 Set-Cookie 头[2]。

使用多个 worker 时,需要开启无状态模式,例如[2]:

FASTMCP_STATELESS_HTTP=true uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4

开启无状态模式的方法有三种:mcp.http_app(stateless_http=True),mcp.run(transport="http", stateless_http=True),或者设置上面的环境变量[2]。开启后,每个请求都会创建新的传输上下文,因此不再需要会话亲和性[2]。

常用的 CLI 选项

  • fastmcp run server.py 会在文件中自动查找名为 mcp、server 或 app 的 FastMCP 实例并运行[1]。
  • 使用 --python、--with、--project 或 --with-requirements 时,服务器会通过 uv run 子进程运行,而不是使用本地环境[1]。
  • 服务器自己的参数写在 -- 后面,例如 fastmcp run config_server.py -- --config config.json[1]。
  • --reload 会在源文件变化时重启服务器,该选项从 3.0.0 版本开始提供[1]。SSE 传输不支持自动重载,如果既要网络访问又要自动重载,应当用 HTTP 传输[1]。

异步与自定义路由

在已经运行于异步环境的代码中,应使用 run_async()。在异步函数内部调用 run() 会报错,提示事件循环已经在运行[1]。

如果需要健康检查之类的接口,可以用 @mcp.custom_route("/health", methods=["GET"]) 添加自定义路由。它和 MCP 端点由同一个 Web 服务器提供[1]。

上线前检查什么

  • 平台方面,常见选择有云主机、容器平台、Platform-as-a-Service、边缘平台和 Kubernetes 集群。基本要求是 Python 3.11 或更高版本,并且能对外暴露一个 HTTP 端口[2]。
  • 部署后,可以用 FastMCP 客户端连接服务器的 URL,确认它可以访问,并且列出了预期的工具[2]。
  • 如果是远程服务,先确认认证已经配置好[2]。

限制

  • 多 worker 必须配合无状态模式,否则会话只存在于单个实例的内存中[2]。
  • 粘性会话不能可靠解决多实例的会话问题[2]。
  • SSE 属于旧的传输方式,且不支持自动重载[1]。

下一步

想了解完整的部署选项,包括认证、CORS、反向代理和托管平台,可以继续阅读 FastMCP 的 HTTP 部署指南[2]。

本文改编自 FastMCP 官方文档中的运行服务器(Running Your Server)和 HTTP 部署(HTTP Deployment)两页[1][2],原文以 Apache-2.0 许可证发布。

来源

  1. 1
    FastMCP Running Your ServerFastMCP docs (Apache-2.0)
  2. 2
    FastMCP HTTP DeploymentFastMCP docs (Apache-2.0)

引用本页: 把 MCP 服务器部署成 HTTP 服务(FastMCP). TellWorld, https://www.tellworld.net/zh/practice/practice-fastmcp-http-deploy. 更新于 2026-11-14

相关动态