第十一课

MCP 从零实现教程(十一)

第十一课:第一次使用官方 MCP SDK

目标:安装官方 SDK,并写出你的第一个官方 MCP Server。


📚 本课目标

今天开始,我们不再自己造轮子

而是开始学习官方 SDK。

但是和别人不同的是:

别人学的是:

API

而你学的是:

API 背后的实现原理。

所以今天你看到任何代码,都应该能知道:

它对应我们前十课自己写的哪一部分。


📖 第一部分:为什么现在才开始用 SDK?

很多教程第一节课就是:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Demo")

然后告诉你:

这是 MCP。

但是你现在应该知道:

实际上:

FastMCP
│
├── Registry
├── Dispatcher
├── Lifecycle
├── JSON-RPC
├── Tool Discovery
├── Tool Call
└── Transport

这些东西,

你都已经自己写过了。

所以:

SDK 只是把前十课封装起来了。


📖 第二部分:安装官方 SDK

官方推荐两种方式。

如果你使用 uv(推荐):

uv add "mcp[cli]"

如果使用 pip

pip install "mcp[cli]"

如果只是最基础的 SDK,也可以直接安装:

pip install mcp

官方目前推荐使用 uv 管理 Python 项目和依赖。 


📖 第三部分:创建项目

建议重新创建一个新的目录。

mcp_demo/

├── server.py
├── pyproject.toml
└── .venv/

以后,

所有官方 SDK 示例,

都放这里。

不要和我们前十课的 mini_mcp 混在一起。

原因很简单:

mini_mcp

↓

学习原理

----------------

mcp_demo

↓

学习 SDK

两个项目承担不同职责。


💻 第四部分:写第一个官方 Server

创建:

server.py

输入:

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()

只有十几行。

是不是感觉非常熟悉?


📖 第五部分:逐行对照我们自己写的代码

第一行:

mcp = FastMCP("Demo")

对应:

我们自己写的:

TOOLS = {}

dispatcher = {}

server = {}

第二行:

@mcp.tool()

对应:

我们自己写的:

@tool

第三行:

mcp.run()

对应:

我们自己写的:

while True:

    request = ...

    dispatch(...)

看到这里,

是不是已经没有任何神秘感了?


💻 第六部分:再增加一个 Tool

继续增加:

@mcp.tool()
def multiply(a: int, b: int) -> int:
    """乘法"""
    return a * b

现在:

Server:

已经拥有:

Tool

├── add
└── multiply

注意:

你没有:

TOOLS["multiply"] = ...

为什么?

因为:

SDK 自动完成了。


💻 第七部分:增加一个 Resource

继续:

@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
    return f"你好,{name}"

你有没有发现?

它和 Tool 非常像。

只是:

以前:

@mcp.tool()

现在:

@mcp.resource(...)

SDK 自动把它放到了:

Resource Registry

这正对应我们第八课讲过的:

TOOLS

RESOURCES

PROMPTS

💻 第八部分:增加一个 Prompt

继续:

@mcp.prompt()
def review(code: str) -> str:
    return f"""
请作为高级 Python 工程师,
帮我审查下面代码:

{code}
"""

现在:

你的 Server:

已经拥有:

Tool

+

Resource

+

Prompt

和官方 Quick Start 已经基本一致。 


📖 第九部分:为什么没有 Schema?

很多同学会问:

以前我们不是写:

inspect.signature()

吗?

现在怎么没有?

因为:

SDK 自动读取:

def add(a: int, b: int):

自动生成:

{
    "type":"object",

    "properties":{

        "a":{

            "type":"integer"

        },

        "b":{

            "type":"integer"

        }

    }

}

也就是说:

Python 的类型注解:

a: int

自动变成:

JSON Schema

所以:

以后一定要认真写:

def weather(city: str):

不要偷懒。

SDK 会利用这些类型生成输入 Schema、进行数据验证。 


📖 第十部分:今天真正理解了一件事

如果今天让你重新实现:

@mcp.tool()

你应该知道:

SDK 内部,

大概就是:

class FastMCP:

    def tool(self):

        def wrapper(func):

            self.tools[func.__name__] = func

            return func

        return wrapper

当然:

真正源码:

远比这个复杂。

但是:

思想完全一致。

所以:

以后:

你看 SDK,

不会觉得:

@mcp.tool()

是魔法。

而会知道:

它只是:

注册一个 Tool。


🧪 本课练习

请完成下面这个官方 Server。

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("My Demo")


@mcp.tool()
def hello(name: str) -> str:
    """打招呼"""
    return f"你好,{name}"


@mcp.tool()
def square(x: int) -> int:
    """平方"""
    return x * x


@mcp.resource("config://app")
def config() -> str:
    return """
host=localhost
port=3306
"""


@mcp.prompt()
def summarize(text: str) -> str:
    return f"""
请总结下面内容:

{text}
"""


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

要求:

你能解释下面每一行代码,对应我们前十课自己实现的哪个模块。

例如:

SDK

对应前十课

FastMCP()

Server + Registry

@mcp.tool()

Tool Registry

@mcp.resource()

Resource Registry

@mcp.prompt()

Prompt Registry

mcp.run()

Server + Dispatcher + Lifecycle

如果你能全部对应出来,

说明:

你已经真正理解 SDK。


🎯 本课总结

今天,我们第一次使用官方 SDK。

但是,

今天真正学到的不是:

怎么写 FastMCP

而是:

为什么 FastMCP 能这么简单。

因为:

它把我们前十课亲手实现的:

  • Registry
  • Dispatcher
  • Lifecycle
  • JSON-RPC
  • Tool Discovery
  • Tool Call
  • Transport

全部封装好了。

所以你现在和大多数初学者最大的区别是:

你不是”会用 SDK”,而是知道 SDK 为什么这么设计


🚀 第十二课预告

下一课,我们将第一次阅读官方 SDK 的设计思路

但不会一上来啃全部源码。

我们会从一个最核心的问题开始:

@mcp.tool() 到底做了哪些事情?

我们会一步一步追踪:

@mcp.tool()
        │
        ▼
Decorator
        │
        ▼
Registry
        │
        ▼
Schema 生成
        │
        ▼
Dispatcher
        │
        ▼
tools/list

到第十二课结束,你将真正具备阅读 MCP SDK 源码的能力,而不是只会调用它的 API。

posted @ 2026-07-31 18:12  zwx901323  阅读(2)  评论(0)    收藏  举报