第十课
MCP 从零实现教程(十)
第十课:重构你的 Mini MCP——从”教程代码”变成真正的项目
目标:把前九课所有代码整理成一个可维护、可扩展的项目。
📚 本课目标
学完本课后,你将能够:
- 为什么不能所有代码都写在一个
server.py - 如何拆分 MCP 项目
- 如何新增一个 Tool,而不用修改其它代码
- 如何让你的项目越来越接近官方 SDK 的组织方式
这一课最大的变化不是增加功能,而是优化架构。
以后你写任何 Agent、MCP Server、Web 服务,都会不断经历这个过程。
📖 第一部分:我们的代码已经开始”乱”了
现在我们的代码大概是这样的:
server.py
200~500 行
├── Tool
├── Resource
├── Prompt
├── Registry
├── Dispatcher
├── initialize
├── tools/list
├── tools/call
├── while True
└── json.loads()
有没有发现?
虽然能运行,
但是:
越来越难维护。
如果以后有:
100 个 Tool
怎么办?
全部放一个文件?
当然不行。
📖 第二部分:真正的软件都会拆模块
例如一个电商系统:
user.py
order.py
product.py
payment.py
不会:
system.py
一万行。
MCP Server 也是一样。
所以:
我们开始拆目录。
📖 第三部分:第一版项目结构
建议创建:
mini_mcp/
├── server.py # 启动 Server
├── dispatcher.py # Dispatcher
├── registry.py # Registry
├── tools/
│ ├── __init__.py
│ ├── math.py
│ ├── weather.py
│ └── file.py
├── resources/
│ ├── __init__.py
│ └── docs.py
├── prompts/
│ ├── __init__.py
│ └── code_review.py
└── client.py
这已经非常接近真实项目了。
📖 第四部分:Registry 独立出来
以前:
TOOLS = {}
RESOURCES = {}
PROMPTS = {}
全部写:
server.py
现在:
新建:
registry.py
内容:
TOOLS = {}
RESOURCES = {}
PROMPTS = {}
以后:
任何地方:
from registry import TOOLS
即可。
📖 第五部分:Dispatcher 独立
以前:
Dispatcher:
def dispatch(request):
...
放:
server.py
现在:
新建:
dispatcher.py
内容:
from registry import TOOLS
def dispatch(request):
method = request["method"]
if method == "tools/list":
...
elif method == "tools/call":
...
Server:
只负责:
response = dispatch(request)
这样:
职责非常清晰。
📖 第六部分:Tool 拆目录
以前:
@tool
def add():
和:
@tool
def weather():
全部放一起。
现在:
tools/
├── math.py
里面:
from registry import TOOLS
def add(a, b):
return a + b
TOOLS["add"] = {
"func": add,
"description": "加法"
}
再建:
weather.py
from registry import TOOLS
def weather(city):
return f"{city} 晴天"
TOOLS["weather"] = {
"func": weather,
"description": "天气"
}
是不是:
每个文件只负责一种能力?
📖 第七部分:Server 变得非常干净
以前:
Server:
300 行。
现在:
import json
from dispatcher import dispatch
import tools.math
import tools.weather
def run():
while True:
text = input()
request = json.loads(text)
response = dispatch(request)
print(json.dumps(response))
run()
是不是:
Server:
终于只负责:
接收
↓
Dispatcher
↓
发送
其它事情:
全部交给:
模块。
📖 第八部分:新增一个 Tool 变得非常容易
假设:
新增:
calculator.py
只需要:
from registry import TOOLS
def multiply(a, b):
return a * b
TOOLS["multiply"] = {
"func": multiply,
"description": "乘法"
}
然后:
import tools.calculator
结束。
Dispatcher:
完全不用改。
Server:
完全不用改。
这就是:
开放封闭原则(Open/Closed Principle):
新增功能,不修改已有逻辑。
📖 第九部分:官方 SDK 为什么几乎没有 Dispatcher?
你可能会发现:
官方 FastMCP 示例里面:
几乎没有:
dispatch()
为什么?
因为:
SDK 已经把:
Dispatcher
↓
Registry
↓
Lifecycle
↓
Transport
全部封装起来了。官方 FastMCP 的职责就是负责协议处理、消息路由、生命周期管理,你只需要注册 Tool、Resource、Prompt 即可。
所以:
@mcp.tool()
def add(...):
...
其实内部,
最后还是进入:
Registry
↓
Dispatcher
↓
Tool
只是:
你看不到。
📖 第十部分:我们继续升级目录
如果以后:
越来越复杂。
还可以继续拆。
例如:
mini_mcp/
├── server.py
├── client.py
├── core/
│ ├── dispatcher.py
│ ├── registry.py
│ ├── lifecycle.py
│ └── transport.py
├── tools/
│ ├── math.py
│ ├── weather.py
│ └── github.py
├── resources/
│ └── docs.py
├── prompts/
│ └── review.py
├── models/
│ ├── request.py
│ └── response.py
└── utils/
└── json_util.py
这时候:
你的项目,
已经开始接近:
真正的 MCP Server。
💻 第十一部分:推荐你做一次真正的重构
到目前为止,我建议你不要继续在原来的 server.py 上修改。
而是重新创建一个项目。
例如:
mini_mcp/
├── server.py
├── client.py
├── registry.py
├── dispatcher.py
├── tools/
│ ├── __init__.py
│ ├── math.py
│ └── weather.py
然后:
把前九课所有代码,
一点一点搬过去。
这个过程,
你的理解会提升非常快。
🧪 本课练习
请完成下面这个项目。
mini_mcp/
├── server.py
├── dispatcher.py
├── registry.py
└── tools/
├── math.py
├── weather.py
└── hello.py
要求:
运行:
python server.py
能够:
tools/list
↓
返回:
add
weather
hello
然后:
tools/call
↓
hello("John")
↓
你好,John
🎯 本课总结
今天,
我们没有增加任何新协议。
但是完成了一件更重要的事情:
开始像软件工程师一样组织代码,而不是像写教程一样写代码。
现在你的项目已经拥有:
✅ Registry
✅ Dispatcher
✅ Lifecycle
✅ Server
✅ Tool 模块
而且:
新增 Tool 不需要修改已有代码。
这就是一个优秀框架最重要的特征。
🚀 第十一课预告(真正开始使用官方 SDK)
前十课,我们一直坚持:
不用 SDK。
下一课开始,我们终于会安装官方 Python SDK:
pip install "mcp[cli]"
或者官方推荐的:
uv add "mcp[cli]"
然后,我们会把自己写的 MiniMCP 与官方 FastMCP 一步一步对照,实现同样的功能。官方 SDK 不仅提供 Tool,还支持 Resource、Prompt、STDIO、Streamable HTTP 等完整协议能力。
到那时,你不会只是”会用 SDK”,而是真正知道:
SDK 每一行代码背后,到底帮你做了什么。

浙公网安备 33010602011771号