✦ 大道至简 · 时光是画在卷上的河流 · 行到水穷处,坐看云起时

mcp2026.08.25 · 17 分钟阅读

agent之mcp

工具写一次,所有支持 MCP 的客户端都能用。** 这就像 HTTP——同一个服务器,浏览器、curl、Python 都能访问。

L

Leo

2026.08.25 · 更新于 2026.09.13

5 次浏览
agent之mcp

MCP 协议:让工具写一次、处处可用

上一篇文章讲了 Agent 的工具系统。但每个应用(Cursor、Claude Code、自己写的程序)都要各自接入一遍工具,太累了。MCP 就是来解决这个问题的。

一、MCP 要解决什么问题?—— N × M 的集成地狱

假设你有 3 个工具(查用户、查地图、读文件),有 4 个客户端(Cursor、Claude Code、Claude Desktop、自己写的程序)。

没有标准协议时,每个客户端都要为每个工具写一套专属接入代码:

工具1 ──→ Cursor、Claude Code、Desktop、自研程序   (4 份代码)
工具2 ──→ Cursor、Claude Code、Desktop、自研程序   (4 份代码)
工具3 ──→ Cursor、Claude Code、Desktop、自研程序   (4 份代码)

3 × 4 = 12 份集成代码,且每对组合的 API 还不一样。工具一多就失控。

MCP(Model Context Protocol,模型上下文协议) 就是 AI 世界的"USB-C 接口"——它是 Anthropic 开源的一个开放标准,规定了一套统一的工具接入方式。有了它:

工具(MCP Server)──→ 任何 MCP Client(Cursor / Claude Code / 自研程序…)

工具写一次,所有支持 MCP 的客户端都能用。 这就像 HTTP——同一个服务器,浏览器、curl、Python 都能访问。


二、核心概念:Server / Client / Transport

MCP 架构里有三个角色:

角色是什么举例
MCP Server提供能力的一方,暴露工具 / 资源 / 提示词mymcp.js、@modelcontextprotocol/server-filesystem
MCP Client消费能力的一方,连接 Server 并调用工具Cursor、Claude Code、自研 LangChain 程序
Transport两者通信的通道stdio(本地子进程)、Streamable HTTP(远程)

关键点:一个 Server 可以被多个 Client 连接。同一个 mymcp.js,Cursor 能用、Claude Code 能用、你写的程序也能用,Server 端一行代码都不用改。


三、stdio 传输:MCP 到底怎么通信?

最常用的传输方式是 stdio(标准输入/输出)。Client 以子进程方式启动 Server:

MCP Client(Cursor / Claude Code / 自研程序)
   │  spawn 子进程: node src/mymcp.js
   │  通过 stdin 发送 JSON-RPC 请求
   │  从 stdout 读取 JSON-RPC 响应
   ▼
MCP Server(mymcp.js)

三个特点:

  1. 本地零配置:不需要开端口、不需要装服务,天然安全。
  2. 生命周期跟随 Client:Client 关了,Server 子进程自动退出,不留孤儿进程。
  3. 传输内容是 JSON-RPC 消息(请求 / 响应 / 通知)。

⚠️ 最大的坑:stdout 被协议占用。 console.log 会把杂数据写进 stdout,污染协议,Client 解析会直接崩。 要打日志必须用 console.error(走 stderr)或写文件。


四、第一个 MCP Server:四步骨架

以我写的 mymcp.js 为例,一个 MCP Server 只有四步:

// ① 导入
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: 'my-mcp-server', version: '1.0.0' });

// ③ 注册能力(工具)
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} 不存在。可用的 ID: 001, 002, 003` }] };
    }
    return {
        content: [{
            type: 'text',
            text: `用户信息:\n- ID: ${user.id}\n- 姓名: ${user.name}\n- 邮箱: ${user.email}\n- 角色: ${user.role}`,
        }],
    };
});

// ④ 创建传输并连接,开始等待请求
const transport = new StdioServerTransport();
await server.connect(transport);

骨架四步:导入 → 建实例 → 注册能力 → connect 监听。

工具四要素 = LangChain 四件套的翻版

对比上一篇讲的 LangChain 工具,你会发现结构惊人地一致:

LangChain 工具MCP 工具
name工具名(registerTool 第一个参数)
description(写给模型)description(写给模型)
schema(zod)inputSchema(zod)
func第三个参数(handler)

理解了上一篇,MCP 的 Server 端你基本就会了——只是包装的框架不同。

注意:Server 不主动运行

connect 之后,Server 只是挂在 stdio 上等请求,没有界面、不打印任何东西。你直接 node src/mymcp.js 运行它,肉眼什么都看不到——因为它没收到请求,这是正常的。


五、除了工具,还有"资源"(Resource)

MCP 还能注册资源——给 Client 读取的静态数据 / 文档。可以这样理解:

  • 工具是"动作":会改变世界或计算东西(查用户、读文件、执行命令)
  • 资源是"数据/文档":只读,直接给 Client 看(使用指南、配置说明)
server.registerResource('使用指南', 'docs://guide', {
    description: 'MCP Server 使用文档',
    mimeType: 'text/plain',
}, async () => {
    return {
        contents: [{
            uri: 'docs://guide',
            mimeType: 'text/plain',
            text: `MCP Server 使用指南\n\n功能:提供用户查询等工具。`,
        }],
    };
});

六、在 Claude Code / Cursor 里注册使用

写好的 Server 要怎么让 Claude Code 用?在项目根目录放一个 .mcp.json:

{
  "mcpServers": {
    "my-mcp-server": {
      "type": "stdio",
      "command": "node",
      "args": ["src/mymcp.js"]
    },
    "filesystem": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "F:/agent-learn"]
    }
  }
}

要点:

  1. 每个 server = 一个名字 + command / args 启动命令。args 里的相对路径相对于配置文件所在目录。
  2. Client 启动时读取配置,用子进程拉起 Server;注册后通常要重启会话或重新 /mcp 连接,工具才会出现在工具列表里。
  3. 连接成功后,Claude Code 才真正"看得到" query_user 这个工具,才能在对话里问"查询用户 001 的信息"。

上面还配置了一个官方现成的 filesystem Server——一行命令启动,立刻获得读写文件的能力。这就是 MCP 生态:能力即插即用。


七、三种使用路线

同一个 MCP Server,可以走三条不同的路线:

路线一:作为 MCP Client 的配置使用(正常使用)

Client(Cursor / Claude Code)读 .mcp.json 自动拉起 Server 子进程。用户在对话里用自然语言提问,Client 自动调用 query_user 返回结果。

路线二:直接运行 + MCP Inspector 调试(开发调试)

node src/mymcp.js 能验证语法和启动,但看不到输出。要交互式调试,用官方可视化调试台 MCP Inspector:

npx @modelcontextprotocol/inspector node src/mymcp.js

启动后自动打开网页调试台,能做的事:

  • 连接并列出 Server 暴露的工具 / 资源
  • 手动选择工具、填参数、触发调用,直接看返回
  • 查看两端往来的 JSON-RPC 原始消息(加深对协议的理解)

路线三:自己写代码当 MCP Client(MultiServerMCPClient)

用 @langchain/mcp-adapters 的 MultiServerMCPClient,在自己写的 LangChain 程序里连接 MCP Server,把它暴露的工具转成 LangChain 工具,直接并入工具数组:

import { MultiServerMCPClient } from '@langchain/mcp-adapters';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const mcpClient = new MultiServerMCPClient({
    'my-mcp-server': {
        transport: 'stdio',
        command: 'node',
        args: [path.join(__dirname, 'mymcp.js')],  // 用绝对路径,不依赖 cwd
    },
});

const mcpTools = await mcpClient.getTools();   // query_user 转成 LangChain 工具
const tools = [readFileTool, ..., ...mcpTools]; // 并入手写工具数组

要点:

  1. getTools() 返回标准 StructuredTool,与手写工具同类,能 bindTools()、invoke()。
  2. 路径解析差异:.mcp.json 的 args 相对配置文件目录;MultiServerMCPClient 的 args 相对进程 cwd,建议拼绝对路径(path.join(__dirname, ...))。
  3. 这样你自己的 Agent 就能像调用 read_file 一样调用 query_user,本地工具 + MCP 工具无缝混用。

八、远程 MCP:Streamable HTTP 传输

stdio 只适合本地。MCP 还支持 HTTP 传输,让 Server 部署在远端。比如接入高德地图的官方 MCP:

const mcpClient = new MultiServerMCPClient({
    'amap-maps-streamableHTTP': {
        url: 'https://mcp.amap.com/mcp?key=你的key',
    },
});

一行配置,你的 Agent 立刻获得"查询周边酒店 / 位置搜索"的能力。这也是 MCP 生态的威力——别人写好的能力,接上就能用。


九、总结:MCP = AI 世界的 HTTP

  • 解决 N×M 集成问题:工具写一次,所有 MCP Client 都能用。
  • 三个角色:Server 提供能力、Client 消费能力、Transport 负责通信。
  • stdio 本地通信:零配置、安全、生命周期跟随 Client;别用 console.log 污染 stdout。
  • Server 骨架四步:导入 → 建实例 → 注册能力 → connect 监听。
  • 工具是动作,资源是文档:工具四要素 = LangChain 四件套的翻版。
  • 三条使用路线:Client 配置、Inspector 调试、MultiServerMCPClient 自研接入。
  • 远程能力即插即用:HTTP 传输,一行配置接入高德地图等第三方 MCP。

MCP 正在成为 AI 应用的标准底座。学会它,你的工具就再也不用为每个应用重写一遍了。

标签 / TAGSmcp
L

Leo

博主

独立开发者 / Blogger,原博客「大道至简」维护者。正在把 WordPress 上攒了几年的文章与拾语迁移到 Next.js。

读者留言

COMMENTS · 0

发表留言

评论经审核后展示 · 请友善发言0/100