学习日期:2026年3月1日
学习目标:深入理解MCP协议的核心定义、设计理念、技术架构、实操方法及行业应用,掌握MCP协议在Agent开发中的核心用法,能够独立编写符合MCP规范的工具与服务,理解其在大模型生态中的核心价值与未来发展趋势。
核心关键词:MCP协议、Model Context Protocol、Agent、工具调用、跨进程通信、Stdio、HTTP、MCP Server/Client、SDK、资源注册
参考资料:本地MCP文档、MCP官方SDK文档、行业技术解析文章及开源社区资料
一、MCP协议基础认知:从起源到核心定位
1.1 MCP的起源与背景
在大模型(LLM)快速发展的今天,“LLM + 工具”的组合已成为实现Agent智能化的核心模式——LLM负责逻辑推理、决策规划,工具负责执行具体的操作(如读取文件、执行代码、查询数据、调用第三方服务等),二者结合让大模型从“只能对话”升级为“能够干活”,这也是Agent技术落地的核心“甜头”。
但随着Agent应用场景的复杂化,开发者逐渐面临一个关键问题:如何将本地工具、跨语言工具、第三方工具高效集成到Agent中,同时解决不同工具之间的对接混乱、通信不规范、兼容性差等问题?传统的工具调用方式缺乏统一标准,不同工具的调用格式、通信方式、返回结果差异巨大,导致Agent开发过程中,大量时间被消耗在工具对接、联调上,严重影响开发效率,也限制了Agent能力的规模化扩展。
为解决这一痛点,Anthropic公司在2024年底推出了Model Context Protocol(简称MCP,模型上下文协议),并计划在2025年底将其贡献给开源社区,让更多开发者参与到协议的完善与推广中。此后,MCP协议快速发展,不仅得到了OpenAI、Google、Microsoft等科技巨头的支持,还正式进入Linux基金会旗下新成立的Agentic AI Foundation(AAIF),成为Agent基础设施领域的工业级标准之一。
MCP的核心定位的是:一套标准化的协议规范,用于统一大模型(LLM)与各类工具、资源之间的交互方式,实现工具的标准化开发、跨场景调用、规模化集成,降低Agent开发的复杂度,让开发者能够更专注于核心业务逻辑,同时让大模型的能力得到最大化释放。
形象地说,MCP就像是AI世界的“USB-C接口”,无论是什么类型的工具(本地/远程、不同语言、不同厂商),只要遵循MCP规范,就能无缝对接各类支持MCP的Agent,实现“一次开发,多端复用”,这也是MCP协议最核心的价值所在。
1.2 MCP的核心定义与本质
从字面意义上拆解,MCP由三个核心部分组成:Model(模型)、Context(上下文)、Protocol(协议),三者共同构成了MCP协议的核心逻辑:
- Model(模型):核心是大模型(LLM),负责接收上下文信息、进行逻辑推理、决策是否调用工具,以及处理工具返回的结果,是Agent的“大脑”。
- Context(上下文):包含工具的描述、调用参数、返回结果,以及资源信息、提示模板等,是大模型与工具之间交互的“桥梁”,确保大模型能够理解工具的功能、调用方式,以及工具返回结果的含义。MCP协议中,上下文的核心公式为:context = Tool + Resource + PromptTemplate,即上下文由工具、资源和提示模板三部分组成。
- Protocol(协议):是整套交互规范的核心,定义了工具的注册方式、通信方式、数据格式、调用流程等,确保不同工具、不同Agent之间能够标准化通信,解决对接混乱的问题。
结合参考资料的核心观点,MCP的本质可以概括为:MCP就是标准化的工具与资源交互协议,它不是一个具体的工具或框架,而是一套约定俗成的规范,让所有遵循该规范的工具、服务、Agent能够无缝协作。简单来说,MCP协议的核心目的就是“统一标准、降低复杂度、提升集成效率”。
需要注意的是,MCP与传统的工具调用协议(如OpenAI Function Calling)有本质区别:MCP是一套完整的客户端-服务器通信架构,支持本地进程通信和远程网络调用,且传输层可插拔,协议层保持统一,而传统工具调用协议往往只针对特定场景设计,兼容性和扩展性较差。
1.3 MCP的核心价值与应用场景
1.3.1 核心价值
结合参考资料及行业实践,MCP的核心价值主要体现在以下4个方面:
- 解决工具集成的复杂性:通过标准化的协议规范,统一工具的注册、调用、通信方式,避免不同工具对接时的格式混乱、联调繁琐等问题,大幅降低Agent开发的难度和成本。
- 实现跨场景、跨语言复用:MCP支持跨进程、跨语言、远程调用,开发者开发的符合MCP规范的工具,不仅可以在本地Agent中使用,还可以被远程Agent调用;同时支持Node.js调用Java、Python、Rust等其他语言开发的工具,打破语言壁垒。
- 推动工具生态的规模化发展:大厂可以将自身的服务以MCP的方式向外提供,开发者可以直接集成这些第三方MCP服务,无需重复开发,形成“工具复用、生态共享”的良性循环,甚至有观点认为,未来80%的APP会消失,取而代之的是集成第三方MCP服务的Agent应用。
- 提升Agent的能力边界:通过标准化集成各类工具(本地、远程、第三方),让大模型能够处理更复杂的任务(如复杂数据查询、跨系统操作、实时服务调用等),真正实现“大模型干更强大的任务,工具干具体的执行工作”。
截至2025年底,MCP协议已实现工业级规模应用:全球已有超过10000个公开MCP服务器,被ChatGPT、Cursor、Gemini、Copilot、VS Code等主流工具全面接入,官方SDK覆盖主流语言,月下载量达9700万+,Anthropic内部的Claude更是内置了75+个MCP工具连接器,可在复杂Agent工作流中同时调度成千上万个工具并降低延迟。
1.3.2 典型应用场景
MCP的应用场景主要围绕Agent的工具集成与能力扩展展开,涵盖多个领域,典型场景包括:
- 编程Agent开发:如Cursor、Trae等编程Agent,通过MCP协议集成代码查询、语法检查、调试、运行等工具,实现代码的自动生成、优化与调试,提升编程效率。参考资料中的代码示例,就是为编程Agent开发的用户查询工具,可被Cursor等MCP Client调用。
- 企业级Agent应用:企业通过MCP协议,将内部的数据库、业务系统、第三方服务(如支付、物流、客服)等封装成MCP工具,让Agent能够快速对接企业内部资源,实现业务流程的自动化(如自动查询订单、处理客户诉求、生成业务报表等)。例如华鼎冷链通过MCP让大模型对接温度传感器、库存系统、运输系统,年省9300万成本;辽宁12345通过MCP串联6个大模型智能体,人力成本降低30%。
- 跨语言工具调用:开发者可以用Node.js开发MCP Server,注册Python、Java等语言开发的工具,实现不同语言工具的无缝调用,解决多语言开发中的工具复用问题。
- 远程服务集成:通过HTTP通信方式,Agent可以调用远程的MCP工具,实现跨地域、跨服务器的工具调用,例如远程数据查询、云端服务调用等。
- 多Agent协同:多个Agent通过MCP协议共享工具与资源,实现协同工作,例如一个Agent负责数据采集,一个Agent负责数据处理,一个Agent负责结果输出,三者通过MCP协议实现数据与指令的传递。
二、MCP协议核心技术架构:分层设计与核心组件
MCP协议的核心优势在于其清晰的分层设计和标准化的组件定义,从架构上看,MCP可分为三层(应用层、协议层、传输层),同时包含三大核心组件(MCP Host、MCP Client、MCP Server),各层与组件之间分工明确、协同工作,确保协议的灵活性、可扩展性和兼容性。
2.1 MCP的三层架构设计
MCP采用“三层解耦”设计,将协议语义与通信方式彻底分离,使同一套Agent协议既能跑在本地进程,也能运行在浏览器、微服务乃至实时双向系统中,这也是MCP能够适配多场景的核心原因之一。三层架构具体如下:
2.1.1 上层应用层
应用层是MCP协议的业务核心,包含Agent、Tools(工具)、Resources(资源)、Prompts(提示模板)等业务能力,直接面向开发者和实际应用场景。其中:
- Agent:即智能体,是MCP协议的使用者,负责发起工具调用请求、接收工具返回结果、进行逻辑推理和决策,例如Cursor、Vite等编程Agent都属于MCP应用层的核心载体。
- Tools:工具是应用层的核心执行单元,负责执行具体的操作(如数据查询、文件读写、代码执行等),所有工具都需要遵循MCP规范进行开发和注册,才能被Agent调用。
- Resources:资源是向LLM暴露上下文数据的核心原语,本质是可被读取的背景信息,包括文件内容、数据库记录、API响应、实时系统状态等,通过URI(统一资源定位符)进行唯一标识,供Agent和LLM获取上下文信息。
- Prompts:提示模板,用于定义LLM与工具、资源之间的交互模式,是LLM理解任务需求、调用工具的重要依据,与工具、资源共同构成MCP的上下文。
2.1.2 协议层(Protocol Layer)
协议层是MCP协议的“规则核心”,基于JSON-RPC 2.0构建,负责定义消息的结构、语义和会话状态,不关心底层的通信方式,只专注于“消息如何被理解和处理”。协议层的核心组件是BaseSession,它并非简单封装JSON-RPC,而是解决了Agent场景下的核心通信问题:
- 统一请求(Request)、响应(Response)、通知(Notification)模型,确保Agent与工具之间的交互有统一的格式规范。
- 自动维护请求–响应的ID关联,支持并发调用,避免消息混乱。
- 屏蔽底层读写流差异(如Stdio、HTTP、WebSocket),让上层应用无需感知底层通信细节。
- 提供统一的错误与异常处理机制,确保通信过程中的问题能够被及时识别和处理。
在BaseSession之上,协议层还为客户端和服务端补齐了角色语义:ClientSession(客户端会话)负责主动发起initialize请求、声明自身能力;ServerSession(服务端会话)负责内嵌初始化状态机、校验客户端能力、确保协议执行的安全性与一致性。这种设计使MCP的通信过程具备明确的生命周期和状态约束,避免“随便发消息”导致的通信混乱。
2.1.3 传输层(Transport Layer)
传输层是MCP协议的“通信载体”,负责消息在不同通道中的实际传输,核心特点是“可插拔”——同一套业务代码(工具实现逻辑)可以通过不同的传输方式暴露给不同的客户端,而协议层的JSON-RPC消息格式完全不变。传输层的差异只影响“怎么连”,不影响“怎么用”,极大提升了MCP协议的适配性。
参考资料及行业实践中,MCP支持的核心传输方式主要有以下4种,其中Stdio和HTTP是最常用的两种:
- Stdio(标准输入输出):基于操作系统的进程间通信机制,通过标准输入(STDIN)和标准输出(STDOUT)交换数据,极其轻量,适合本地进程通信,如CLI工具、编辑器插件、本地Agent等场景。其底层依赖操作系统的管道机制,数据传递高效,且无需网络配置,客户端和服务器之间为一对一关系,每条消息以换行字符分隔,格式为JSON-RPC 2.0。
- HTTP(含Streamable HTTP):通过HTTP协议实现远程通信,其中Streamable HTTP是更偏生产级的方案,在同一路径上混合POST与SSE(服务器发送事件),支持会话管理、断线重连和流式响应,适合前后端分离、轻量微服务和远程调用场景。客户端通过HTTP POST请求发送消息,通过SSE接收服务器的实时推送,可实现跨网络远程访问。
- WebSocket:全双工通道,低延迟、高频交互,适合实时Agent与前端嵌入式Copilot场景,一旦握手完成,后续数据帧仅包含 opcode和payload,通信效率高,但认证信息只能在握手时传递一次。
- 其他传输方式:MCP协议支持扩展其他传输方式,以适配不同的部署场景,如TCP、UDP等,开发者可根据实际需求进行自定义扩展。
2.2 MCP的三大核心组件
MCP协议的正常运行,依赖于三大核心组件的协同工作:MCP Host(宿主)、MCP Client(客户端)、MCP Server(服务器),三者的关系的是“Host发起请求,Client提供工具,Server承载工具运行”,具体定义和功能如下:
2.2.1 MCP Host(宿主)
MCP Host是Agent的载体,也是MCP协议的发起者,核心功能是:管理MCP配置文件(SDD)、发起工具调用请求、接收并处理MCP Server返回的结果,然后将结果传递给LLM进行后续推理。
参考资料中提到的Cursor、Vite等编程Agent,都是典型的MCP Host。Host的核心工作流程包括:读取MCP配置文件,明确需要调用的工具;向MCP Server发送initialize请求,获取工具列表和详情;根据用户任务(prompt),检索配置文件,确定需要调用的Client工具和通信方式;接收Server返回的工具执行结果,传递给LLM生成最终响应。
简单来说,MCP Host就像是“指挥官”,负责统筹规划任务,决定调用哪些工具、如何调用,以及如何处理工具返回的结果。
2.2.2 MCP Client(客户端)
MCP Client是符合MCP规范的工具载体,核心功能是:实现工具的具体逻辑,注册到MCP Server中,接收MCP Host的调用请求,执行具体操作并返回结果。
需要注意的是,MCP Client并非独立的应用,而是嵌入在MCP Server中的工具实例——任何工具只要遵循MCP规范,实现对应的接口,就能成为MCP Client,被MCP Host调用。例如参考资料中编写的“query-user”工具,就是一个MCP Client,它实现了用户查询的核心逻辑,注册到MCP Server后,可被Cursor等Host调用。
MCP Client的核心特征:必须遵循MCP协议的工具注册规范,包含工具描述、输入参数校验、执行逻辑、返回结果格式等;支持多种通信方式(Stdio、HTTP等),可根据Host的需求调整;可以是本地工具、跨语言工具,也可以是远程工具。
2.2.3 MCP Server(服务器)
MCP Server是工具的“运行容器”,核心功能是:承载MCP Client(工具)的运行,接收MCP Host的调用请求,将请求转发给对应的Client,接收Client的执行结果,再返回给Host。
MCP Server的核心作用是“中间枢纽”,连接Host和Client,解决二者之间的通信与调度问题。开发者需要通过MCP SDK提供的McpServer类,创建Server实例,然后将工具(Client)注册到Server中,配置通信方式(如Stdio、HTTP),才能实现工具的调用。
参考资料中的“my-mcp-server”就是一个典型的MCP Server实例,它注册了“query-user”工具和“使用指南”资源,通过Stdio传输方式,接收Host的调用请求,执行用户查询操作并返回结果。MCP Server的核心优势在于:支持多Client注册,一个Server可以承载多个不同功能的工具;支持多种传输方式,可根据场景灵活配置;能够统一管理工具的生命周期,确保工具的稳定运行。
2.3 三大组件的协同工作流程
结合参考资料的描述,MCP三大组件的完整工作流程可分为7个步骤,清晰展现了协议的运行机制:
- MCP Host初始化:Host加载自身的配置文件(SDD),明确需要调用的MCP Server和工具信息。
- 发起初始化请求:Host向MCP Server发送initialize请求,用于获取Server中注册的工具列表和详情(如工具描述、输入参数、通信方式等)。
- Server响应初始化请求:MCP Server接收请求后,返回自身注册的所有工具的详细信息,供Host选择。
- Host发起任务与工具调用:Host根据用户的任务需求(prompt),检索配置文件,确定需要调用的工具,然后通过对应的通信方式(如Stdio、HTTP),向MCP Server发送工具调用请求,携带工具所需的输入参数。
- Server调度Client执行任务:MCP Server接收调用请求后,将请求转发给对应的MCP Client(工具),Client执行具体的操作(如参考资料中的用户查询)。
- Client返回执行结果:Client执行完成后,将结果按照MCP规范的格式返回给MCP Server,Server再将结果转发给MCP Host。
- Host处理结果并反馈:Host接收结果后,将其传递给LLM,LLM结合上下文进行推理,生成最终的响应,反馈给用户。
这一流程确保了MCP协议的标准化、规范化运行,每一步都有明确的规则约束,避免了工具调用过程中的混乱,同时支持并发调用、断线重连等场景,提升了协议的稳定性和可靠性。
三、MCP协议核心知识点详解:工具、资源与通信
在MCP协议的学习中,工具(Tool)、资源(Resource)和通信方式是三大核心知识点,也是开发者实际开发中最常接触的内容。本节将结合参考资料中的代码示例,详细拆解这三个知识点的核心内容、开发规范和注意事项。
3.1 MCP Tool(工具):核心执行单元
Tool是MCP协议中最核心的执行单元,也是Agent能力的核心体现——所有Agent能够完成的具体操作,都依赖于Tool的实现。参考资料中明确提到:“MCP其实就是tool”,这里的“tool”并非指单一的工具,而是指遵循MCP规范的所有工具的集合。
3.1.1 Tool的核心特征
符合MCP规范的Tool,必须具备以下4个核心特征,这也是区别于普通工具的关键:
- 标准化描述:必须包含清晰的工具描述(description),说明工具的功能、用途、输入输出格式,让LLM和Host能够理解工具的作用。例如参考资料中“query-user”工具的描述:“查询数据库中的用户信息。输入用户ID,返回该用户的详细信息(姓名、邮箱、角色)。”
- 标准化输入校验:必须定义输入参数的校验规则(inputSchema),确保Host传递的参数符合工具的要求,避免因参数错误导致工具执行失败。参考资料中使用zod库定义了userId的校验规则:z.string().describe("用户ID,例如:001,002,003"),确保输入的是字符串类型,且明确了参数示例。
- 标准化返回格式:工具执行完成后,必须按照MCP规范的格式返回结果,通常包含content数组,数组中包含type(如text)和text(具体结果)两个字段,确保Host和LLM能够正确解析结果。
- 支持MCP注册:必须通过MCP Server的registerTool方法注册到Server中,才能被Host调用,注册时需要指定工具名称、描述、输入校验规则和执行逻辑。
3.1.2 Tool的分类
根据使用场景和实现方式,MCP Tool可分为以下4类,与参考资料中的描述高度对应:
- 本地工具:运行在本地进程中的工具,通过Stdio通信方式与Host交互,如参考资料中的“query-user”工具,依赖本地数据库,通过Stdio传输方式接收调用请求。
- 跨语言工具:由不同语言开发的工具,如Java、Python、Rust开发的工具,通过MCP协议,可被Node.js开发的Host或Server调用,打破语言壁垒。
- 第三方工具:大厂或第三方开发者提供的标准化工具,以MCP服务的形式向外提供,开发者可直接集成,无需重复开发,例如AWS、Google Cloud提供的企业级MCP工具服务。
- 远程工具:运行在远程服务器中的工具,通过HTTP等远程通信方式与Host交互,实现跨地域、跨服务器的工具调用,适合需要访问远程资源的场景。
3.1.3 Tool的开发规范(结合参考资料代码示例)
结合参考资料中的“query-user”工具代码,我们可以总结出MCP Tool的标准开发流程和规范,分为5个步骤,每一步都有明确的要求:
- 引入依赖:首先需要引入MCP SDK相关模块(如McpServer)、通信模块(如StdioServerTransport)、参数校验模块(如zod),这是开发MCP Tool的基础。参考资料中的依赖引入代码:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" `` import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" ``import { z } from "zod" - 创建MCP Server实例:Tool必须运行在MCP Server中,因此需要先创建Server实例,指定Server的名称和版本,用于标识Server的身份。参考资料中的代码:
const server = new McpServer({ `` name: "my-mcp-server", `` version: "1.0.0", ``}) - 定义工具执行逻辑:实现工具的核心功能,如参考资料中的数据库查询逻辑,定义一个包含用户数据的database对象,然后实现根据userId查询用户信息的逻辑,处理“用户不存在”的异常情况。
- 注册工具到Server:通过server.registerTool方法注册工具,参数包括工具名称、工具配置(描述、输入校验规则)、执行函数。参考资料中的注册代码:
server.registerTool("query-user",{ `` description: "查询数据库中的用户信息。输入用户ID,返回该用户的详细信息(姓名、邮箱、角色)。", `` inputSchema: { `` userId: z.string().describe("用户ID,例如:001,002,003"), `` } `` }, async ({ userId }) => { `` const user = database.users[userId] `` if (!user) { `` return { `` content: [ `` { `` type: "text", ``` text:用户ID {userId} 不存在` ``` } `` ] `` } `` }else { `` return { `` content: [ `` { `` type: 'text', ``` text: `用户信息:\n- ID: {user.id}\n- 姓名: {user.email}\n- 角色: ${user.role}``` } `` ] `` } `` } ``})注意:执行函数必须是异步函数(async),返回结果必须符合MCP规范的content格式,否则Host无法解析。 - 配置通信方式并启动Server:选择对应的传输方式(如Stdio),创建传输实例,通过server.connect(transport)启动Server,等待Host的调用请求。参考资料中的代码:
const transport = new StdioServerTransport(); ``await server.connect(transport);
此外,开发Tool时还需要注意:工具名称必须唯一,避免与其他工具冲突;输入校验规则要尽可能详细,明确参数类型、示例和约束;异常处理要完善,避免工具执行失败导致Server崩溃;返回结果要简洁明了,便于LLM理解和处理。
3.2 MCP Resource(资源):上下文支撑单元
Resource(资源)是MCP协议中不可或缺的上下文支撑单元,参考资料中提到:“context = Tool + Resource + PromptTemplate”,可见资源是构成上下文的重要组成部分,其核心作用是为LLM提供背景信息,帮助LLM更好地理解任务需求和工具功能,避免因信息不足导致工具调用错误。
3.2.1 Resource的核心定义与特征
MCP中的Resource,本质是可被LLM和Host读取的背景数据,核心特征包括:
- 唯一标识:每个资源都通过URI(统一资源定位符)进行唯一标识,如参考资料中的“docs://guide”,通过这个URI可以定位到“使用指南”资源,方便Host和LLM获取资源内容。
- 标准化描述:资源需要包含清晰的描述(description),说明资源的用途、内容和使用方式,让LLM能够理解资源的价值。参考资料中“使用指南”资源的描述:“MCP Server 使用文档”。
- 多种类型:资源可以是文本、文件、数据库记录、API响应等多种类型,参考资料中的资源是文本类型(mimeType: 'text/plain'),用于提供MCP Server的使用指南。
- 可注册性:资源需要通过MCP Server的registerResource方法注册到Server中,才能被Host和LLM获取,注册时需要指定资源名称、URI、描述、类型和获取逻辑。
根据资源内容的灵活性,Resource可分为静态资源和动态资源:静态资源的URI和内容固定,如参考资料中的“使用指南”;动态资源的内容随参数变化,通过URI Template(RFC 6570)定义,如“logs://recent?timeframe={duration}”,客户端只需填充参数即可获取对应的资源内容。
3.2.2 Resource的开发与注册(结合参考资料代码示例)
结合参考资料中“使用指南”资源的代码,MCP Resource的开发与注册流程分为3个步骤,与Tool的注册流程类似,但参数和逻辑有所不同:
- 定义资源获取逻辑:实现资源的核心内容,如参考资料中“使用指南”的文本内容,明确资源的功能和使用方式,供LLM和Host读取。
- 注册资源到Server:通过server.registerResource方法注册资源,参数包括资源名称、URI、资源配置(描述、类型)、获取函数。参考资料中的注册代码:
server.registerResource('使用指南', 'docs://guide', { `` description: 'MCP Server 使用文档', `` mimeType: 'text/plain', `` }, async () => { `` return { `` contents: [ `` { `` uri: 'docs://guide', `` mimeType: 'text/plain', ``` text:MCP Server 使用指南功能:提供用户查询等工具。使用:在 Cursor 等 MCP Client 中通过自然语言对话,Cursor 会自动调用相应工具。, ``` } `` ] `` } ``})注意:获取函数必须是异步函数,返回结果包含contents数组,数组中包含URI、mimeType和text三个字段,与Tool的返回格式有所区别。 - 启动Server后,资源即可被Host和LLM获取:Host通过URI定位资源,发送获取请求,Server调用资源的获取函数,返回资源内容,供LLM作为上下文使用。
开发Resource时需要注意:URI必须唯一,避免与其他资源冲突;资源内容要准确、简洁,能够为LLM提供有效的上下文支撑;mimeType要正确设置,匹配资源的类型(如文本、JSON、图片等);获取逻辑要高效,避免因资源获取缓慢影响Agent的响应速度。
3.3 MCP通信方式:连接Host与Server的桥梁
MCP协议的核心优势之一是支持多种通信方式,能够适配不同的应用场景(本地/远程、轻量/生产级),参考资料中重点介绍了Stdio和HTTP两种通信方式,结合行业实践,本节将详细拆解这两种核心通信方式的原理、用法和适用场景。
3.3.1 Stdio通信方式(本地进程通信)
Stdio(标准输入输出)是MCP协议中最基础、最常用的通信方式,主要用于本地进程之间的通信,如本地Agent(Cursor)调用本地MCP Server中的工具。
核心原理
Stdio通信基于操作系统的进程间通信(IPC)机制,通过管道(pipe)实现Host和Server之间的数据传递:Host作为父进程,创建子进程(MCP Server),操作系统自动创建三个匿名管道,连接父子进程,Host通过STDIN向Server发送请求消息,Server通过STDOUT向Host返回响应消息,每条消息以换行字符分隔,格式为JSON-RPC 2.0。
Stdio通信的底层优化:采用写时复制(Copy-on-Write)技术,减少内存占用;通过内核直接操作虚拟内存页表,实现零拷贝(部分现代内核支持splice()系统调用),提升数据传递效率;操作系统会优先调度正在等待数据的进程,减少上下文切换带来的延迟。
适用场景
Stdio通信适合以下场景:
- 本地Agent开发:如Cursor、VS Code插件等,调用本地工具,无需网络配置,通信效率高。
- 轻量级工具调用:工具逻辑简单、数据传递量小,不需要远程访问,如本地文件读写、简单数据查询。
- CLI工具集成:命令行工具中的Agent,通过Stdio调用本地MCP工具,实现命令行的智能化。
使用方法(结合参考资料代码)
参考资料中,MCP Server采用Stdio通信方式,核心代码如下:
// 引入Stdio传输模块
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
// 创建Stdio传输实例
const transport = new StdioServerTransport();
// 连接传输方式,启动Server
await server.connect(transport);
使用Stdio通信时,无需配置IP、端口等网络参数,只需创建StdioServerTransport实例,调用server.connect(transport)即可,操作简单、轻量。
3.3.2 HTTP通信方式(远程通信)
HTTP通信方式主要用于远程调用,即Host和Server运行在不同的进程、不同的服务器上,通过HTTP协议实现数据传递,参考资料中提到“HTTP 远程调用”,是MCP协议实现远程工具集成的核心方式。
核心原理
HTTP通信基于HTTP/HTTPS协议,采用“请求-响应”模式,Host作为客户端,向MCP Server的HTTP接口发送请求(如POST请求),携带工具调用参数;Server接收请求后,调度对应的工具执行,然后通过HTTP响应将结果返回给Host。对于需要实时推送的场景,可结合SSE(服务器发送事件),实现Server向Host的实时消息推送,形成双向通信。
MCP的HTTP通信支持两种模式:普通HTTP请求(适合简单的工具调用)和Streamable HTTP(适合生产级场景),Streamable HTTP在同一路径上混合POST与SSE,支持会话管理、断线重连和流式响应,提升通信的稳定性和效率。
适用场景
HTTP通信适合以下场景:
- 远程工具调用:Host和Server运行在不同的服务器上,如云端Agent调用本地服务器的工具,或本地Agent调用云端的第三方MCP服务。
- 多Agent协同:多个Agent分布在不同的节点,通过HTTP通信调用同一个远程MCP Server中的工具,实现协同工作。
- 生产级应用:需要高可用性、可扩展性的场景,如企业级Agent,通过HTTP通信调用分布式的MCP工具,确保服务的稳定性。
使用方法(补充说明)
参考资料中未提供HTTP通信的完整代码,结合MCP SDK的官方文档,HTTP通信的核心步骤如下:
- 引入HTTP传输模块:从MCP SDK中引入HttpServerTransport模块(不同语言的SDK名称可能略有差异)。
- 创建HTTP传输实例:指定Server的IP地址和端口,如:
import { HttpServerTransport } from "@modelcontextprotocol/sdk/server/http.js" `` const transport = new HttpServerTransport({ `` host: "0.0.0.0", `` port: 3000 ``}); - 连接传输方式并启动Server:
await server.connect(transport); - Host调用远程工具:Host通过HTTP POST请求,向http://ip:port/mcp/tools/call接口发送调用请求,携带工具名称和输入参数,Server接收请求后执行工具,返回响应结果。
3.3.3 两种通信方式的对比
为了方便开发者选择合适的通信方式,结合参考资料和行业实践,对Stdio和HTTP两种核心通信方式进行对比:
| 对比维度 | Stdio通信 | HTTP通信 |
|---|---|---|
| 通信范围 | 本地进程之间 | 本地/远程均可,支持跨服务器 |
| 配置复杂度 | 无需配置IP、端口,操作简单 | 需要配置IP、端口,涉及网络权限设置 |
| 通信效率 | 高,基于本地管道,延迟低 | 中等,受网络带宽、延迟影响 |
| 适用场景 | 本地Agent、轻量级工具调用、CLI工具 | 远程工具调用、多Agent协同、生产级应用 |
| 可靠性 | 高,无网络依赖,不易中断 | 受网络影响,可能出现断线、延迟等问题 |
四、MCP协议实操实战:从环境搭建到工具开发
理论学习的最终目的是落地实践,本节将结合参考资料中的代码示例,从环境搭建、依赖安装、Server创建、Tool/Resource开发、测试调用等环节,完整演示MCP工具的开发流程,帮助开发者快速上手MCP协议的实操开发。
4.1 实操准备:环境搭建与依赖安装
4.1.1 环境要求
开发MCP工具需要满足以下环境要求,参考MCP SDK的官方要求:
- Node.js环境:推荐版本16.x及以上(MCP SDK主要支持Node.js,其他语言可参考对应SDK)。
- 包管理工具:npm或yarn,用于安装MCP SDK及相关依赖。
- 代码编辑器:推荐VS Code、WebStorm等,支持JavaScript/TypeScript开发。
- 测试工具:Cursor(MCP Client)、Postman(HTTP通信测试)、命令行(Stdio通信测试)。
4.1.2 依赖安装
MCP工具开发的核心依赖是MCP SDK和参数校验工具zod,参考资料中的代码使用了@modelcontextprotocol/sdk和zod,安装命令如下:
# 初始化项目(若未初始化)
npm init -y
# 安装MCP SDK
npm install @modelcontextprotocol/sdk
# 安装参数校验工具zod
npm install zod
注意:MCP SDK的版本可能会不断更新,安装时可指定最新版本,或参考官方文档选择合适的版本。此外,若需要使用HTTP通信方式,还需安装对应的HTTP传输模块(通常包含在MCP SDK中,无需额外安装)。
4.2 实操步骤:开发一个完整的MCP工具(基于参考资料示例)
本次实操将基于参考资料中的“query-user”工具,完整开发一个能够查询用户信息的MCP工具,包含Server创建、Tool注册、Resource注册、通信配置、测试调用等环节,步骤如下:
4.2.1 步骤1:创建项目目录与文件
创建一个名为“my-mcp-demo”的项目目录,在目录中创建一个名为“my-mcp-server.mjs”的文件(使用.mjs后缀,支持ES6模块导入),作为MCP Server的入口文件。
# 创建项目目录
mkdir my-mcp-demo
cd my-mcp-demo
# 创建入口文件
touch my-mcp-server.mjs
4.2.2 步骤2:引入核心依赖
在my-mcp-server.mjs文件中,引入MCP SDK的McpServer、StdioServerTransport,以及zod工具,代码如下:
// 引入MCP Server核心模块
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// 引入Stdio传输模块(本地通信)
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// 引入参数校验工具zod
import { z } from "zod";
4.2.3 步骤3:定义工具所需的数据资源
参考资料中,“query-user”工具需要查询用户数据,因此定义一个包含用户信息的database对象,模拟数据库数据,代码如下:
// 模拟用户数据库,存储用户信息
const database = {
users: {
"001": { id: "001", name: "张三", email: "zhangsan@example.com", role: "admin" },
"002": { id: "002", name: "李四", email: "lisi@example.com", role: "user" },
"003": { id: "003", name: "王五", email: "wangwu@example.com", role: "user" },
}
};
4.2.4 步骤4:创建MCP Server实例
创建McpServer实例,指定Server的名称和版本,用于标识Server的身份,代码如下:
// 创建MCP Server实例
const server = new McpServer({
name: "my-mcp-server", // Server名称,自定义
version: "1.0.0", // Server版本,自定义
});
4.2.5 步骤5:注册MCP Tool(用户查询工具)
通过server.registerTool方法,注册“query-user”工具,定义工具描述、输入校验规则和执行逻辑,代码如下(与参考资料一致):
// 注册用户查询工具
server.registerTool("query-user",
{
description: "查询数据库中的用户信息。输入用户ID,返回该用户的详细信息(姓名、邮箱、角色)。",
inputSchema: {
userId: z.string().describe("用户ID,例如:001,002,003"), // 输入参数校验
}
},
async ({ userId }) => {
// 工具执行逻辑:根据userId查询数据库
const user = database.users[userId];
if (!user) {
// 处理用户不存在的情况,返回标准化结果
return {
content: [
{
type: "text",
text: `用户ID ${userId} 不存在`
}
]
};
} else {
// 处理用户存在的情况,返回用户详细信息
return {
content: [
{
type: 'text',
text: `用户信息:\n- ID: ${user.id}\n- 姓名: ${user.name}\n- 邮箱: ${user.email}\n- 角色: ${user.role}`
}
]
};
}
}
);
4.2.6 步骤6:注册MCP Resource(使用指南)
通过server.registerResource方法,注册“使用指南”资源,为LLM提供工具的使用说明,代码如下(与参考资料一致):
// 注册资源:MCP Server 使用指南
server.registerResource(
'使用指南', // 资源名称
'docs://guide', // 资源URI,唯一标识
{
description: 'MCP Server 使用文档', // 资源描述
mimeType: 'text/plain', // 资源类型,文本类型
},
async () => {
// 资源获取逻辑,返回资源内容
return {
contents: [
{
uri: 'docs://guide',
mimeType: 'text/plain',
text: `MCP Server 使用指南
功能:提供用户查询等工具。
使用:在 Cursor 等 MCP Client 中通过自然语言对话,Cursor 会自动调用相应工具。`,
}
]
};
}
);
4.2.7 步骤7:配置通信方式并启动Server
4.2.7 步骤7:配置通信方式并启动Server
选择Stdio通信方式,创建StdioServerTransport实例,连接传输方式并启动Server,代码如下:
// 配置Stdio通信方式
const transport = new StdioServerTransport();
// 连接传输方式并启动Server,等待Host调用
await server.connect(transport);
// 打印启动成功提示,便于开发者确认服务状态
console.log("MCP Server 启动成功(Stdio通信),可通过Cursor等MCP Client调用工具");
4.3 实操测试:验证工具可用性
工具开发完成后,可通过以下两种方式测试其可用性,确保工具能够正常被调用并返回结果:
- Stdio本地测试:在命令行中运行MCP Server(node my-mcp-server.mjs),启动成功后,打开Cursor等支持MCP的Client,输入自然语言指令(如“查询用户ID为001的信息”),Client会自动调用“query-user”工具,返回用户详细信息,验证工具执行逻辑是否正常。
- 异常场景测试:输入不存在的用户ID(如“004”),验证工具的异常处理逻辑是否生效,确保能够返回“用户ID不存在”的标准化提示,避免Server崩溃。
4.4 实操注意事项
-
确保Node.js版本符合要求(16.x及以上),否则可能出现SDK导入失败、语法报错等问题;
-
工具名称和资源URI必须唯一,避免重复注册导致冲突;
-
代码中所有异步函数(工具执行函数、资源获取函数)必须使用async/await语法,确保执行顺序正确;
-
测试时需先启动MCP Server,再启动Client,否则会出现连接失败的问题。
五、学习总结与未来展望
通过本次学习,我系统掌握了MCP协议的核心定义、三层架构、三大组件及实操方法,明确其作为Agent工具集成标准化协议的核心价值,能够独立开发简单的MCP工具与服务。
后续将重点学习MCP高级特性,结合复杂业务场景深化实操能力,关注协议更新动态,将所学知识运用到实际项目中,适配大模型与Agent技术的发展趋势。