尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MCP协议入门指南:从核心原理到Node.js与Python实战接入

MCP协议入门指南:从核心原理到Node.js与Python实战接入 在最近几个项目里我都需要把不同能力接入到 AI 客户端中有时候是查数据库有时候是读设计稿有时候是让 AI 操作浏览器。每换一个工具就要重新写一遍集成代码每换一个客户端又要再适配一遍接口。后来接触到 MCPModel Context Protocol模型上下文协议才逐渐把这一堆零散的接入工作收敛成一套标准做法。本文围绕 MCP 协议从基础概念、核心原理、环境准备到 Node.js 和 Python 两个实际可运行的 Server Demo再到 Cursor、Claude Desktop 等客户端中的接入步骤做一次完整梳理。适合正在学习 MCP 的开发者也适合需要把 MCP server 落地到业务里的工程同学。1. 背景与核心概念1.1 为什么需要一套“标准协议”在没有 MCP 之前AI 应用要接入外部工具通常有两种做法第一种是给大模型直接调用特定 API。比如想让 AI 查询天气就在代码里写一个getWeather()函数然后把这个函数注册到模型的 function calling 列表里。这种方式的缺点是函数定义散落在业务代码里换一个客户端就要重新适配。第二种是给 AI 客户端写插件。插件本身并没有统一标准不同客户端的插件 API 完全不同一个插件很难同时跑在 Cursor、Claude Desktop、Trae 这些工具上。于是问题就来了每个工具链都在重复“定义工具、暴露工具、让模型调用工具”这件事但协议不统一开发成本被成倍放大。MCP 就是为了解决这个重复劳动而出现的。1.2 MCP 是什么MCP 是 Anthropic 在 2024 年 11 月开源的一套开放协议全称是 Model Context Protocol中文可以理解为“模型上下文协议”。它定义了大模型与外部数据源、工具之间的标准化交互方式。2025 年 3 月协议规范进入广泛可用阶段生态也迅速扩展。可以把 MCP 理解为大模型世界的“USB-C 接口”无论你插入的是鼠标、键盘还是显示器只要它们遵循同一个物理标准就能无缝对接。MCP 做的就是这个标准化工作只不过它连接的不是硬件设备而是数据源、API、命令行工具和 AI 客户端。一个完整的 MCP 架构中通常包含几个角色MCP Host用户使用的 AI 应用比如 Claude Desktop、Cursor、Trae。MCP Client宿主应用内部负责与 MCP Server 建立连接、收发消息的进程。MCP Server向外暴露工具、资源、提示词的服务进程本质是一个轻量级服务。外部资源和工具MCP Server 背后真正访问的数据库、文件、API 等。从协议角度讲MCP 规定了“客户端如何发现工具”“模型如何发起调用”“服务端如何返回结果”这三个核心问题。它还支持多种传输方式本地进程可以用标准输入输出stdio远程服务可以用 HTTP 流式传输这就让 MCP 既能跑在本地也能部署成远程服务。1.3 MCP 的典型应用场景MCP 目前覆盖了非常多领域简单列几个热搜词里反复出现的场景方便理解它到底能做什么数据库接入通过 MCP server 连接 MySQL、PostgreSQL 等数据库AI 客户端可以直接用自然语言查询数据。设计稿接入蓝湖 MCP、MasterGo MCP、Figma MCP 这类服务把设计稿的图层、标注、属性暴露给 AI前端开发可以直接让 AI 读取设计稿生成代码。浏览器自动化Playwright MCP 可以让 AI 控制真实浏览器完成页面操作、截图、端到端测试。游戏引擎和三维场景Unity MCP、Cocos Creator MCP、三维建筑图生成相关的 MCP 服务正在把游戏引擎和可视化工具接入 AI 流程。代码调试和逆向分析x64dbg MCP、Ghidra MCP 等社区项目把调试器、反编译器能力暴露给 AI。安全审计Wazuh MCP、Burp Suite MCP 等探索让 AI 能直接查询安全平台数据、辅助分析告警。这些场景的共同点是都需要把“某个外部能力”安全地暴露给 AI 客户端而且希望客户端能自动发现、调用这些能力。MCP 标准化之后一套 Server 可以被多个客户端复用生态价值非常明显。1.4 MCP 与相关概念的边界学习 MCP 时经常有人把 MCP 和 function calling、skills、插件混在一起。它们之间的关系可以用一张表格来大致区分概念定位与 MCP 的关系Function Calling模型调用函数的能力是模型侧的一种推理机制MCP 的工具调用可以依赖 function calling 实现API系统间接口格式由服务方自定MCP 是一种标准化的 API 封装协议Plugin / 插件客户端侧的扩展机制强耦合客户端MCP Server 是跨客户端的通用插件形态Skills给模型预设的知识、技能、流程模板与 MCP 互补Skills 提供“怎么用”的上下文MCP 提供“能调用什么”的外部能力简单理解function calling 是“模型能调用函数”的底层能力而 MCP 是“把函数暴露给模型”的统一标准Skills 更像是给模型的锦囊而 MCP 是外接的工具箱。2. 环境准备与版本说明MCP 的官方 SDK 主要提供 TypeScript/JavaScript 和 Python 两套社区也有 Java、Go、Rust 等实现。本文的示例以 Node.js 和 Python 为主。2.1 基础运行环境建议本机具备以下环境Node.js 18 或更高版本用于运行 TypeScript/JavaScript MCP Server。Python 3.10 或更高版本用于运行 Python MCP Server。一个支持 MCP 的 AI 客户端例如 Cursor、Claude Desktop、Trae 或 Cherry Studio。如果你需要验证当前环境可以打开终端执行node -v npm -v python --version只要命令能正常输出版本号即可。版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。2.2 安装官方 SDK如果是 Node.js 项目在项目目录内执行npm install modelcontextprotocol/sdk zod其中modelcontextprotocol/sdk是官方 TypeScript SDKzod用于工具参数校验。如果你的 Node.js 版本较新SDK 会默认使用较新的协议版本。如果是 Python 项目可以安装官方 Python SDKpip install mcp[cli]社区也有基于官方 SDK 封装的 FastMCP它让 Server 的编写更加简洁适合快速 Demopip install fastmcp这里需要提醒一下MCP SDK 版本迭代较快而且某些 API 在不同版本里会有调整。你在复制本文代码时如果遇到“某个类不存在”或“方法签名变化”的报错优先检查项目里实际安装的 SDK 版本再对照官方文档微调写法。2.3 准备一个 AI 客户端本文后半部分的接入示例会用到客户端配置。不同客户端的配置入口不太一样Cursor通过项目根目录的.cursor/mcp.json配置也可以在 Settings 的 MCP 页面里通过 UI 添加。Claude Desktop在应用的设置里找到 Developer 配置编辑claude_desktop_config.json。Trae支持在设置中配置 MCP 服务也支持某些第三方 MCP 快速接入。Cherry Studio设置中通常有 MCP 服务管理入口支持添加本地或远程 Server。如果你还没有这些客户端本文前 4 章的 Server 部分仍然可以独立学习因为 MCP Server 本质上是一个独立进程不一定非要绑定某个客户端才能运行和测试。3. MCP 核心原理拆解3.1 MCP 服务端的三个核心原语MCP Server 对外暴露的能力在规范里被抽象成三类原语Tools工具可被模型调用的函数模型会按需发起调用。工具适合执行操作比如查数据、发请求、执行命令。Resources资源提供给模型读取的上下文数据类似文件系统中的文件。资源适合向模型注入数据比如项目文档、表结构说明。Prompts提示词模板可复用的提示词模版用户或模型可以选择性使用帮助模型完成特定任务。三者的定位可以这样记想让模型“做事情”→ 暴露 Tool。想让模型“读资料”→ 暴露 Resource。想让模型“按模板对话”→ 定义 Prompt。日常落地中Tools 是使用最频繁的一类。下面实战部分我们会重点实现 Tool。3.2 客户端与服务端的传输方式MCP 支持多种传输方式目前最常见的是两种stdio通过标准输入输出进行通信适用于本地进程。客户端启动一个子进程来运行 MCP Server数据在 stdin/stdout 中传递。HTTP over Streamable HTTP / SSE适用于远程服务。Server 部署在服务器上客户端通过 URL 访问较新的规范中 Streamable HTTP 正在逐渐替代早期的 SSE 模式。选择传输方式的判断很简单如果 Server 和客户端在同一台机器上优先用 stdio如果 Server 部署在远端需要被多个客户端共享用 HTTP 传输。远程 MCP 服务如果涉及敏感数据还应该结合认证机制比如 OAuth 或服务端自定义鉴权。3.3 一次工具调用的完整流程为了更清楚地把 MCP 工作原理讲明白下面用文字描述一次“客户端调用 MCP 工具”的过程用户向 AI 客户端提问模型判断需要查询外部数据。客户端通过 MCP 协议向 Server 发送tools/list请求获取 Server 上可用的工具列表和参数 schema。模型根据工具描述生成调用参数客户端发送tools/call请求给 Server。Server 执行对应逻辑访问数据库或外部 API把结构化结果返回给客户端。客户端把结果交给模型模型根据结果生成最终回复。可以看到整个过程中客户端只依赖协议标准与 Server 交互并不关心 Server 内部是什么技术栈。这就是 MCP 能实现“一次实现多处复用”的关键。4. 实战用 Node.js 搭建一个商品查询 MCP Server下面我们实现一个真实可运行的 MCP Server。这个 Server 会读取本地 JSON 文件中的商品数据并向客户端暴露两个工具list_products获取商品列表get_product按 ID 查询商品详情。4.1 初始化项目结构首先创建项目目录mkdir mcp-demo-server cd mcp-demo-server npm init -y然后安装依赖npm install modelcontextprotocol/sdk zod在项目根目录下创建data目录并新建商品数据文件data/products.json[ { id: 1, name: 无线鼠标, price: 59.0, stock: 120 }, { id: 2, name: 机械键盘, price: 249.0, stock: 45 }, { id: 3, name: 4K 显示器, price: 1699.0, stock: 18 } ]这个文件就是 MCP Server 要访问的“外部数据源”。实际业务中你可以把这里替换成 MySQL、PostgreSQL 查询或者调用某个内部 HTTP API。4.2 编写 MCP Server 核心代码在项目根目录创建index.js代码如下// 文件路径mcp-demo-server/index.js import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { z } from zod; import { readFileSync } from node:fs; import { fileURLToPath } from node:url; import path from node:path; const __dirname path.dirname(fileURLToPath(import.meta.url)); // 读取本地商品数据实际项目中建议替换为数据库查询 const products JSON.parse( readFileSync(path.join(__dirname, data/products.json), utf-8) ); // 创建 MCP Server 实例 const server new McpServer({ name: product-server, version: 1.0.0 }); // 工具 1获取商品列表 server.tool( list_products, {}, async () { return { content: [{ type: text, text: JSON.stringify(products, null, 2) }] }; } ); // 工具 2按 ID 查询商品 server.tool( get_product, { id: z.number().describe(商品 ID) }, async ({ id }) { const product products.find((p) p.id id); if (!product) { return { content: [{ type: text, text: 未找到 ID 为 ${id} 的商品 }] }; } return { content: [{ type: text, text: JSON.stringify(product, null, 2) }] }; } ); async function main() { const transport new StdioServerTransport(); await server.connect(transport); console.error(Product MCP Server running on stdio); } main().catch((err) { console.error(err); process.exit(1); });这里有几个细节需要解释。McpServer是官方 SDK 提供的高层封装它会自动处理协议握手、请求分发等工作。server.tool方法接收三个参数工具名称、参数 schema、处理函数。参数 schema 使用 zod 定义客户端会自动读取这个 schema 并转换成大模型能理解的 JSON Schema所以在定义参数时加上描述会直接影响模型调用工具的准确性。StdioServerTransport表示使用标准输入输出作为传输通道。我用console.error打印启动日志而不是console.log这是一个重要的细节因为 stdio 模式下的标准输出不能再输出普通日志否则会污染 MCP 数据通道。另外这段逻辑里使用zod对id做了数字类型校验。如果客户端传入非数字的idServer 会直接返回参数校验错误而不是进入真实的业务处理这也是工程上一个很好的兜底习惯。4.3 修改 package.json由于index.js使用了 ES Module 语法需要在package.json中声明模块类型{ name: mcp-demo-server, version: 1.0.0, type: module, main: index.js, dependencies: { modelcontextprotocol/sdk: ^1.0.0, zod: ^3.25.0 } }如果你安装到的版本与示例有差异以实际安装为准但type字段必须保持为module否则import语法会报错。4.4 用 MCP Inspector 测试 ServerMCP 官方提供了一个图形化调试工具叫做 MCP Inspector。在我们把 Server 接入客户端之前先用它来验证 Server 是否能正常工作。执行npx modelcontextprotocol/inspector node index.js运行后Inspector 会打开一个本地调试页面。你可以看到List Tools按钮点击后应该能看到list_products和get_product两个工具。点击某个工具并传入参数可以模拟一次完整的工具调用。预期输出是 JSON 格式的商品数据。例如调用get_product并传入{id: 1}返回结果应该包含“无线鼠标”的信息。如果这里出现错误一般是依赖版本或 Node 版本问题可以先查看终端里的错误日志。这一步能让 Server 的验证脱离具体客户端非常高效。4.5 把 Server 接入 Cursor在 Cursor 项目根目录创建.cursor/mcp.json文件{ mcpServers: { product-server: { command: node, args: [/absolute/path/to/mcp-demo-server/index.js] } } }注意args里的路径要改成你本机项目的绝对路径。Windows 用户建议使用/分隔路径例如E:/codes/mcp-demo-server/index.js避免反斜杠转义问题。配置完成后在 Cursor 的 MCP 管理界面刷新列表看到product-server已连接就可以在对话中直接询问“帮我列一下商品列表”模型会调用list_products工具并返回结果。5. 实战用 Python FastMCP 快速实现如果你更熟悉 Python可以使用 FastMCP 快速写出一个 MCP Server。FastMCP 是对官方 SDK 的友好封装代码量更少非常适合搭建内部工具原型。5.1 安装依赖创建一个新的 Python 项目目录并安装 fastmcpmkdir python-mcp-demo cd python-mcp-demo pip install fastmcp5.2 编写 Server创建server.py# 文件路径python-mcp-demo/server.py from fastmcp import FastMCP mcp FastMCP(demo-server) mcp.tool() def add(a: int, b: int) - int: 计算两个整数之和 return a b mcp.tool() def get_weather(city: str) - str: 模拟查询某个城市的天气实际项目可替换为真实天气 API return f{city} 的天气多云23℃ if __name__ __main__: mcp.run(transportstdio)FastMCP会根据函数的类型注解和 docstring 自动生成工具描述这一点对模型准确调用工具非常友好。你只需要用mcp.tool()装饰函数函数就会自动暴露为 MCP Tool。5.3 运行与验证在终端运行python server.py如果没有输出日志说明 Server 已经启动并等待 stdio 输入。你可以同样用 MCP Inspector 来测试npx modelcontextprotocol/inspector python server.py如果 Inspector 中能看到add和get_weather两个工具并且调用add时传入{a: 1, b: 2}能得到3说明 Server 工作正常。需要说明的是FastMCP 的 API 与官方 Python SDK 略有不同如果你后续需要更多底层控制建议直接使用官方 SDK。FastMCP 的优势是适合快速写业务工具示例思路如下需按实际版本调整。6. 在主流客户端中接入 MCP Server6.1 Claude Desktop 配置方式打开 Claude Desktop 的设置找到 Developer 栏目点击Edit Config打开配置文件后加入{ mcpServers: { product-server: { command: node, args: [E:/codes/mcp-demo-server/index.js] } } }保存配置后重启 Claude Desktop就可以在对话中调用该 MCP Server 的工具了。Claude 桌面端通常会展示当前可用的 MCP 工具列表你可以确认product-server是否已经连接。6.2 Trae 与 Cherry Studio 等客户端的说明Trae、Cherry Studio 这类新兴客户端的 MCP 配置入口各有不同但整体逻辑一致添加一个 MCP Server 时要么填写 stdio 模式下的命令和参数要么填写远程服务的 URL。你可以按照客户端界面的提示把 Node.js 项目的启动命令填入即可。如果你使用的是 VS Code 中的 Cline 等插件一般也能在插件设置里找到 MCP Server 配置项配置格式与上面大同小异。6.3 远程 MCP Server 的 URL 接入方式如果你的 Server 部署在远端那么客户端配置就很简单只需要提供 URL例如{ mcpServers: { remote-server: { url: https://your-host.com/mcp } } }远程 MCP 的接入还要考虑认证、HTTPS、网络策略等问题。如果你的 Server 部署在内网客户端所在机器必须能访问到该内网地址同时要有相应的网络白名单策略。6.4 使用社区现成的 MCP Server很多业务场景不需要自己从零实现 MCP Server。比如设计稿解析可以直接找蓝湖 MCP、Figma 社区版 MCP浏览器自动化可以直接使用 Playwright MCP如果只想让 Cursor 查询 MySQL可以优先搜索社区维护的 MySQL MCP Server再根据项目 README 配置数据库连接字符串。我的建议是先确认社区是否有现成方案再评估是否需要自研。因为 MCP Server 本身只是一个转发和封装层更关键的是背后的数据源和工具能力与其重复造轮子不如把精力花在业务逻辑上。7. 常见问题与排查思路在实际使用 MCP 的过程中最常遇到的坑通常集中在配置格式、SDK 版本、传输方式、路径这四个方面。下面整理成表格方便快速定位。问题现象常见原因解决思路客户端看不到 MCP 工具Server 未启动成功或工具未注册先用 MCP Inspector 单独验证 Server工具列表有但调用时报参数错误参数 schema 定义与模型生成参数不匹配检查 zod 定义类型补全参数描述启动时提示 ES Module 报错package.json 缺少 typemodule在 package.json 中声明模块类型stdio 模式却往 stdout 打印日志日志污染了协议数据通道改用 stderr 打印日志Python 环境执行报错本机存在多个 Python 版本使用虚拟环境安装依赖并运行配置文件不生效配置路径错误或 JSON 格式错误检查配置文件格式确认绝对路径远程 Server 连接超时网络策略、HTTPS 证书或认证配置问题检查网络可达性、证书、鉴权信息MCP Server 版本不兼容SDK 版本与协议版本不匹配统一升级或锁定 SDK 版本如果遇到“工具不显示”排查顺序建议是先用 MCP Inspector 跑通 Server再用客户端配置接入最后再检查客户端日志。很多问题发生在一开始直接把 Server 交给客户端会增加排查难度。如果是远程 HTTP 传输的 MCP还要注意服务端是否开启了必要的 CORS 策略以及是否支持最新的 Streamable HTTP 规范。部分早期 MCP 服务只支持 SSE 端点新版客户端会提示不兼容这时候需要查看服务方提供的文档确认 URL 类型。针对“自己实现 MCP 还是用现有 MCP”这个问题我给出的判断标准是如果社区工具已经覆盖了你需要的能力优先使用如果你是业务方需要把内部 API 或数据库安全地暴露给各 AI 客户端那就值得自研一个 MCP Server因为你只写一次却能被多种客户端复用。8. 最佳实践与工程建议8.1 工具设计原则MCP 暴露的工具会对模型可见所以工具的命名、入参、描述都会影响模型调用的准确率。命名建议使用小写字母 下划线比如get_product、list_orders语义要清晰。入参建议全部使用带描述的参数 schema尽量把“模型需要传什么、最终返回什么”写清楚。工具职责尽量保持单一。一个工具只做一件事避免让模型猜你要不要传一堆控制参数。如果逻辑复杂宁可拆成多个工具也不要设计一个“万能工具”。8.2 错误处理与结果结构工具处理函数内部要自己兜底异常。不要把异常直接抛给协议层否则客户端只会看到一条难以理解的报错。建议在工具内部捕获异常并返回人类可读的错误文本。返回结果统一使用结构化内容内容字段尽量是纯文本或合法 JSON。这样模型总结结果时会更稳定也方便后续接入其他客户端。8.3 安全边界与最小权限MCP Server 能访问的资源必须遵循最小权限原则。如果你是给客户端暴露数据库查询工具建议使用只读账号而不是 root 账号如果是查询类工具只暴露必需的 SQL 能力不要在工具里写“可直接执行任意 SQL”这种危险设计。密钥管理也要注意。MCP 的配置文件中会明文记录命令、参数、环境变量不要把数据库密码、API Key 直接写在mcp.json或claude_desktop_config.json里。建议通过环境变量注入或者使用密钥管理服务。远程 MCP 服务如果要接收来自多个客户端的请求务必开启认证机制。MCP 规范支持的标准 OAuth 认证流程可以让服务端安全地验证客户端身份具体配置方法要以官方文档和实际部署版本为准。8.4 日志与审计本地 stdio 模式下记得所有日志走 stderr远程服务模式下建议记录谁在什么时间调用了哪个工具、传了哪些参数。尤其涉及生产数据、安全审计、自动化变更时完整调用链审计能帮你在出现问题时快速定位。8.5 与 Skills 的配合MCP 解决的是“外部工具怎么接进来”的问题而 Skills 解决的是“模型怎么使用这些工具”的问题。你可能在一个项目中既配置了 MCP Server又给客户端配置了 Skills。两者并不冲突Skills 可以提供业务规则、术语解释、操作手册MCP 可以真正执行外部操作。好的实践是让 Skills 中定义业务上下文让 MCP 提供能力边界。在多智能体场景中MCP 的作用也会更加明显。不同智能体可以共享一组 MCP Server每个 Agent 按职责调用不同工具避免每个 Agent 各自实现一套 API 集成减少重复建设也便于统一做权限管控。9. 总结与后续学习路线本文围绕 MCP 协议做了比较完整的梳理从“为什么需要 MCP”到核心架构原理从 Node.js 和 Python 两个可运行 Demo到客户端接入和问题排查。你可以看到MCP 并不算复杂它本质上是把“工具接入”这件重复的事情标准化了。接下来你可以继续深入几个方向一是阅读官方协议规范重点看 Streamable HTTP 传输和认证的部分二是尝试把本地 JSON 数据源替换成真实的数据库查询写一个真正能用的内部工具三是研究生态中已有的 MCP Server比如浏览器自动化、设计稿解析、数据库访问等避免重复造轮子。实际项目中优先关注的一定是安全边界和权限控制。MCP 给开发带来便利的同时也让 AI 客户端第一次真正拥有了“执行操作”的入口这个入口必须严格管理。先在小范围验证再逐步推广到团队是比较稳妥的落地路径。如果本文对你有帮助可以收藏备用后续我会继续更新 MCP 相关的实战笔记。
返回列表