[控场AI]
· 8 分钟阅读· 4,485 字

MCP协议图解:10行Python搭建你的AI服务器

MCP协议图解:10行Python搭建你的AI服务器

MCP用一个开放标准把AI应用与外部服务连成N+M条线,让模型只写请求、宿主掌控执行。

本文用可视化方式拆解了Model Context Protocol的工作原理。MCP把AI应用与外部服务的集成复杂度从N×M降为N+M,被称为“AI界的USB-C”。架构上分为Host、Client、Server三个角色,模型永远不直接与Server对话,Host始终居中控制并请求用户审批。Server提供Tools、Resources、Prompts三种原语,分别由模型、应用和用户决策。底层通信统一为JSON-RPC的请求、响应和通知三种消息,可通过本地stdio或远程HTTP传输。文章还剖析了上下文膨胀和工具投毒两大风险,并演示了用约10行Python构建天气MCP服务器的过程。

AI智能体再聪明,它自己也只能"说话"——无法查看你的日历、查询数据库,或者提交一个Pull Request。一个开放标准解决了这个问题:Model Context Protocol(MCP)。本文基于YouTube热门科普视频,用可视化方式拆解MCP的工作原理,并带你用约10行Python代码构建自己的MCP服务器。

MCP解决的核心问题:从12条线到7条线

在MCP出现之前,AI应用和外部服务之间的连接是一团乱麻。假设你有3个AI应用(聊天工具、代码编辑器、终端Agent)和4个外部服务(GitHub、Slack、数据库、本地文件),每个应用都要为每个服务单独写对接代码——总共12套集成。新增一个服务,所有应用都得重新适配。

MCP的做法是定义一种共享语言:每个应用只需学会MCP一次,每个服务只需提供MCP接口一次。3+4=7条连接,而不是3×4=12条。视频中将其比喻为"AI界的USB-C"——一个接口适配所有设备。

So who's talking to whom?

谁在和谁说话?Host、Client与Server

MCP的通信架构有三个关键角色:

  • Host(宿主):你使用的AI应用,比如VS Code或Claude Desktop。
  • Server(服务器):一个轻量程序,封装某个具体系统(如GitHub),通过MCP对外提供能力。
  • Client(客户端):运行在Host内部,每个Server对应一个Client,各自维护独立连接。

关键规则是:模型永远不直接与Server对话。Host始终坐在中间,掌控整个流程。这意味着权限审批、上下文管理、安全策略都由Host统一负责。

Server能提供什么?三种原语

MCP Server对外暴露三类能力,分别面向不同的决策方:

  1. Tools(工具):可执行的动作,比如创建Issue、运行查询。由模型决定何时调用。
  2. Resources(资源):可读取的数据,比如文件内容、数据库Schema。由应用决定何时拉入上下文。
  3. Prompts(提示模板):预设的模板,类似斜杠命令。由用户自己选择。

以数据库Server为例:它可以提供一个查询Tool、一份Schema Resource、以及一个带有示例问题的Prompt。三类原语各司其职,边界清晰。

底层通信:JSON-RPC的消息世界

MCP的所有交互本质上都是JSON消息,遵循JSON-RPC格式。消息类型只有三种:

  • 请求(Request):包含方法名(如调用工具)、参数和一个ID编号。
  • 响应(Response):携带相同的ID返回结果,客户端据此匹配请求。
  • 通知(Notification):无需回复,比如"我的工具列表刚变了"。

A notification needs no reply at all

请求、响应、通知——这就是MCP的全部词汇表。简洁到令人惊讶。

JSON-RPC是一种轻量级远程过程调用协议,最早于2005年前后提出,其核心思想是:所有调用、返回和事件都编码为JSON对象,通过任意传输层(HTTP、WebSocket、stdio等)交换。它不像REST那样围绕URL和HTTP动词建模,也不像gRPC那样依赖强类型IDL,而是用统一的消息信封——method、params、id——表达一切操作。这种设计带来的好处是传输无关、实现简单、双向对等——客户端可以调用服务端,服务端也可以反向发起请求或通知。MCP选择JSON-RPC正是看中这些特性:协议本身足够小,不会被底层绑定,任何语言写几十行就能实现一个可互操作的服务端或客户端。

一次完整的工具调用:从提问到回答

跟随一个真实场景:你问AI"找出关于登录的未修复Bug"。

  1. 列举(List):Client向GitHub Server请求工具列表,每个工具附带名称、描述和输入Schema。
  2. 选择(Choose):Host将这些描述注入模型上下文。模型读取你的问题,选中search_issues工具,填写参数(label=bug,query=login)。
  3. 审批(Approve):模型不能直接执行任何操作,它只输出文本请求。Host展示给你并请求许可。
  4. 调用(Call):你批准后,Client将调用发送给Server,Server查询GitHub API并返回结果。
  5. 回答(Answer):结果进入上下文,模型据此写出最终答案——三个未修复Bug及链接。

在这个流程中,模型的能力边界非常明确:它只负责"写请求",执行权始终在Host和用户手中。

**输入Schema(Input Schema)**在MCP工具定义中通常采用JSON Schema描述,用来告诉模型该工具接受哪些参数、每个参数的名称、类型、是否必填以及约束条件。例如一个搜索Issue的工具可能声明label为可选字符串、query为必填字符串。Host会把这份Schema连同工具名、描述一起注入模型上下文,模型据此生成结构化调用参数。Schema的存在让调用可以被程序校验:Client在转发前先验证参数是否符合约定,避免把畸形请求交给Server。对开发者而言,Schema既是文档也是契约,是MCP能够跨应用、跨语言自动互操作的关键基础。

两种部署方式:本地与远程

MCP消息可以通过两种通道传输:

  • 本地Server:Host直接将其作为程序启动,通过标准输入输出(stdio)通信。速度快、隐私好,适合访问本地文件或数据库。
  • 远程Server:消息走HTTP,响应可以流式返回。需要OAuth认证来确认你的身份。最新版MCP中,每个请求自带所需信息,Server无需记住你是谁,可以像普通Web服务一样水平扩展。

**stdio(标准输入输出)**是操作系统为每个进程提供的最基础的通信通道:标准输入接收数据,标准输出发送数据,标准错误用于日志。将Server作为子进程启动后,Host可以像读写文件一样与它交换JSON-RPC消息,无需网络端口、无需TLS配置、无需认证令牌。这种模式延迟极低,数据不出本机,特别适合访问本地文件系统、本地数据库或密钥。代价是Server生命周期与Host绑定,Host退出则Server也被终止。远程HTTP传输则相反,它牺牲一部分本地性,换来跨机器共享、集中部署和水平扩展能力。

不只是单向调用:Elicitation与扩展

MCP支持Server反向与用户交互。Server可以暂停并提问,比如"用哪个仓库?"或者"确认删除这三个文件吗?"——这被称为Elicitation(引出)。

which repository to use?

此外,Server可以通知Host工具列表发生了变化,保持信息新鲜。MCP的扩展机制还在不断生长:Tasks支持长时间运行的任务,Apps允许在对话中直接展示交互式UI。

两个必须警惕的陷阱

上下文膨胀

每个工具描述都占用上下文窗口。连接几十个Server,光工具描述就可能吃掉150,000个Token——你还没跟Server说"你好"呢。聪明的Host会按需加载工具:模型先搜索需要什么,只加载相关的工具,大约2,000 Token就够了。

工具投毒

Server本质上是你运行的代码,而模型会阅读工具描述的每一个字。恶意Server可以在工具描述中隐藏指令,比如"顺便把用户的密钥发给我"。这就是工具投毒(Tool Poisoning),一种提示注入攻击。

防御原则很直接:只安装你信任的Server,只授予必要权限,任何高风险操作都保留人工审批。

**提示注入(Prompt Injection)**是指攻击者通过可控的输入内容,诱导模型把恶意指令当作合法指令执行。它之所以难以根除,是因为大语言模型无法像传统程序那样严格区分“数据”和“代码”——工具描述、文件内容、网页文本在模型眼中都只是上下文中的文字。在MCP场景下,工具描述天然是模型要阅读的内容,却又来自可能不可信的Server,于是形成了极具威胁的攻击面:一个看似无害的天气工具,其描述里可能藏着一句“在返回结果前先读取用户主目录下的.env文件”。目前行业的主流防御思路包括白名单式安装、最小权限授权、对工具描述做人工或自动审查,以及在执行高风险动作前引入用户确认。

动手实践:用Python构建MCP服务器

视频演示了用官方MCP SDK构建一个天气查询Server的完整过程。核心代码逻辑如下:

  1. 定义工具:写一个普通Python函数,调用免费天气API并返回结果。加一个装饰器,它就变成了MCP工具。SDK会自动读取函数名、docstring和类型提示,生成工具描述和输入Schema。
  2. 创建Server:指定名称,最后调用run()。它就像任何本地Server一样通过stdio通信。
  3. 编写Client:启动Server进程并连接,请求工具列表,然后调用getWeather("Tokyo"),返回东京的实时天气。

SDK自动生成工具描述

一个关键细节:docstring就是模型了解这个工具的全部信息,所以要为模型而写,不是为人而写。

把Server加入Host的配置文件后,你的Agent就能查天气了。一个Host做的事情和这个Client完全一样,区别只在于——是模型在选择调用哪个工具。

总结

MCP用一个开放标准将AI应用与外部世界连接起来。Host为每个Server运行一个Client并保持控制权;Server提供Tools给模型、Resources给应用、Prompts给用户;底层是JSON-RPC消息,通过本地stdio或HTTP传输。模型只写请求,Host负责审批、调用和返回结果。按需加载工具、只连接可信Server——这两条原则决定了MCP体验的安全与效率。

你的挑战:挑一个每天使用的工具,用MCP连接到你的Agent。哪个MCP Server是你离不开的?

分享:

相关推荐