免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

MCP协议:AI应用开发的标准化中间件,实现大模型与外部工具的高效连接

MCP协议:AI应用开发的标准化中间件,实现大模型与外部工具的高效连接 1. 从“中间件”到“智能体协作协议”MCP的定位与价值如果你最近在关注AI Agent或者大模型应用开发大概率会频繁听到一个词MCP。它不像GPT、Claude这些模型名称那样直观也不像LangChain、LlamaIndex这类框架名那样直白。我第一次接触时也困惑了一阵这到底是个工具、一个库还是一个标准经过一段时间的实践和梳理我发现MCPModel Context Protocol最贴切的定位是一个专为AI应用设计的“中间件协议”。它的核心价值在于解决大模型与外部世界连接时的“最后一公里”问题——如何让模型安全、高效、标准化地获取和使用工具与数据。想象一下你开发了一个基于大模型的智能助手希望它能帮你查邮件、分析数据库、控制智能家居。传统的做法是你需要为每一个功能编写特定的API调用代码处理复杂的认证、数据格式转换和错误处理。更麻烦的是每个模型供应商如OpenAI、Anthropic的“工具调用”Function Calling接口和格式可能略有不同你的代码会变得臃肿且难以维护。MCP的出现就是为了统一这个混乱的局面。它定义了一套标准化的通信协议让数据源如数据库、API、文件系统和工具如代码执行器、搜索引擎能够以统一的“服务”形式暴露给大模型而模型只需通过MCP客户端来调用这些服务无需关心底层实现细节。这带来的直接好处是解耦与复用。数据源和工具的提供者Server端与模型应用Client端被彻底分开。一个写好的、能安全读取本地文件系统的MCP服务可以同时被Claude Desktop、Cursor IDE以及你自研的AI应用使用。开发者不再需要为每个应用重复造轮子生态得以快速繁荣。目前AnthropicClaude的创造者是MCP的主要推动者并将其深度集成到了Claude Desktop等产品中但协议本身是开源的任何开发者都可以基于它构建或使用服务。2. MCP的核心架构拆解Server, Client与Stdio传输要理解MCP必须厘清它的三个核心组件Server服务器、Client客户端和它们之间的通信方式。这套架构非常清晰借鉴了经典的客户端-服务器模型但针对AI场景做了特殊优化。2.1 Server能力与数据的提供者MCP Server是一个独立的进程它的唯一职责是对外提供一组定义良好的“资源”Resources和“工具”Tools。你可以把它理解为一个功能专一的微服务。资源代表的是数据。例如一个“本地文件系统”Server可以将你的~/documents目录暴露为一个资源列表一个“数据库”Server可以将某个数据表暴露为资源。资源有唯一的标识符URI和描述Client可以“读取”资源来获取其内容。资源的内容通常是文本如文件内容、数据库查询结果但也可以是图像等多媒体通过Base64编码。工具代表的是可执行的操作。例如“执行Python代码”、“搜索网络”、“发送邮件”。每个工具都有名称、描述和输入参数的JSON Schema。Client调用工具时需要提供符合Schema的参数Server执行操作后返回结果。一个Server可以同时提供资源和工具。关键在于Server的实现者需要确保操作的安全性和权限边界。例如一个文件系统Server可能会被配置为只能读取特定目录而不能任意写入。2.2 Client模型的“手”与“眼”MCP Client是集成在AI应用如Claude Desktop、你的智能助手程序中的组件。它的核心工作是发现与一个或多个MCP Server建立连接并获取Server提供的所有资源和工具列表。编排将这些资源和工具的描述以模型能理解的格式通常是OpenAI Function Calling或类似格式提供给大模型。执行当模型决定调用某个工具或读取某个资源时Client负责将模型的请求转换为标准的MCP协议请求发送给对应的Server并将Server的响应返回给模型。Client是模型与外部世界交互的桥梁。一个强大的Client可以同时连接多个Server让模型的能力得到极大扩展。2.3 通信基石Stdio与SSEMCP Server和Client之间如何对话协议目前主要支持两种传输方式其中Stdio标准输入/输出是最常用、最核心的一种。Stdio模式下Server作为一个命令行程序启动Client通过子进程的方式启动Server并通过标准输入stdin和标准输出stdout与Server进行JSON-RPC通信。这种方式简单、通用、跨平台无需处理网络端口和复杂的生命周期管理。Server只需要实现从stdin读取请求向stdout写入响应即可。另一种方式是SSEServer-Sent Events这是一种基于HTTP的协议允许Server主动向Client推送数据。它适用于Server需要主动通知Client资源发生变化的场景例如一个监控日志文件的Server。但在大多数初期集成场景中Stdio模式已经足够。提示Stdio模式虽然简单但也意味着Server的生命周期由Client管理。如果Client崩溃它启动的所有Server进程也需要被正确清理否则可能会成为“僵尸进程”。在开发时这是需要注意的一个细节。协议通信的消息格式是JSON-RPC 2.0这是一种轻量级的远程过程调用规范。每条消息包含jsonrpc: “2.0”一个id用于匹配请求与响应一个method指明要调用的方法如tools/listresources/list以及params或result字段承载数据。3. 协议核心资源、工具与提示词模板理解了架构我们深入到MCP协议定义的几个核心概念。这些概念直接对应了模型与外界交互的几种基本模式。3.1 资源结构化的数据接入资源让模型能够“看到”外部数据。在MCP中资源不仅仅是一个数据块它包含元数据uri: 唯一资源标识符如“file:///home/user/project/README.md”或“db://sales/customers”。name: 对人类友好的名称。description: 描述资源内容的文本帮助模型理解是否要读取它。mimeType: 资源的媒体类型如“text/plain”“text/markdown”“image/png”。Client通过resources/list获取资源列表通过resources/read读取特定URI的资源内容。一个典型的应用场景是你将一个项目文件夹配置为资源模型在回答代码问题时可以主动读取相关的源码文件获得准确的上下文而不是依赖于可能过时或错误的训练数据记忆。3.2 工具可执行的操作抽象工具让模型能够“操作”外部系统。每个工具的定义类似于一个函数签名name: 工具名如“search_web”。description: 工具功能的详细描述。这个描述至关重要它直接决定了模型是否以及如何调用该工具。描述应清晰、无歧义。inputSchema: 定义输入参数的JSON Schema。这确保了模型提供的参数是结构化的、类型正确的。例如一个执行SQL查询的工具其inputSchema会要求一个query字符串参数。当模型需要查询数据时它会生成类似{“query”: “SELECT * FROM users WHERE active 1”}的参数由Client转发给Server执行。3.3 提示词模板动态的上下文构建这是MCP中一个非常巧妙的设计。prompts不是指我们通常写给模型的指令而是一种可动态渲染的模板资源。Server可以提供一系列提示词模板。每个模板有名称、描述和一组参数。当Client或用户选择某个模板并传入具体参数时Server会渲染出最终的提示词文本。这有什么用一个典型的例子是代码审查模板。一个“Code Review”提示词模板可能定义了两个参数code代码内容和language编程语言。Server端预置了一个高质量的代码审查提示词框架。当用户想审查一段Python代码时Client只需要调用prompts/get并传入{“code”: “…”, “language”: “python”}Server就会返回一个精心设计、包含具体代码的完整提示词。这个提示词可以直接被送入大模型得到更专业的审查意见。提示词模板的价值在于它将高质量的提示词工程能力封装和复用。应用开发者无需成为提示词专家可以直接利用社区沉淀的最佳实践。4. 实战从零构建一个自定义MCP Server理论讲得再多不如动手实现一个。我们以构建一个“天气查询MCP Server”为例展示完整流程。这个Server将提供一个工具允许模型查询指定城市的天气。4.1 环境准备与项目初始化我们使用Node.js环境因为官方提供了完善的TypeScript SDK能极大简化开发。首先确保已安装Node.js18版本和npm。# 创建一个新目录并初始化项目 mkdir mcp-weather-server cd mcp-weather-server npm init -y # 安装MCP核心SDK和类型定义 npm install modelcontextprotocol/sdk npm install --save-dev typescript tsx types/node # 初始化TypeScript配置 npx tsc --init在tsconfig.json中确保设置“module”: “ESNext”和“target”: “ES2022”以兼容SDK。4.2 编写Server核心逻辑创建一个src/server.ts文件。我们将实现一个简单的Server它提供一个get_weather工具。import { Server } from “modelcontextprotocol/sdk/server/index.js”; import { StdioServerTransport } from “modelcontextprotocol/sdk/server/stdio.js”; import { CallToolRequestSchema, ListToolsRequestSchema, } from “modelcontextprotocol/sdk/types.js”; // 1. 创建Server实例并声明其能力这里我们只需要工具 const server new Server( { name: “weather-server”, version: “1.0.0”, }, { capabilities: { tools: {}, // 声明本Server提供工具 }, } ); // 2. 模拟一个天气数据函数真实场景应调用如OpenWeatherMap的API async function fetchWeather(city: string): Promisestring { // 这里模拟API调用 const weatherMap: Recordstring, string { “beijing”: “晴朗25°C北风2级”, “shanghai”: “多云28°C东南风3级”, “shenzhen”: “阵雨30°C南风1级”, “new york”: “Partly cloudy, 72°F, NW wind 5 mph”, }; const key city.toLowerCase(); return weatherMap[key] || 未找到城市“${city}”的天气信息。; } // 3. 处理工具列表请求 server.setRequestHandler(ListToolsRequestSchema, async () { return { tools: [ { name: “get_weather”, description: “获取指定城市的当前天气情况。请提供城市名称。”, inputSchema: { type: “object”, properties: { city: { type: “string”, description: “城市名称例如Beijing, Shanghai, New York”, }, }, required: [“city”], }, }, ], }; }); // 4. 处理工具调用请求 server.setRequestHandler(CallToolRequestSchema, async (request) { if (request.params.name ! “get_weather”) { throw new Error(未知工具: ${request.params.name}); } const args request.params.arguments as { city?: string }; const city args.city; if (!city || typeof city ! “string”) { throw new Error(“工具调用必须提供有效的 ‘city’ 字符串参数。”); } const weatherInfo await fetchWeather(city); return { content: [ { type: “text”, text: 城市【${city}】的天气是${weatherInfo}, }, ], }; }); // 5. 启动Server使用Stdio传输 async function main() { const transport new StdioServerTransport(); await server.connect(transport); console.error(“Weather MCP Server 已启动通过Stdio通信。”); } main().catch((error) { console.error(“Server启动失败:”, error); process.exit(1); });4.3 配置与运行在package.json中添加启动脚本{ “scripts”: { “start”: “tsx src/server.ts” } }现在这个Server已经可以运行了。但它目前只是一个独立的进程需要被MCP Client调用。我们可以使用一个简单的测试Client来验证或者直接配置到Claude Desktop中。5. 集成实战在Claude Desktop中配置自定义ServerClaude Desktop是体验MCP最直接的工具。我们将上面编写的天气Server配置进去。5.1 构建与配置步骤首先将我们的TypeScript代码编译成JavaScript或者直接使用tsx在运行时编译。为了简单我们采用后者。我们需要创建一个Claude Desktop能识别的配置文件。在Claude Desktop中MCP Server的配置位于~/.config/claude/desktop-config.jsonmacOS/Linux或%APPDATA%\Claude\desktop-config.jsonWindows。编辑这个文件如果不存在则创建{ “mcpServers”: { “weather”: { “command”: “node”, “args”: [ “-e”, “require(‘tsx’).register(); require(‘./absolute/path/to/your/mcp-weather-server/src/server.ts’)” ], “env”: {} } } }注意上面的args使用-e参数直接执行一段代码其中通过tsx动态注册并运行我们的TypeScript文件。你需要将./absolute/path/to/your/替换为你项目server.ts文件的绝对路径。这是一种快速测试的方法。更正式的做法是先将TypeScript编译为JS然后直接执行JS文件。5.2 验证与使用保存配置文件后完全重启Claude Desktop应用。重启后在Claude的聊天界面你应该能看到一个微小的“螺丝刀”图标或类似的插件标识。当你输入“今天北京天气怎么样”时Claude作为MCP Client会识别出它有一个get_weather工具可用并自动调用它最终将Server返回的天气信息整合到回复中。这个过程是自动的。你不需要在提示词中告诉Claude去调用工具模型会根据你的问题和工具描述自行决定。这就是MCP带来的无缝体验。5.3 常见配置问题排查如果Claude Desktop没有识别你的Server请按以下步骤排查检查配置文件路径和格式JSON格式必须严格正确不能有尾随逗号。路径必须是绝对路径。查看Claude Desktop日志在macOS上可以通过Console.app查看Claude Desktop的日志在终端中启动Claude Desktop有时也能看到错误输出。日志中通常会包含加载MCP Server失败的具体原因如“命令未找到”或“模块加载错误”。测试Server独立性在终端中直接运行你的Server命令看是否能正常启动并等待输入。例如运行node -e “require(‘tsx’).register(); require(‘./src/server.ts’)”如果立即报错退出说明Server代码本身有问题。环境变量确保Claude Desktop启动时的环境尤其是PATH包含了node命令。有时从图形界面启动的应用和终端环境不同。6. 生态现状与高级应用场景目前MCP生态还处于早期但高速发展的阶段。除了官方维护的一些基础Server如文件系统、SQLite社区已经涌现了许多有趣的实现。6.1 官方与社区Server示例modelcontextprotocol/server-filesystem官方文件系统Server可安全地让模型读取本地文件。modelcontextprotocol/server-sqlite官方SQLite Server允许模型查询和分析本地SQLite数据库。mcp-server-github社区开发的GitHub Server可以读取仓库信息、Issue、PR等。mcp-server-brave-search集成Brave搜索API为模型提供联网搜索能力。自制Server正如我们上面所做的你可以为任何内部API、数据库或工具创建MCP Server将公司内部能力安全地暴露给AI助手。6.2 高级场景多Server编排与复杂工作流MCP的真正威力在于Client可以同时连接多个Server。这意味着一个AI助手可以同时具备文件读写、数据库查询、网络搜索、代码执行等多种能力。模型扮演“大脑”和“协调者”的角色。设想一个复杂的工作流用户说“帮我分析一下上个月销售数据找出表现最好的产品并生成一份总结报告”。模型通过数据库Server查询销售数据。对返回的数据模型可能调用代码执行Server如Python进行更复杂的数据清洗和分析。分析结果出来后模型调用文件系统Server读取一个报告模板提示词模板资源。最后结合数据和分析结果模型生成最终的报告文本并可能通过文件系统Server写入一个新文件。这一切通过MCP协议可以在一个对话中流畅、自动地完成。开发者需要做的只是部署好相应的Server并在Client中配置好连接。6.3 安全与权限考量将本地文件、数据库甚至执行代码的能力暴露给AI模型听起来风险很高。MCP通过设计来缓解这些风险最小权限原则每个Server都应被配置为仅拥有完成其任务所需的最小权限。文件系统Server应该被限制在特定的工作目录而不是整个硬盘。用户确认未来方向协议设计上支持“用户确认”机制对于高风险操作如删除文件、执行命令Server可以请求用户明确批准。这需要Client端的支持。沙箱化对于代码执行类Server必须在严格的沙箱环境中运行不可信的代码。审计日志所有工具调用和资源读取都应被记录便于事后审计。在实际企业应用中MCP Server可以作为内部系统和AI前端之间的一个安全、可控的代理层。7. 对比与展望MCP在AI工程化中的位置为了更清晰地定位MCP我们可以将其与其它流行的AI框架进行对比。特性/项目LangChain/LlamaIndexMCP (Model Context Protocol)核心定位AI应用开发框架。提供构建端到端AI应用链、代理、检索等所需的高级抽象和组件。AI能力接入协议。专注于标准化模型与外部工具/数据源之间的通信接口。要解决的问题如何编排多个步骤、管理上下文、集成各种向量数据库和模型。如何让模型安全、统一地调用成千上万种不同的工具和数据源。使用方式在Python/JS应用中导入库编写代码构建应用逻辑。实现或配置独立的Server进程在AI应用Client中连接这些Server。耦合度应用代码与具体的工具/数据源实现耦合较紧。更换数据源可能需要修改代码。松耦合。Server与Client独立可以随时替换或增加Server无需修改Client或模型。生态目标成为AI应用开发的“标准库”。成为AI工具/数据源的“USB标准”或“驱动协议”。它们不是竞争关系而是互补关系。一个复杂的AI应用完全可以使用LangChain来构建核心的代理逻辑同时通过MCP来接入各种外部工具和数据源。MCP解决了LangChain生态中“工具定义不统一、集成复杂”的痛点。展望未来我认为MCP的发展会集中在几个方向Server生态爆炸会出现越来越多垂直领域的、高质量的MCP Server从操作云服务到控制物联网设备。协议功能增强可能会增加更细粒度的权限控制、流式响应支持、双向通信Server主动推送事件给模型等。客户端标准化更多的AI应用和平台如IDE、聊天机器人框架会内置或兼容MCP Client使其成为AI应用的标配能力。企业级特性围绕安全、审计、监控、Server管理平台等企业需求会诞生相应的工具和服务。对我个人而言在项目中引入MCP最大的体会是它带来了一种“清洁的架构”。将能力封装成独立的Server后AI应用的代码变得非常干净只关心核心的业务逻辑和提示词工程而将各种脏活、累活交给了专门化的Server。这种关注点分离让开发和维护效率都得到了提升。尤其是在团队协作中前端AI工程师和后端工具开发者可以并行工作通过MCP协议定义好接口即可这无疑是AI工程化迈向成熟的重要一步。
返回列表