第4章:第一个 MCP 服务器
🎯 章节目标:亲手写出一个可运行、可调试、可部署的 MCP 服务器 ⏱️ 章节时长:4–6 小时(建议边读边敲) 📊 难度等级:⭐⭐⭐ 实战(需完成第 1–3 章)
🚀 章节概述
这是全教程第一个"出成果"的章节。从 MCP 世界的 "Hello World" 开始,一路走到能部署上线的完整项目。
节奏是渐进的,不要跳步:
跑起来 → 加工具 → 写好工具 → 接客户端 → 测稳 → 部署 → 进流水线。
每一小节都配套可运行代码。建议不要复制粘贴了事——跟着敲一遍,改改参数,看看 Inspector 里工具定义怎么变,收获会大得多。
📌 版本提醒:本章代码基于 MCP Python SDK 2.x(当前主线)。写法上工具用
@server.tool()装饰器或server.add_tool(fn, name=...)注册,不需要手写Tool定义字典;传输由server.run(transport="stdio")指定,可选stdio/sse/streamable-http。
🗺️ 学习路径
📚 章节内容
| 小节 | 标题 | 核心内容 | 难度 |
|---|---|---|---|
| 4.1 | 创建简单MCP服务器 | 最小可运行服务器、stdio 传输、用 Inspector 连上它 | ⭐⭐ |
| 4.2 | 添加更多工具 | 多工具注册、类型注解转 Schema、工具命名与描述 | ⭐⭐ |
| 4.3 | 高级工具开发 | 参数校验、异步工具、结构化输出、错误处理 | ⭐⭐⭐ |
| 4.4 | 客户端集成与测试 | 客户端与服务器联调、请求/响应闭环、协议版本确认 | ⭐⭐⭐ |
| 4.5 | 测试和调试 | 单元测试、Inspector 调试、常见故障定位 | ⭐⭐⭐ |
| 4.6 | 部署和优化 | 生产配置、性能与稳定性、日志与监控 | ⭐⭐⭐ |
| 4.7 | Docker和持续集成 | 容器化打包、镜像构建、CI/CD 流水线 | ⭐⭐⭐⭐ |
👶 4.1 创建简单MCP服务器
MCP 世界的 "Hello World"。十几行代码,一个能跑起来的服务器,再把它连进 Inspector 看看长什么样。
看点:最小工程结构、MCPServer 初始化、run(transport="stdio")、Inspector 初体验。
➕ 4.2 添加更多工具
从"一个工具"到"一套工具"。学习怎么注册多个工具,理解函数类型注解如何自动变成 JSON Schema,以及工具命名和描述为什么直接影响模型调用准确率。
看点:@server.tool() / add_tool 两种注册方式、注释即文档、命名规范。
🧠 4.3 高级工具开发
让工具从"能用"到"好用":参数约束(枚举/范围/长度/正则)、异步 I/O、结构化输出、优雅的错误返回。
看点:Annotated + Field 做参数约束、异步工具、错误如何不"炸掉"会话。
🔌 4.4 客户端集成与测试
把"顾客"请进来。写一个客户端,连上你的服务器,走完一次完整的工具调用闭环,确认协议版本与传输配置无误。
看点:客户端连接、list_tools / call_tool 调用、请求与响应对照。
🧪 4.5 测试和调试
在问题暴露给用户之前抓住它。单元测试 + Inspector 交互式调试双管齐下,并覆盖高频故障的定位套路。
看点:pytest 测试工具函数、Inspector 逐步调试、错误日志阅读。
🚢 4.6 部署和优化
从"我机器上能跑"到"生产环境稳得住"。配置、性能、稳定性、可观测性一次说清。
看点:生产配置项、性能优化点、日志与监控接入。
🐳 4.7 Docker和持续集成
容器化打包,让环境不再成为借口;接上 CI/CD,让每次提交都自动验证与发布。
看点:Dockerfile 编写、镜像构建、GitHub Actions 流水线。
🎯 学习目标
读完本章,你应当能够:
- ✅ 从零创建一个可运行的 MCP 服务器,并用 Inspector 连上调试
- ✅ 用类型注解自动生成工具 Schema,注册多个工具
- ✅ 开发带参数校验、异步处理和结构化输出的高级工具
- ✅ 编写客户端完成一次端到端的工具调用
- ✅ 为工具编写单元测试,并能独立定位常见故障
- ✅ 将服务器 Docker 化并接入 CI/CD 流水线
⚡ 最小可运行示例
先睹为快。一个带两则运算工具的最小服务器:
from mcp.server import MCPServer
server = MCPServer("calculator")
@server.tool()
def add(a: float, b: float) -> float:
"""把两个数相加并返回结果。"""
return a + b
@server.tool()
def multiply(a: float, b: float) -> float:
"""把两个数相乘并返回结果。"""
return a * b
if __name__ == "__main__":
server.run(transport="stdio")工具名默认取函数名,描述默认取 docstring,参数 Schema 由类型注解推导——不用手写任何 Schema。这几行就是第4章全部内容的种子。
🚦 下一步
跑通第一个服务器后,进入第5章解锁资源、提示词、流式处理等高级特性。