MCP入门教程:模型上下文协议架构与三大原语详解

MCP是Anthropic推出的标准化协议,解决AI模型与外部工具的集成问题
MCP(模型上下文协议)是Anthropic发布的通信层协议,通过标准化AI模型与外部工具之间的交互,解决了传统开发中N×M集成问题。其架构由客户端和服务器组成,定义了工具(模型控制)、资源(应用控制)、提示词(用户控制)三大原语,将工具定义和执行的负担从应用开发者转移到MCP服务器,大幅降低集成成本。
什么是MCP?它解决了什么问题
MCP(Model Context Protocol,模型上下文协议)是Anthropic推出的一个通信层协议,旨在为Claude等大语言模型提供上下文和工具访问能力,而无需开发者编写大量繁琐的集成代码。

在MCP出现之前,AI应用开发领域面临严重的"N×M集成问题":如果有N个AI应用和M个外部服务,理论上需要N×M个独立的集成实现。这类似于USB协议出现前,每种外设都需要专用接口的困境。Anthropic于2024年11月正式发布MCP规范,其设计哲学借鉴了LSP(Language Server Protocol)的成功经验——LSP通过标准化编辑器与语言工具之间的通信,使得任何编辑器都能支持任何编程语言的智能补全,而MCP则试图在AI模型与外部工具之间建立类似的标准化层。
在传统开发模式中,如果我们想构建一个能与GitHub交互的聊天机器人,需要自己编写所有工具的Schema定义、函数实现,并负责测试和维护。GitHub拥有仓库、Pull Request、Issues、Projects等大量功能,要完整覆盖这些功能意味着巨大的开发负担。
MCP的核心价值在于:将定义和运行工具的负担从你的服务器转移到MCP服务器上。你不再需要自己编写工具函数和工具模式,这些由MCP服务器的实现者完成。例如,一个GitHub MCP服务器会将GitHub的各种功能封装为一组工具,供任何客户端直接使用。
关于MCP的三个常见问题
谁来编写MCP服务器? 任何人都可以。通常服务提供商会发布官方实现,比如AWS可能发布自己的官方MCP服务器。社区也在积极贡献开源实现,目前已有数百个MCP服务器覆盖了从数据库、云服务到本地文件系统等各种场景。
MCP与直接调用API有什么区别? 直接调用API需要你自己编写工具Schema和函数实现;使用MCP服务器则省去了这些工作,工具的定义和执行逻辑都由服务器端封装好了。更重要的是,MCP提供了标准化的发现机制——客户端可以动态查询服务器支持哪些工具,而不需要硬编码集成逻辑。
MCP和工具使用(Tool Use)是一回事吗? 不是。它们是互补的关系。Tool Use(也称Function Calling)是大语言模型的一种能力,指模型能够在对话中决定调用外部函数并处理返回结果。MCP解决的是"谁来做实际工作"的问题——工具的定义和执行由MCP服务器负责,而非应用开发者。换言之,Tool Use是模型侧的能力,MCP是基础设施层的协议。
MCP架构:客户端与服务器如何协作
客户端的角色
MCP客户端的目的是在你的应用服务器和MCP服务器之间提供通信手段。它是访问MCP服务器所有工具的入口点。
MCP是传输无关的(transport-agnostic),客户端和服务器可以通过多种协议通信:
- 标准输入输出(stdio):当客户端和服务器在同一台机器上时使用
- HTTP/WebSocket:用于远程连接场景
传输无关性是一种协议设计原则,意味着上层协议不依赖于特定的底层通信方式。MCP采用JSON-RPC 2.0作为消息格式标准,这是一种轻量级的远程过程调用协议,使用JSON编码请求和响应。stdio传输适用于本地进程间通信,客户端直接通过子进程的标准输入输出流交换消息,延迟极低但仅限同机部署。而HTTP+SSE(Server-Sent Events)传输则支持远程部署场景,客户端通过HTTP POST发送请求,服务器通过SSE流式推送响应,这使得MCP服务器可以作为独立的云服务运行。
消息交换机制
客户端和服务器之间通过交换消息进行通信,关键消息类型包括:
list_tools_request/list_tools_result:获取服务器提供的工具列表call_tool_request/call_tool_result:请求执行特定工具并返回结果
这些消息遵循JSON-RPC 2.0规范,每个请求包含方法名(method)、参数(params)和唯一标识符(id),响应则包含对应的结果或错误信息。这种请求-响应模式确保了通信的可靠性和可追踪性。
完整调用流程
以用户询问"我有什么仓库"为例,完整流程如下:
- 用户提交查询到应用服务器
- 服务器通过MCP客户端向MCP服务器发送
list_tools_request - MCP服务器返回工具列表(包含每个工具的名称、描述和参数Schema)
- 服务器将用户查询和工具列表一起发送给Claude
- Claude决定使用某个工具,返回tool_use消息(包含工具名和参数)
- 服务器通过MCP客户端发送
call_tool_request到MCP服务器 - MCP服务器执行工具(如调用GitHub API),返回结果
- 结果通过客户端传回服务器,再作为tool_result发送给Claude
- Claude生成最终回复返回给用户
值得注意的是,步骤5中Claude的决策完全基于工具描述和用户意图的语义匹配——这就是为什么工具的description字段如此重要,它直接影响模型是否能正确选择和使用工具。
三大服务器原语(Primitives)详解
工具(Tools)——由模型控制
工具是MCP服务器最核心的组件,由模型(Claude)决定何时调用。使用MCP Python SDK定义工具非常简洁:
@mcp.tool(name="read_contents", description="读取文档内容并作为字符串返回")
def read_document(doc_id: str = Field(description="文档ID")):
if doc_id not in docs:
raise ValueError(f"Doc with id {doc_id} not found")
return docs[doc_id]
相比手动编写JSON Schema,SDK会自动根据装饰器和Field类型生成工具模式,大幅降低开发复杂度。JSON Schema是一种用于描述JSON数据结构的规范,在AI工具调用场景中,模型需要通过JSON Schema理解每个工具接受什么参数、参数类型是什么、哪些是必填的。传统方式下,开发者需要手动编写这些Schema定义,例如OpenAI的Function Calling要求开发者提供完整的JSON Schema对象。MCP Python SDK利用Python的类型注解(Type Hints)和Pydantic的Field描述符,通过反射机制自动生成符合规范的JSON Schema,这种方式不仅减少了样板代码,还避免了Schema定义与实际函数签名不一致的问题。
课程中实现了两个工具:read_contents用于读取文档,edit_document用于查找替换文档内容。
资源(Resources)——由应用控制
资源允许MCP服务器向客户端暴露数据,由应用代码决定何时获取。资源分为两种类型:
- 直接资源(静态):固定URI,如
docs://documents,返回所有文档列表 - 模板化资源:URI中包含参数,如
docs://documents/{doc_id},根据参数返回特定内容
MCP资源的URI设计借鉴了RESTful架构风格中的资源标识理念。每个资源通过唯一的URI进行标识,格式为 scheme://path,其中scheme表示资源类型(如docs、github、file等)。模板化资源使用RFC 6570 URI Template规范,允许在路径中嵌入变量。这种设计使得资源具有可发现性——客户端可以先获取静态资源列表了解有哪些数据可用,再通过模板化资源获取具体内容,类似于REST API中先获取集合再获取单个实体的模式。
@mcp.resource("docs://documents", mime_type="application/json")
def list_docs() -> list[str]:
return list(docs.keys())
@mcp.resource("docs://documents/{doc_id}", mime_type="text/plain")
def fetch_doc(doc_id: str) -> str:
if doc_id not in docs:
raise ValueError(f"Doc with id {doc_id} not found")
return docs[doc_id]
课程中利用资源实现了文档提及功能:用户输入@时自动显示可提及的文档列表,选择后自动将文档内容注入提示上下文。这种模式的关键区别在于,资源的获取时机由应用逻辑决定(如UI交互触发),而非由模型在推理过程中决定。
提示词(Prompts)——由用户控制
提示词是预定义的、经过充分测试和评估的工作流模板,由用户主动触发(如斜杠命令、按钮点击)。
@mcp.prompt(name="format", description="重写文档内容为Markdown格式")
def format_document(doc_id: str = Field(description="要格式化的文档ID")):
prompt = f"请读取文档 {doc_id} 的内容,然后用Markdown语法重写它..."
return [BaseUserMessage(prompt)]
提示词的价值在于:虽然用户可以自己输入类似指令,但经过MCP服务器作者精心设计和评估的提示词往往能产生更稳定、更高质量的结果。提示词工程(Prompt Engineering)是指通过精心设计输入提示来引导大语言模型产生期望输出的技术。在实际生产环境中,一个好的提示词往往需要经过多轮迭代、A/B测试和系统评估才能稳定工作。MCP的Prompts原语将这些经过验证的提示词封装为可复用的模板,本质上是将提示词工程的成果产品化。这类似于软件工程中将最佳实践封装为库函数——用户无需了解内部实现细节,只需触发即可获得经过优化的结果。
开发与调试:MCP Inspector
MCP Python SDK提供了内置的浏览器调试工具——MCP Inspector。运行 mcp dev mcp_server.py 即可启动,在浏览器中可以:
- 连接到MCP服务器
- 列出所有工具、资源和提示词
- 手动输入参数测试各个组件
- 验证返回结果是否符合预期
这使得开发者无需将服务器连接到实际应用即可进行快速迭代和调试。MCP Inspector本质上是一个可视化的MCP客户端,它模拟了真实客户端的所有行为(发送list_tools、call_tool等请求),但提供了图形化界面让开发者直观地查看请求和响应内容。这种开发体验类似于API开发中使用Postman或Swagger UI进行接口测试。
三大原语使用场景对比
| 原语 | 控制方 | 适用场景 |
|---|---|---|
| 工具 | 模型(Claude) | 为模型添加执行能力 |
| 资源 | 应用代码 | 向应用提供数据(UI展示、上下文注入) |
| 提示词 | 用户 | 预定义的高质量工作流 |
在Claude官方界面中可以看到这三者的实际应用:底部的快捷按钮对应提示词,"从Google Drive添加"对应资源,而Claude自主决定执行代码则对应工具调用。
理解这三者的区分至关重要:工具赋予模型自主行动的能力,适合需要模型根据上下文动态决策的场景;资源为应用提供结构化数据访问,适合需要在UI中展示或预加载上下文的场景;提示词则封装了专家级的交互模式,适合需要一致性和可靠性的重复性任务。在实际应用中,三者通常协同工作——例如用户通过提示词触发一个格式化工作流,该工作流内部使用工具读取和编辑文档,而文档列表则通过资源机制提供给UI进行展示。
总结
MCP通过标准化的协议将工具定义、数据暴露和提示词管理从应用开发者的负担中解放出来。对于开发者而言,理解客户端与服务器的职责划分、掌握工具/资源/提示词三大原语的适用场景,是高效使用MCP生态的关键。随着越来越多的服务提供商发布官方MCP服务器实现,开发者可以用极少的代码就接入丰富的外部能力。
从更宏观的视角来看,MCP代表了AI应用开发从"每个应用独立集成一切"向"标准化协议+生态共建"的范式转变。正如HTTP协议统一了Web通信、SQL统一了数据库查询,MCP有望成为AI模型与外部世界交互的通用标准。这不仅降低了单个开发者的集成成本,更重要的是催生了一个可组合、可复用的工具生态系统。
核心要点
- MCP将工具定义和执行的负担从开发者转移到MCP服务器,解决了集成维护的核心痛点
- MCP架构由客户端和服务器组成,通过标准化消息(list_tools、call_tool等)进行通信,支持多种传输协议
- 三大服务器原语各有分工:工具由模型控制、资源由应用控制、提示词由用户控制
- MCP Python SDK极大简化了开发流程,通过装饰器和Field类型自动生成JSON Schema
- MCP Inspector提供浏览器内调试能力,支持在不连接实际应用的情况下测试服务器功能
相关推荐
教程攻略Cursor+Codex双IDE协同:开源项目二开实战方法论
基于实战经验总结的开源项目二次开发完整方法论,详解Cursor+Codex双IDE协同工作流,涵盖二开七环节、MVP验证、AI读源码技巧,帮助开发者三天跑通项目、两周完成业务集成。
教程攻略Cursor多Agent实战:50分钟搭建Next.js全栈博客
使用Cursor IDE多Agent协作模式,50分钟内从零搭建全栈博客。涵盖Next.js、Clerk认证、Supabase数据库集成,详解4个AI Agent分阶段开发流程与关键避坑经验。
教程攻略从零搭建AI软件工厂:Cursor工程师的多Agent协作实战经验
Cursor工程师Eric分享AI软件工厂构建实战:从自动化六层级、护栏设计、并行Agent管理到规模化扩展,详解如何用多Agent协作实现7×24小时高效软件开发。