什么是 MCP
MCP,全称 Model Context Protocol,它是 AI 调用外部工具的一套标准协议。
一、为什么需要 MCP
现在的大模型会聊天、会写代码、会总结内容、会推理,看起来几乎什么都懂。
但,它默认被困在聊天框里。
它不能直接读取你的数据库,不能访问本地文件,不能操作浏览器,也不能连接 GitHub、飞书、公司内部系统。
当然,如果你对 AI 用得比较多,你也许会说:
Agent 加上文件系统工具,也能读取文件;
接一个浏览器自动化工具,也能操作网页。
确实如此。
但这样就需要每个 AI 应用、每个 Agent 框架都实现一套自己的工具调用方式。
而这些工具大概率是生态彼此割裂无法复用的,没有统一标准,就会造成很大的资源浪费,不利于 AI 的发展。
这就是 MCP 出现的原因。
AI 世界开始需要一种统一的工具连接方式。
二、MCP 的核心是什么
MCP 的核心是统一 AI 调用外部工具的方式。它就像 AI 世界里的 USB-C。
有了这个标准,当 Cursor 想接 Mysql 数据库,Codex 助手也想接 Mysql 数据库的时候,只需要 实现一套 Mysql 的 MCP 标准协议的 Server,然后他们各自通过 MCP 标准协议连接和调用即可。
AI 应用 <-> MCP 协议 <-> 外部工具
当文件系统、数据库、浏览器、GitHub、飞书、内部 API,都按 MCP 标准暴露能力的时候,此时 AI 应用只要支持 MCP,就能用统一方式:
发现工具 —— 调用工具 —— 传递参数 —— 获取结果
三、MCP 的架构
MCP 里有三个核心角色:
| 角色 | 是什么 | 例子 |
|---|---|---|
| Host | AI 应用本体 | Cursor、Claude Desktop、AI IDE |
| Client | Host 里的连接器 | Cursor 内部连接 MCP Server 的模块 |
| Server | 工具提供方 | 文件系统 MCP、数据库 MCP、本地 Node.js MCP |
比如你在 Cursor 里配置一个本地 Node.js MCP:
- Cursor 是 Host
- Cursor 内部的 MCP 连接模块是 Client
- 你写的 Node.js 脚本是 Server
MCP Server 主要暴露三类能力:
| 能力 | 解决什么 | 例子 |
|---|---|---|
| Tools | 能做什么 | 查数据库、读网页、创建工单、调用浏览器 |
| Resources | 能看什么 | 文件、日志、接口文档、Git diff |
| Prompts | 怎么开始做 | 生成周报、分析风险、生成测试用例 |
最常用的是 Tools。因为大部分场景里,我们希望 AI 不只是回答,而是能调用一个明确的工具去完成动作。
工具是怎么注册和发现的
MCP Server 启动后,会先把自己有哪些工具注册好。一个工具通常包含:
- 名称
- 描述
- 参数
- 返回结果
Host 连接 MCP Server 后,会读取 Server 已注册的 Tools 列表,包括工具名、描述和参数信息,再交给 LLM 判断是否使用。
所以 LLM 不是随便调用本地函数。它看到的是一份工具清单,然后根据工具名称、描述和参数决定要不要调用。
四、MCP 开发实战
接下来咱们通过实现一个最小 MCP Server,来进一步了解 MCP。
目标:在 Cursor 里输入 hello,本地 MCP 工具返回 word。
这个例子没有业务价值,只是为了看清 MCP 的调用链。真实项目里,把 reply_hello 换成 query_database、read_feishu_doc、open_browser,流程是一样的。
开发起来很简单,因为比较复杂的部分都被封装在开源库 @modelcontextprotocol/sdk 里面了。
1. 创建项目
mkdir hello-mcp
cd hello-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod
把 package.json 设为 ESM:
{
"type": "module"
}
2. 编写 Server
新建 server.js:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "hello-mcp",
version: "1.0.0",
});
server.tool(
"reply_hello",
"When the input text is hello, reply with word.",
{
text: z.string().describe("User input text"),
},
async ({ text }) => {
if (text.trim().toLowerCase() === "hello") {
return {
content: [{ type: "text", text: "word" }],
};
}
return {
content: [
{ type: "text", text: "I only reply word when the input is hello." },
],
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
这里最关键的是 server.tool(...)。
它就是在注册工具:告诉 MCP Server,我有一个叫 reply_hello 的工具,它接收 text 参数;当 Host 调用它时,就执行后面的函数并返回结果。
这段代码只做两件事:
- 注册一个工具:
reply_hello(text) - 当参数是
hello时返回word
3. 配置 Cursor
在项目里的 .cursor/mcp.json,或者全局的 ~/.cursor/mcp.json 里写:
{
"mcpServers": {
"hello": {
"command": "node",
"args": ["/Users/you/hello-mcp/server.js"]
}
}
}
把路径换成你机器上的真实路径。
配置完成之后,Cursor 会按这个配置启动本地 Node.js 进程,并通过 stdio 和它通信。
4. 调用链路
当你在 Cursor 里输入:
hello
大致会发生这些事:
用户输入 hello
↓
Cursor 把用户输入和工具列表交给 LLM
↓
LLM 判断可以调用 hello.reply_hello
↓
Cursor 通过 MCP Client 调用本地 MCP Server
↓
MCP Server 执行 reply_hello({ text: "hello" })
↓
MCP Server 返回 word
↓
LLM 基于工具结果输出 word
注意,LLM 不直接执行 Node.js。它只是决定要调用哪个工具、传什么参数,真正执行逻辑的是 MCP Server。
五、总结
MCP 是让 AI 能通过标准化方式连接外部工具的一套协议。
在 MCP 架构里:
- MCP Server 负责暴露工具和能力;
- Host 负责连接和管理 MCP Server;
- LLM 则根据用户需求决定是否调用工具。
它让 AI 从“回答问题”,开始变成“执行任务”。