第七课
MCP 从零实现教程(七)
第七课:对照官方 MCP SDK——原来我们已经写了 80%
目标:把自己写的 Mini MCP Server 与官方 SDK 一一对应。
📚 本课目标
学完这一课后,你会发现:
- 官方 SDK 没有”魔法”
- SDK 本质上是在帮你自动化重复工作
- 你已经理解了 MCP Server 的核心实现
- 后面学习 LangGraph、ADK 等 Agent 框架会轻松很多
这一课我们第一次使用官方 SDK,但不是从 SDK 学起,而是用我们已经掌握的知识去”拆解 SDK”。
官方 Python SDK 提供了 FastMCP,自动完成 Tool 注册、Schema 生成、JSON-RPC 协议处理和传输层等工作。
📖 第一部分:先回顾我们自己写的代码
到目前为止,我们自己已经实现了:
Tool
│
▼
@tool
│
▼
Registry
│
▼
Dispatcher
│
▼
tools/list
│
▼
tools/call
│
▼
JSON-RPC
│
▼
Server
是不是已经很多了?
📖 第二部分:官方 SDK 长什么样?
官方示例其实非常简单:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""两个数字相加"""
return a + b
if __name__ == "__main__":
mcp.run()
是不是比我们写的代码少很多?
为什么?
因为 SDK 帮我们写了很多代码。
📖 第三部分:第一行代码
官方:
mcp = FastMCP("Demo")
很多新手第一眼会觉得:
FastMCP 好神奇。
其实你现在应该这样理解:
mcp = FastMCP("Demo")
≈
TOOLS = {}
dispatcher = {}
server = {}
也就是说:
FastMCP 就是一个对象。
里面保存了:
- Tool Registry
- Resource Registry
- Prompt Registry
- Dispatcher
- Server
只是封装起来了。
📖 第四部分:真正的 @mcp.tool()
官方:
@mcp.tool()
def add(a: int, b: int):
return a + b
我们自己写的是:
TOOLS = {}
def tool(func):
TOOLS[func.__name__] = {
"func": func
}
return func
有没有发现?
几乎一样。
区别只有:
官方多做了:
- 参数解析
- Schema 生成
- 类型检查
- 注册到 Server
本质还是:
收到函数
↓
保存函数
↓
返回函数
📖 第五部分:SDK 自动帮你生成 Schema
我们以前:
自己写:
import inspect
sig = inspect.signature(func)
然后:
parameters = {}
for name, p in sig.parameters.items():
parameters[name] = p.annotation
官方 SDK:
自动完成:
@mcp.tool()
def weather(city: str):
...
变成:
{
"name": "weather",
"description": "...",
"inputSchema": {
...
}
}
所以:
你之前写的:
inspect.signature()
就是 SDK 的第一步。
📖 第六部分:SDK 自动实现 Dispatcher
以前:
我们自己写:
def dispatch(request):
method = request["method"]
if method == "tools/list":
...
elif method == "tools/call":
...
官方:
你根本看不到。
因为:
SDK 已经写好了。
当收到:
{
"method":"tools/call"
}
SDK 自动:
解析 JSON
↓
找到 Tool
↓
执行 Tool
↓
返回 JSON
是不是和我们第五课完全一样?
📖 第七部分:SDK 自动启动 Server
以前:
我们写:
while True:
text = input()
request = json.loads(text)
response = dispatch(request)
print(json.dumps(response))
官方:
只需要:
mcp.run()
是不是觉得:
mcp.run()
特别厉害?
其实它内部,
大概率就在做:
while True:
...
dispatch(...)
当然真正实现会复杂很多。
但是思想完全一致。
💻 第八部分:如果不用 SDK,你已经会写了
我们自己:
TOOLS = {}
官方:
mcp = FastMCP(...)
我们自己:
@tool
官方:
@mcp.tool()
我们自己:
dispatch()
官方:
自动 Dispatcher
我们自己:
tools/list
官方:
自动实现
我们自己:
tools/call
官方:
自动实现
我们自己:
while True
官方:
mcp.run()
所以:
SDK 帮我们省掉了:
70% 重复代码。
💻 第九部分:自己模拟 FastMCP
为了进一步理解,
我们自己写一个假的 SDK。
例如:
class MiniMCP:
def __init__(self):
self.tools = {}
def tool(self):
def wrapper(func):
self.tools[func.__name__] = func
return func
return wrapper
然后:
mcp = MiniMCP()
@mcp.tool()
def add(a, b):
return a + b
打印:
print(mcp.tools)
输出:
{
"add": <function add>
}
有没有发现?
我们已经自己写出了:
@mcp.tool()
💻 第十部分:继续升级 MiniMCP
继续增加:
class MiniMCP:
def __init__(self):
self.tools = {}
def tool(self):
def wrapper(func):
self.tools[func.__name__] = func
return func
return wrapper
def run(self):
print("Server Start")
while True:
print("等待请求...")
是不是已经越来越像官方 SDK?
以后:
我们还可以增加:
class MiniMCP:
...
def list_tools():
...
def call_tool():
...
def dispatch():
...
其实:
FastMCP 的核心思想,
就是不断往这个类里面增加能力。
🧪 本课练习
请自己实现一个:
class MiniMCP:
要求至少包含:
__init__()
tool()
run()
能够运行:
mcp = MiniMCP()
@mcp.tool()
def hello(name):
return f"你好{name}"
print(mcp.tools)
输出:
{
"hello": <function hello>
}
如果完成了,
说明你已经能够自己设计一个 MCP SDK 的雏形。
🎯 本课总结
今天最大的收获不是学会了 SDK。
而是确认了一件事:
官方 SDK 并没有创造新的原理,它只是把我们前六课写的代码封装成了一个框架。
你现在已经能够把 SDK 中的大多数 API 对应到自己实现过的模块,而不是把它们当成”黑盒”。
🚀 第八课预告(真正进入 MCP 的完整世界)
到目前为止,我们只学习了 Tool。
但是官方 MCP 一共有三种核心能力:
MCP Server
│
├── Tool(工具)
├── Resource(资源)
└── Prompt(提示词)
很多教程只讲 Tool。
但实际上:
- Tool:让 AI 执行操作(例如查询天气、执行 SQL)。
- Resource:让 AI 读取数据(例如文件、配置、数据库内容)。
- Prompt:向 AI 提供可复用的提示模板。
下一课,我们不会急着写代码,而是会先理解:
为什么 MCP 不只设计了 Tool,而是同时设计了 Tool、Resource、Prompt 三种能力?
理解了这三者的职责边界,你对整个 MCP 架构的认识就会完整起来。

浙公网安备 33010602011771号