Model Context Protocol,通常缩写为 MCP,正在迅速成为 AI 应用连接外部系统的一种标准方式。很多人第一次接触它时,会把注意力放在“协议”两个字上,结果越看越抽象。其实只要换一个角度理解,MCP 的核心非常务实:让模型驱动的应用用统一的方法读取外部信息、调用外部能力、执行真实动作。这正是很多 AI 产品从“会聊天”走向“能办事”时必须补上的那一层。

这篇教程不做视频摘要,也不做概念速记,而是直接把你带到可落地的层面:为什么 MCP 会出现、它解决了什么实际问题、服务端和客户端各自负责什么、为什么资源(resources)、工具(tools)、提示模板(prompts)是构建时最先要理解的三类能力,以及怎样用一个最小的 Python 项目把自己的第一个 MCP Server 和 MCP Client 搭起来。读完后,你应该能独立判断:某个需求是不是适合用 MCP 来做,应该把某种能力设计成 resource 还是 tool,本地调试该用标准输入输出还是 HTTP,远程部署时有哪些安全边界必须提前考虑。

为什么单靠大模型还不够

先把一个常见误解拆开。很多人以为“模型足够强”之后,AI 自然就能帮你查询系统、操作网站、预订服务、调用企业内部工具。现实不是这样。

一个普通 LLM 最基础的工作模式是这样的:

  • 用户发送一段输入。
  • 模型生成文本、图像、音频或其他支持的输出。

这适合回答问题、写文案、解释概念、翻译内容,但一旦任务变成“去做一件真实的事”,问题就来了。

比如做一个航班预订助手,用户说:“帮我找下周二从伦敦飞迪拜的便宜航班,比较一下价格和舒适度,再替我订掉。”这时模型本身并不能直接:

  • 登录第三方航司或聚合平台;
  • 读取实时票价;
  • 对比多家返回结果;
  • 记住用户过往偏好;
  • 在拿到足够信息后继续推进流程;
  • 最后真正执行预订动作。

它能做的是“根据已有上下文生成一段看起来合理的话”。但“真实系统动作”不是语言生成的自然延伸,而是要通过外部能力来完成。

这就是 AI Agent 出场的位置。Agent 不等于模型本身,它更像是一个有控制循环的执行层:接收用户目标、决定下一步做什么、何时读取外部数据、何时调用外部工具、何时继续迭代、何时结束任务。过去我们用脚本、自动化编排器、工作流系统来做这类事情;现在 AI Agent 只是把“决策环节”部分交给了模型。

而 MCP 的价值就在于:它给 Agent 和外部能力之间提供了一套统一的接口约定。你不必针对每个 AI 应用都写一套专用集成,也不必让每个模型客户端都直接理解各家五花八门的 API。只要服务端按 MCP 规范暴露能力,客户端按 MCP 规范消费能力,二者就能对接。

用一句人话理解 MCP

把 Model Context Protocol 拆开看会很清楚:

  • Model:模型,或者说由模型驱动的应用。
  • Context:模型完成任务所需的外部上下文与外部能力。
  • Protocol:通信与交互的标准规则。

所以 MCP 不是“新的模型”,也不是“新的 Agent 框架”,而是一套标准化约定:让 AI 应用用一致的方式获取上下文、发现能力、调用能力

这一点特别关键。很多团队在做 AI 工具接入时,最痛苦的不是模型提示词,而是接口碎片化:

  • 这家需要 HTTP;
  • 那家走本地进程;
  • 这边返回 JSON 结构混乱;
  • 那边把错误混在自然语言里;
  • 不同工具的命名、参数、身份认证、状态处理方式都不一样。

MCP 试图解决的正是这种集成层面的混乱。它不保证你的业务逻辑就一定优雅,也不替你完成权限设计,但它提供了一条共同的轨道。对工程团队来说,这比“某个 demo 看起来能跑”重要得多。

先建立正确的架构脑图

很多初学者一上来就记术语,结果只记住了“server”“client”“tool”,却不知道它们在系统里各自扮演什么角色。先建立一个简单架构脑图。

在一个典型 MCP 系统里,至少有三层:

  1. 用户实际使用的宿主应用,比如 IDE 助手、聊天应用、自定义 Python 程序、Agent 运行时。
  2. 宿主应用内部的 MCP Client,负责按协议与外部 MCP Server 通信。
  3. 一个或多个 MCP Server,对外暴露资源、工具、提示模板等能力,并把这些能力翻译成真实的系统行为。

也就是说,客户端不是业务实现层,服务端才是对接外部系统的能力层

MCP Tutorial: Build Your First MCP Server and Client from Scratch (Free Labs) (8:51)

把职责划清后,很多设计问题就容易判断了:

  • 哪些东西应该留在服务端?外部系统集成、工具实现、受控数据读取。
  • 哪些东西应该由客户端负责?连接、能力发现、会话协调、结果展示或进一步编排。
  • 哪些东西属于模型或 Agent 逻辑?任务分解、何时调用什么能力、如何基于返回内容推进下一步。

如果你把这些边界混在一起,后面一定会出现难以调试的问题。例如:工具到底是没注册成功,还是客户端没发现,还是模型根本没选中它?结构清晰时,这些问题是可以逐层定位的。

资源、工具、提示模板:最先要吃透的三类能力

MCP 规范里可以继续深挖很多细节,但第一次上手时,最需要理解的是三个最常见也最实用的概念:resources、tools、prompts

1. Resource:给模型看的“可读取上下文”

Resource 适合暴露那些以“读取”为主、不会产生副作用的信息。它更像是模型可按需获取的上下文来源。

典型例子包括:

  • 机场列表;
  • 产品目录;
  • 公司制度文档;
  • 知识库片段;
  • 静态配置;
  • 某类对象的参考数据。

在航班例子中,机场列表非常适合作为 resource,因为客户端或 Agent 可能需要先读取可信的机场参考数据,再决定如何构造后续查询。

Resource 设计时最容易犯的错是“看似结构化,实际上很脏”。比如把机场编码、城市说明、注释、错误格式、额外描述混在一起。模型不是不能猜,但你不应该把可明确结构化的数据留给模型去猜。Resource 越稳定、越清晰,后续工具调用质量越高。

2. Tool:真正执行动作或查询逻辑的能力

Tool 是大多数人最关心的部分,因为它代表“能做事”。

典型例子包括:

  • 搜索航班;
  • 创建预订;
  • 查询数据库;
  • 创建工单;
  • 调用企业内部审批接口;
  • 读取需要参数的动态查询结果;
  • 对某个对象执行变更。

你可以把 tool 理解为“有输入参数、有执行逻辑、有结构化结果”的操作接口。和普通函数不同,MCP Tool 的设计对象不是单纯的人类开发者,而是“客户端 + 模型 + 后续自动化流程”三方共同消费,因此命名、参数约束、返回结构都要更克制、更清晰。

3. Prompt:可复用的交互指令模板

Prompt 在这里不是泛泛而谈的“提示词工程”,而是服务端对外提供的一种可复用模板能力。它的价值在于把一些容易重复出现的交互流程固定下来。

例如:

  • 预订前应收集哪些缺失字段;
  • 比较多个航班结果时应按哪些标准排序;
  • 执行写操作前是否要求再次确认;
  • 当用户信息不完整时如何向用户追问。

Prompt 不是补锅工具。它不能掩盖糟糕的 tool 设计。但在流程一致性上非常有帮助,尤其适合让不同客户端、不同宿主应用在调用同一个 MCP Server 时维持相近的交互质量。

JSON-RPC 2.0 为什么值得你认真看待

教程里特别提到 MCP 通信基于 JSON-RPC 2.0。这绝不是一个可忽略的小细节,因为它直接决定了客户端与服务端之间的消息组织方式。

与其把每次通信都做成自由发挥的 JSON,不如通过 JSON-RPC 使用统一的结构:

  • method 表示要调用什么方法;
  • params 表示参数;
  • id 用来关联请求和响应;
  • 出错时也有统一错误结构。

这件事在只有一个 demo 时似乎不明显,但当你的客户端需要接多个 MCP Server、或者你的服务端要给多个宿主应用使用时,统一协议带来的收益会非常大。你不用为每个集成对象重新设计一套请求信封,也更容易做日志、诊断、复用和调试。

另一个容易被忽视的点是:连接通常是有状态的。不要想当然地把它理解成每次请求都是完全独立的“无记忆 HTTP 调用”。不同 SDK、不同传输方式下,状态管理和会话行为会影响调试与运行结果。尤其是当客户端需要先发现能力、再持续调用时,会话存在感会比普通 REST API 更强。

本地运行还是远程托管:先选对传输模式

MCP Server 常见有两种运行方式:本地和远程。

本地运行:最适合入门和调试

本地模式通常是由宿主应用直接拉起一个 MCP Server 进程,然后通过标准输入输出(stdio)进行通信。对初学者来说,这是最容易起步的方式,因为:

  • 不需要先搞 HTTP 服务、反向代理、域名和鉴权;
  • 调试链路更短;
  • 本机开发时延迟更低;
  • 适合实验性项目和单人环境。

如果你是在 IDE、代码助手或本地 Agent 工具中接入 MCP,很多时候最先接触到的就是这种模式。

远程托管:适合共享、内网和统一治理

远程模式则是把 MCP Server 部署到组织内部或供应商侧,再由客户端通过 HTTP 连接。它适用于:

  • 多个用户或多个应用要共享同一个能力入口;
  • 服务端必须靠近受保护系统;
  • 凭证不希望散落在每台本地机器上;
  • 需要统一监控、审计、版本管理和访问控制。

但远程模式也带来更现实的问题:

  • 身份认证怎么做;
  • 谁能调用哪些工具;
  • 传给远程服务端的提示与业务数据是否包含敏感信息;
  • 服务端日志保留什么;
  • 写操作是否具备幂等保护或审计追踪;
  • 网络抖动和超时如何处理。

换句话说,本地模式关注“怎么快速跑起来”,远程模式关注“怎么可靠地被别人长期使用”。

在写自己的服务端之前,先会“接入别人写好的服务端”

很多入门者在理解 MCP 时只盯着服务端代码,结果忽略了一个事实:现实中大量场景是“你先作为客户端使用现成的 MCP Server”。这一步理解透了,后面自己做服务端时才知道别人为什么会抱怨你的设计不好用。

常见做法是:在支持 MCP 的 IDE、Agent 工具或桌面应用里配置一个 MCP 服务器条目。

如果是本地服务器,配置通常包括:

  • 启动命令;
  • 启动参数;
  • 必要的环境变量。

如果是远程服务器,配置通常变成:

  • 服务器 URL;
  • 认证信息;
  • 某些情况下的额外请求头或连接选项。

这时你可以记住一个非常实用的判断法:

  • 客户端负责拉起进程时,重点是 command + args。
  • 客户端连接已存在的服务时,重点是 URL + auth。

MCP Tutorial: Build Your First MCP Server and Client from Scratch (Free Labs) (19:19)

初学者最容易误判的一点是:以为“只要连上了,模型就自然会用好这些能力”。实际上要得到稳定结果,需要三层都靠谱:

  • 服务端暴露的能力清晰、命名合理、返回结构稳定;
  • 客户端能正确发现并调用这些能力;
  • 模型或宿主应用有足够明确的指引去选择合适的能力。

任何一层做差,都会让整个系统表现得像“有时会,有时不会”。

搭建你的第一个 Python MCP 项目

第一次实践时,不要把目标设成“做一个完整可生产的 Agent 平台”。更稳妥的方式是做一个极简项目,例如一个“航班预订 MCP 服务端”:

  • 一个 resource:airports,提供机场参考数据;
  • 一个查询类 tool:search_flights
  • 一个写入类 tool:create_booking
  • 一个或两个 prompts,用于指导收集信息与执行预订。

教程材料里使用了 uv 初始化 Python 项目并安装 MCP 相关依赖。一个代表性的流程如下:

# 示例命令
uv init flight-booking-server
cd flight-booking-server
uv add mcp

这里要注意两个工程判断:

第一,这类命令更适合视为“代表性的初始化流程”,不要死背字面。不同版本 SDK、不同实验环境下,命令细节可能变化。你应该抓住的是先建立干净项目,再显式加入 MCP SDK这个动作,而不是某个具体命令文本。

第二,第一次学习时不要把 MCP 直接塞进一个庞大的既有代码库。那会让你无法分辨问题是来自协议集成、依赖版本、业务逻辑,还是老项目本身。最小项目结构越干净,学习效率越高。

一个非常适合练手的目录结构可以只有:

flight-booking-server/
├── pyproject.toml
├── server.py
├── client.py
└── data/

其中 data/ 可以放机场静态数据,方便你把“参考数据”和“执行逻辑”区分开。

在写装饰器之前,先设计能力边界

很多教程演示会直接写 @resource@tool@prompt。实际工程里,最好先做一步设计:先写出你打算暴露的能力清单,以及每个能力的输入输出边界

以航班项目为例,先明确:

  • airports:返回稳定的机场参考数据,不承担搜索逻辑。
  • search_flights(origin, destination, date, preference):根据参数返回标准化的候选航班列表。
  • create_booking(flight_id, passenger_name, email):执行预订,返回预订确认对象或结构化错误。
  • booking_prompt:描述执行预订前如何收集缺失字段、何时要求确认。

这一步看似慢,实际上能避免一个大坑:直接把后端原始函数“硬套”成 MCP 能力。那样通常能跑,但不好用。客户端和模型最怕的是能力表面看起来很多,实际每个都边界模糊、命名随意、输入输出不稳。

好用的 MCP 服务端,能力表面应该尽可能“无惊喜”。别人看到名字就知道它大概做什么,看到参数就知道怎么调用,看到返回结果就知道下一步如何处理。

服务端实现:先从 Resource 开始

在教程演示里,Python 侧会先初始化一个 MCP Server 对象,然后为不同函数加上对应装饰器。不同 SDK 版本的 import 可能略有变化,但整体模式大致一致。

例如会先有这样一个初始化概念:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("flight-booking")

第一步:给机场数据加上 Resource

机场列表是典型的 resource,因为它主要提供只读上下文,而不是执行动作。一个概念性写法会类似这样:

@mcp.resource("file://airports")
def get_airports() -> str:
    return "LHR, London Heathrow\nDXB, Dubai\nSIN, Singapore"

这里最值得关注的不是字面语法,而是三个设计点:

  • 资源标识要清楚,客户端容易发现;
  • 返回内容要稳定、可读、尽量结构化;
  • 资源适合承载被多次读取的参考上下文。

如果你把机场数据写得过于随意,例如混入长篇说明、注释、非标准字段、甚至错误格式,那么后续模型在调用航班搜索工具时就必须额外猜测和纠错。资源不是“能返回点东西就行”,而是后续推理质量的地基。

再加入 Tool:把真正能办事的能力暴露出来

接下来是查询与预订两个核心工具。一个概念化示例可以类似这样:

@mcp.tool()
def search_flights(origin: str, destination: str, date: str, preference: str = "balanced"):
    return {
        "results": [
            {
                "flight_id": "FL-101",
                "airline": "Demo Air",
                "price": 480,
                "duration": "7h 40m",
                "cabin": "economy"
            }
        ]
    }

@mcp.tool()
def create_booking(flight_id: str, passenger_name: str, email: str):
    return {
        "booking_id": "BK-9001",
        "flight_id": flight_id,
        "status": "confirmed",
        "passenger_name": passenger_name,
        "email": email,
    }

这里有几个非常实际的工程决策。

决策一:输入参数要显式

不要让工具去猜用户到底传了什么。像 origindestinationdatepreference 这种字段就应该明确列出。如果某些字段可选,也要能从函数签名或 schema 上看出来。输入边界越清晰,客户端越容易调用,模型越不容易误用。

决策二:输出尽量结构化

很多人第一次做 tool 时喜欢返回一大段自然语言,例如“预订成功啦,你的航班已锁定”。这对终端用户看起来很友好,但对系统编排不友好。更稳妥的做法是返回结构化对象,例如:

  • booking_id
  • status
  • flight_id
  • passenger_name
  • email

这样宿主应用可以自由决定:是直接展示,还是写入日志,还是交给后续流程继续处理。自然语言描述应该由客户端或模型负责生成,而不是让 tool 输出替代结构化数据。

决策三:区分“查”和“改”

search_flights 是查,create_booking 是改。前者即使重复调用问题也不大,后者则具备副作用,必须更谨慎。这种差异应该反映在你的交互设计中,例如:

  • 对写操作增加确认环节;
  • 缺失必填字段时不应“尽量猜”后执行;
  • 返回结果里保留可审计标识;
  • 若未来接入真实系统,还要考虑幂等保护与重放风险。

Prompt 的正确用法:让流程一致,而不是掩盖设计问题

Prompt 适合封装一些重复出现的交互规范。例如:当用户想订票时,应先确认出发地、目的地、日期、预算偏好和乘客信息,再决定是否调用 create_booking。一个概念化示意可类似:

@mcp.prompt()
def booking_prompt() -> str:
    return (
        "When the user asks to book a flight, confirm origin, destination, date, "
        "budget preference, and passenger details before calling create_booking."
    )

它的价值不在于“让模型更聪明”,而在于让不同客户端在同一类场景下采用一致的操作纪律。如果没有这样的提示模板,某个客户端可能在用户信息不全时直接执行写操作,另一个客户端则会先追问确认,行为差异会非常大。

但要警惕一点:Prompt 不能修复差劲的 Tool。参数不清、命名模糊、返回混乱,这些根本问题不是靠多写几句提示词就能补回来的。

客户端怎么写:先发现能力,再调用能力

有了服务端,客户端的职责就容易理解了。它至少要做四件事:

  1. 连接到 MCP Server;
  2. 发现服务端提供了哪些能力;
  3. 读取 resource 或调用 tool;
  4. 把结果展示给用户,或者送回 Agent 循环继续决策。

如果你是在自己的 Python 应用中接入,SDK 往往会帮你处理底层 transport 细节。你更关心的是会话建立与能力调用顺序。一个概念化流程大致可以表示成:

# 仅示意的伪代码
client = connect_to_mcp_server(...)
capabilities = client.list_capabilities()
airports = client.read_resource("file://airports")
flights = client.call_tool("search_flights", {
    "origin": "LHR",
    "destination": "DXB",
    "date": "2026-06-01",
    "preference": "cheap"
})

这里最重要的习惯是:尽量先发现能力,不要到处硬编码假设。

为什么?因为一旦出现问题,你能很快判断:

  • 服务端根本没把这个 tool 注册出来;
  • 客户端配置没连对;
  • 还是模型只是没选中它。

调试时,能力发现是第一道检查线。如果客户端连 airports 都列不出来,就没必要先怀疑模型推理。

配置现成 MCP Server 时最容易踩的坑

哪怕你先不自己写服务端,只是接入现成服务端,也有一些高频配置陷阱。

1. 把本地模式和远程模式配置思路混用

本地模式通常需要:

  • 启动命令;
  • 参数;
  • 环境变量。

远程模式通常需要:

  • URL;
  • 认证;
  • 有时还包括额外请求头。

你不能把“本地启动命令的思维”套在远程地址上,也不能把“远程 URL 的思维”套在本地进程模式上。先分清 transport 再谈配置。

2. 只验证“连上了”,不验证“能发现能力”

看到客户端面板里没有报错,不代表它真的能使用服务端。正确的验证方式是:

  • 能否列出 resources;
  • 能否列出 tools;
  • 能否读取某个简单 resource;
  • 能否成功调用一个无副作用的 tool。

3. 让敏感数据在远程服务器上裸奔

当服务端由第三方托管时,你必须额外审视:

  • 提示词中有没有客户隐私;
  • 工具调用是否包含企业内部标识;
  • 响应数据是否会被记录;
  • 认证 token 如何保存与轮换。

如果这些问题没有答案,先别急着把远程 MCP 接入到真实业务链路里。

一个完整的端到端思路示例

现在把这些概念串起来,看看一个合理的流程应该怎么工作。

假设用户说:“帮我找一张下周二从伦敦到迪拜的便宜机票,用 Priya Nair 的名字订。”

一个设计良好的 MCP 系统,可以按下面顺序执行:

  1. 客户端接收用户请求。
  2. 根据 prompt 或内置流程检查是否缺少必要信息,例如邮箱、确切日期格式、预算偏好。
  3. 如有必要,先读取 airports 资源,把地点标准化成可用机场编码或参考项。
  4. 调用 search_flights,传入结构化参数。
  5. 基于返回结果按“便宜优先”进行筛选或排序。
  6. 如果还缺用户确认,则先确认;如果规则允许自动选择,则选中目标航班。
  7. 在所有必需字段齐全后,调用 create_booking
  8. booking_id、航班信息和状态回给用户。

这才是真正的“模型借助外部能力完成任务”。模型不是在假装知道航班结果,也不是把一堆外部 API 拼成一坨不透明逻辑,而是在标准协议上协调能力、推进流程。

你应该如何验证自己的第一个实现

判断“我的第一个 MCP 项目是不是已经跑通”,不要只看一条 happy path。至少检查以下项目:

  • 服务端能否稳定启动;
  • 客户端能否发现 airports resource;
  • 客户端能否发现 search_flightscreate_booking 两个 tool;
  • resource 读取结果是否格式清晰、可复用;
  • search_flights 返回值是否是稳定的结构化列表;
  • create_booking 在缺字段时是否明确失败,而不是含糊其辞;
  • 成功预订时是否返回固定字段,例如 booking_idstatus
  • 非法输入时是否产生显式错误,便于客户端处理。

如果你使用了实验环境或教学 lab,尽量把 lab 中的每个小任务都视为能力校验点,而不是“答题步骤”。例如:

  • 初始化项目是否成功;
  • MCP 依赖是否安装到正确环境;
  • resource decorator 是否加在正确函数上;
  • tool decorator 是否作用于真正有参数和业务意义的函数;
  • prompt 是否明确了流程要求。

这种逐项验证的习惯,比单纯“能跑出一次结果”更重要。因为你未来做的不是演示,而是要维护、扩展、让别人接入的系统。

真实项目里最重要的几个设计原则

能力命名要表达业务意图

search_flightscreate_booking 这种名字,一眼就知道它干什么。相反,像 processexecuterunTask 这类模糊名称,短期省事,长期非常难维护。MCP 的消费者并不只有写服务端的人,还包括客户端开发者、模型决策层、未来维护者。

Tool 参数越少越好,但不能少到模糊

好的参数设计不是“把一切都塞进去”,也不是“让模型自己猜”。应该是只暴露真正必要的信息,同时保持语义清晰。比如航班搜索需要出发地、目的地、日期、偏好;但未必要把几十个后端内部参数全暴露出来。

返回结构要稳定

你今天返回 price,明天改成 ticket_price,后天又把时长放进一句自然语言里,这会让客户端和上层流程快速失控。MCP 是协议层能力,不应该频繁做随意的输出格式漂移。

把“写操作”当成高风险能力对待

只读 resource 和查询型 tool 风险较低;任何会创建、修改、删除真实状态的 tool 都应该更保守。预订、下单、发消息、改库存这类能力,必须配合确认、权限、日志、失败回滚或最少也要有审计标识。

先让能力边界清楚,再谈复杂 Agent 编排

很多人一上来就想接大型框架、做多轮自主决策、做复杂推理链。其实如果 resource、tool、prompt 三类基础能力都还没设计清楚,再复杂的 Agent 也只是把混乱放大。正确顺序应该是:

  • 先把能力接口做清楚;
  • 再把客户端发现与调用流程跑通;
  • 最后才去扩展复杂 Agent 行为。

最终操作检查清单

在你把第一个 MCP 服务端或客户端交给别人使用之前,至少逐项确认以下内容:

  • 已明确哪些能力属于 resource,哪些属于 tool,哪些属于 prompt。
  • 每个 tool 的参数都有清晰语义,且没有依赖隐式猜测。
  • tool 返回值采用稳定的结构化对象,而不是只返回自然语言。
  • 本地调试优先使用 stdio;需要共享访问时再切换到 HTTP。
  • 客户端已验证 capability discovery,不是只验证“没有报错”。
  • 对写操作加入确认策略,不在信息缺失时盲目执行。
  • 如果连接远程服务端,已评估认证、日志、隐私、权限与信任边界。
  • capability 名称体现业务意图,避免模糊抽象命名。
  • 已测试正常路径、缺字段路径、非法输入路径和失败返回路径。
  • 客户端连接说明完整:本地模式写清 command + args,远程模式写清 URL + auth。
  • 如果某条命令只是示意,文档中已标明“示例命令”,避免读者直接照抄后因版本差异踩坑。
  • 如果 resource 提供参考数据,内容已尽量保持整洁、一致、可预测。

结语:把 MCP 当成“能力边界标准”而不是“又一个 AI 热词”

MCP 真正重要的地方,不是它给 AI 工程又增加了一个新缩写,而是它把“模型应用”和“真实世界能力”之间的边界标准化了。边界一旦标准化,客户端可以复用,服务端可以替换,能力可以被多个宿主消费,调试也能按层次展开。这就是它在工程上的价值。

如果你现在要开始自己的第一个实践,不需要一上来就搞一个庞大的 Agent 平台。最好的起点反而很小:

  • 一个 resource;
  • 两个 tool;
  • 一个 prompt;
  • 一个最小客户端;
  • 一条清楚的本地调试链路。

先把这些东西做得边界明确、返回稳定、调用路径可验证。等你真正理解了“协议、能力、客户端、服务端、状态、信任边界”这些概念之后,再去扩展远程部署、共享接入、复杂工作流和更强的 Agent 编排,速度会快很多,返工也会少很多。

来源说明:本文基于 KodeKloud 发布的教程视频 “MCP Tutorial: Build Your First MCP Server and Client from Scratch (Free Labs)” 整理与重构写成。原始链接:https://www.youtube.com/watch?v=RhTiAOGwbYE