在前面的文章里,笔者也介绍过 MCP 是什么,以及 MCP 相较于传统 Function Call 方式的优势。当下,更多开发者关注的是如何在自己的代码中实际集成和使用 MCP,这也是过去几期文章讨论的核心,感兴趣的朋友可以翻阅查看。
虽然 MCP 协议官方定义了 LLM 应用访问外部“工具”(执行动作)和“资源”(获取数据)的标准方式,并提供了不少客户端和服务器的构建方法与示例,但从协议层直接构建 MCP 服务,仍然不可避免地涉及大量繁琐的底层工作。对于普通开发者而言,一个封装完善、简单易用的开发框架就显得尤为重要。
今天,笔者就向大家介绍一个非常好用的 MCP 库——FastMCP。可以说,FastMCP 是当前最受欢迎的用于构建 MCP Server 的库之一。
基本介绍
FastMCP 核心目标就是成为构建 MCP Server 和客户端的“快速、Pythonic 的方式”。它远不止是一个简单的封装,而是一套完整的解决方案。它旨在屏蔽 MCP 协议的底层复杂性,让开发者能够运用熟悉且喜爱的 Python 语法和模式,专注于创造真正有价值的功能,而无需在协议处理、Server 管理、内容类型协商等事务上耗费心神。
快速上手:构建计算器服务
使用 FastMCP 构建一个简单的加法工具,只需几行代码:
# server.py
from fastmcp import FastMCP
# 1. 创建一个 FastMCP 服务器实例
mcp = FastMCP("计算器 Demo")
# 2. 使用 @mcp.tool() 装饰器暴露一个函数作为工具
@mcp.tool()
def add(a: int, b: int) -> int:
"""将两个数字相加"""
return a + b
# 3. (非必要) 使脚本可以直接运行
if __name__ == "__main__":
mcp.run() # 启动服务器
运行服务
在终端中,你可以这样启动服务:
-
开发模式 (推荐用于调试):
fastmcp dev server.py
这将启动一个本地开发服务器,并提供一个交互式的 MCP Inspector 界面,方便调试(如下图所示)。
-
生产模式 (直接运行):
python server.py
启动后,一个本地 MCP Server 就构建完成了,任何兼容 MCP 的客户端都可以发现并使用这个 add
工具。

提示:FastMCP 项目的 examples/
目录下有更丰富的代码示例,涵盖基础到高级用法,是学习和测试的好资源。
核心概念与特性
FastMCP 使用直观的装饰器来定义 Server 管理的各个组件:
1. 构建 FastMCP
服务器实例:
-
它是 MCP 应用的核心对象,负责处理连接、协议和路由。 -
创建: mcp = FastMCP("My Awesome App")
-
指定依赖 (可选): mcp = FastMCP("Data App", dependencies=["pandas", "numpy"])
2. 工具 (Tools): @mcp.tool()
-
用途: 让 LLM 执行你的 Python 函数(同步/异步),适用于计算、API 调用、产生副作用等场景。 -
实现: 使用 @mcp.tool()
装饰函数。FastMCP 会根据函数的类型提示(支持 Pydantic 模型)和文档字符串自动生成 MCP 协议所需的模式 (Schema)。
@mcp.tool()
async def send_notification(user_id: int, message: str) -> dict:
"""向用户发送通知。"""
print(f"Notifying user {user_id}: {message}")
return {"status": "sent"}
3. 资源 (Resources): @mcp.resource("your://uri/template/{param}")
-
用途: 向 LLM 暴露数据,主要用于信息获取(类似 HTTP GET),应避免复杂计算和副作用。 -
实现: 使用 @mcp.resource("uri")
装饰函数。URI 可以是静态的,也可以使用{}
定义动态模板,URI 中的参数会自动传递给函数。
# 静态资源示例
@mcp.resource("config://app-version")
def get_app_version() -> str:
"""返回应用版本号。"""
return "v2.1.0"
# 动态资源示例
@mcp.resource("db://users/{user_id}/email")
async def get_user_email(user_id: str) -> str:
"""根据用户ID检索邮箱地址。"""
# ... 此处执行数据库查询逻辑 ...
return f"{user_id}@example.com"
4. 提示 (Prompts): @mcp.prompt()
-
用途: 定义可复用的文本模板或交互模式,用于指导 LLM 如何更有效地使用你的工具和资源。 -
实现: 使用 @mcp.prompt()
装饰函数。函数可以返回简单的字符串,或者UserMessage
、AssistantMessage
对象(或它们的列表)。
from fastmcp.prompts.base import UserMessage
@mcp.prompt()
def ask_review(code_snippet: str) -> UserMessage:
"""生成标准的 Code Review 请求。"""
return UserMessage(f"请帮忙审查以下代码:\n```python\n{code_snippet}\n```")
5. 上下文 (Context
):
-
用途: 在工具或资源函数的内部访问 MCP 服务器提供的能力。 -
实现: 在函数参数中添加类型提示 ctx: Context
。 -
核心能力: -
日志记录: ctx.debug()
,ctx.info()
,ctx.warning()
,ctx.error()
-
进度报告: ctx.report_progress(current, total)
-
读取其他资源: await ctx.read_resource(uri)
-
获取请求信息: ctx.request_id
,ctx.client_id
-
LLM 采样 (高级): await ctx.sample(...)
请求客户端 LLM 生成内容。
from fastmcp import Context
@mcp.tool()
async def process_data(data_uri: str, ctx: Context) -> str:
"""处理大型文件,并报告进度。"""
await ctx.info(f"开始处理文件:{data_uri}")
content_resource = await ctx.read_resource(data_uri)
content = content_resource[0].content # 假设是文本内容
# ... 执行处理逻辑 ...
await ctx.report_progress(1, 1) # 报告处理完成
await ctx.info(f"文件处理完成:{data_uri}")
return "处理成功。"
6. 图像处理 (Image
):
-
用途: 简化图像数据的输入和输出。 -
实现: 使用 fastmcp.Image
类。FastMCP 会自动处理图像数据与 MCP 协议要求的 Base64 编码之间的转换。
from fastmcp import Image
from PIL import Image as PILImage
import io
@mcp.tool()
def create_thumbnail(img_data: Image) -> Image:
"""根据提供的图像创建缩略图。"""
img = PILImage.open(io.BytesIO(img_data.data))
img.thumbnail((100, 100))
buffer = io.BytesIO()
img.save(buffer, format="PNG")
# 返回包含缩略图数据的新 Image 对象
return Image(data=buffer.getvalue(), format="png")
@mcp.tool()
def load_image(path: str) -> Image:
"""从指定路径加载图像。"""
# 自动处理文件读取和基于扩展名的格式检测
return Image(path=path)
客户端交互
FastMCP 不仅能构建服务器,还提供了强大的 Client
类。你可以用它通过 Python 代码轻松地与 任何 兼容 MCP 的服务器进行交互(调用工具、读取资源),并支持多种传输协议和 LLM 采样等高级功能。
-
客户端交互示例:
from fastmcp import Client
# 连接目标可以是脚本路径、服务器URL或FastMCP对象
async with Client("path/to/server_script.py") as client:
# 调用工具
result = await client.call_tool("add", {"a": 5, "b": 3})
print(f"调用 add(5, 3) 结果: {result.content[0].text}") # Output: 8
# 读取资源
version = await client.read_resource("config://app-version")
print(f"读取 config://app-version 结果: {version.content[0].text}")
FastMCP v2 高级特性:无缝集成现有 API
FastMCP v2 引入了多项高级特性,其中最引人瞩目的显著优势是能够从你现有的 FastAPI 应用或 OpenAPI 规范自动生成 MCP 服务器。这意味着你可以轻松复用已有的 Web API 代码,将其快速接入 LLM 生态。
只需使用 FastMCP.from_fastapi(your_fastapi_app)
或 FastMCP.from_openapi(spec, client=http_client)
,FastMCP 就能智能地将 HTTP 端点映射为 MCP 的工具和资源。
-
示例:一行代码桥接 FastAPI 应用
from fastapi import FastAPI
from fastmcp import FastMCP
# 假设你有一个现成的 FastAPI 应用
fastapi_app = FastAPI()
@fastapi_app.get("/status", summary="获取服务状态")
def get_status():
return {"status": "ok"}
@fastapi_app.post("/users/{user_id}/notify", summary="向用户发送通知")
def notify_user(user_id: int, message: str):
print(f"正在通知用户 {user_id}: {message}")
return {"delivered": True}
# 只需这一行代码,即可从 FastAPI 应用创建 MCP 服务器!
mcp_server = FastMCP.from_fastapi(fastapi_app, name="API Bridge")
# 现在 mcp_server 就可以运行并被 LLM 使用了
# if __name__ == "__main__":
# mcp_server.run()
此外,FastMCP v2 还支持代理现有 MCP 服务器 (FastMCP.from_client
) 和组合多个 MCP 应用 (mcp.mount
),这为构建更复杂、模块化的系统提供了便利。
小结
FastMCP 凭借其 Pythonic 的设计哲学、简洁易用的 API 以及强大的功能(尤其是 FastAPI/OpenAPI 集成),极大地降低了构建 MCP Server 或将现有服务暴露为 MCP Server 的门槛。它为开发者提供了一条优雅的适配MCP协议的路径,轻松扩展 LLM 的能力边界,同时自己也成为当前构建MCP Server最佳方案之一。
-
官方文档:gofastmcp.com -
GitHub 仓库:github.com/jlowin/fastmcp
(文:AI工程化)