导航菜单

  • 1.claudecode
  • 2.claudecode
  • readline
  • iconv-lite
  • mcp
  • skills
  • gray-matter
  • modelcontextprotocol
  • 1. 这个 SDK 是做什么的
  • 2. 学前准备
    • 2.1 zod 是做什么的
    • 2.3 stdio 传输
  • 3. 安装
  • 4. Server 端:McpServer 与 registerTool
  • 5. Client 端:连接、列工具、调用
  • 6. SDK 常用 API 对照(Server / Client)
  • 7. 把 MCP 工具转成 OpenAI 风格 schema(可选)
  • 8. 知识点速查

1. 这个 SDK 是做什么的 #

MCP 是协议(消息格式、能力约定);@modelcontextprotocol/sdk 是官方提供的 JavaScript/TypeScript 实现,帮你处理:

  • JSON-RPC 消息的收发与握手
  • McpServer 上注册 Tool、声明参数类型
  • Client 连接 Server、listTools、callTool

你不用自己拼每一帧 JSON;按 SDK 的 API 写 Server/Client 即可。

2. 学前准备 #

2.1 zod 是做什么的 #

新版 SDK 注册 Tool 时,常用 zod 描述参数类型(如 z.string()、z.number())。它会在注册阶段生成 JSON Schema,供 AI 客户端理解「这个工具要传哪些字段」。 只需会写:

inputSchema: { name: z.string().describe('名字') }

2.3 stdio 传输 #

  • Server:StdioServerTransport —— 从 stdin 读、向 stdout 写 MCP 消息。
  • Client:StdioClientTransport —— 用 spawn 启动 Server 子进程,与子进程 stdin/stdout 通信。

3. 安装 #

在练习目录打开终端(PowerShell 或 CMD):

npm init -y
npm install @modelcontextprotocol/sdk zod
  • @modelcontextprotocol/sdk:MCP 官方 SDK。
  • zod:Tool 的 inputSchema 依赖(与 SDK 配套使用)。

4. Server 端:McpServer 与 registerTool #

Server 端典型步骤:

  1. new McpServer({ name, version })
  2. server.registerTool(工具名, { description, inputSchema }, 回调)
  3. await server.connect(new StdioServerTransport())

回调返回形如 { content: [{ type: 'text', text: '...' }] } 的结果,Client 的 callTool 会收到。

下面整段保存为 01-mcp-server.js。单独 node 01-mcp-server.js 会看起来像「卡住」——它在等 Client 发消息,属正常现象。

// 从 SDK 服务端入口引入 McpServer
const { McpServer } = require('@modelcontextprotocol/sdk/server/mcp.js');
// 引入 stdio 传输(标准输入/输出)
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
// 引入 zod,定义工具参数类型
const { z } = require('zod');

// 创建 MCP 服务实例
const server = new McpServer({
  name: 'sdk-tutorial-server',
  version: '1.0.0',
});

// 注册名为 greet 的工具
server.registerTool(
  // 工具名称(Client 调用时用这个名字)
  'greet',
  {
    // 给 AI / 人类看的说明
    description: '通过名字向某人问好',
    // 参数:一个字符串 name
    inputSchema: {
      name: z.string().describe('要问候的人的名字'),
    },
  },
  // 被调用时执行;参数来自 Client 的 arguments
  async ({ name }) => ({
    content: [{ type: 'text', text: `你好,${name}!` }],
  }),
);

// 异步主函数
async function main() {
  // 创建 stdio 传输
  const transport = new StdioServerTransport();
  // 绑定传输并开始处理消息
  await server.connect(transport);
}

// 启动;失败则打印并退出
main().catch((err) => {
  console.error(err);
  process.exit(1);
});

5. Client 端:连接、列工具、调用 #

Client 端典型步骤:

  1. new StdioClientTransport({ command, args }) 拉起 Server 进程
  2. new Client({ name, version })
  3. await client.connect(transport)
  4. await client.listTools() / await client.callTool({ name, arguments })
  5. await client.close()

保存为 02-mcp-client.js,与 01-mcp-server.js 同目录。运行:

node 02-mcp-client.js
// 拼接 server 脚本路径
const path = require('path');
// SDK 客户端类
const { Client } = require('@modelcontextprotocol/sdk/client/index.js');
// stdio 客户端传输
const { StdioClientTransport } = require('@modelcontextprotocol/sdk/client/stdio.js');

// 主流程
async function main() {
  // 与本文件同目录的 server 脚本
  const serverPath = path.join(__dirname, '01-mcp-server.js');

  // 用当前 Node 启动 server 子进程
  const transport = new StdioClientTransport({
    command: process.execPath,
    args: [serverPath],
  });

  // 创建 Client(名称/version 会在握手时上报)
  const client = new Client({
    name: 'sdk-tutorial-client',
    version: '1.0.0',
  });

  // 连接并完成 MCP 握手
  await client.connect(transport);

  // 列出 Server 注册的所有工具
  const { tools } = await client.listTools();
  console.log(
    'SDK 返回的工具:',
    tools.map((t) => t.name).join(', '),
  );

  // 调用 greet
  const result = await client.callTool({
    name: 'greet',
    arguments: { name: 'SDK' },
  });

  // 提取 text 类型内容
  const text =
    result.content
      ?.filter((item) => item.type === 'text')
      .map((item) => item.text)
      .join('') || '(无文本)';

  console.log('callTool 结果:', text);

  // 关闭连接与子进程
  await client.close();
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

预期输出(大意):

SDK 返回的工具: greet
callTool 结果: 你好,SDK!

6. SDK 常用 API 对照(Server / Client) #

入门阶段记住下表即可;方法名以你安装的 SDK 版本为准,若报错请对照 npm 文档。

端 类 / 方法 作用
Server McpServer 创建服务
Server registerTool(...) 注册可被调用的工具
Server StdioServerTransport stdio 通信
Server server.connect(transport) 开始监听
Client Client 创建客户端
Client StdioClientTransport spawn Server
Client client.connect(transport) 握手连接
Client client.listTools() 获取工具列表
Client client.callTool({ name, arguments }) 调用工具
Client client.close() 断开连接

7. 把 MCP 工具转成 OpenAI 风格 schema(可选) #

mcp_client.js 会把 listTools() 的结果转成 DeepSeek / OpenAI 的 tools 数组。

// path
const path = require('path');
// Client
const { Client } = require('@modelcontextprotocol/sdk/client/index.js');
// stdio 传输
const { StdioClientTransport } = require('@modelcontextprotocol/sdk/client/stdio.js');

// 将 MCP 的 tool 定义转为 OpenAI tools 数组里的一项(简化版)
function mcpToolToOpenAI(tool) {
  const schema = tool.inputSchema || { type: 'object', properties: {} };
  return {
    type: 'function',
    function: {
      name: tool.name,
      description: tool.description || `MCP 工具:${tool.name}`,
      parameters: schema,
    },
  };
}

async function main() {
  const serverPath = path.join(__dirname, '01-mcp-server.js');
  const transport = new StdioClientTransport({
    command: process.execPath,
    args: [serverPath],
  });
  const client = new Client({ name: 'schema-demo', version: '1.0.0' });
  await client.connect(transport);

  const { tools } = await client.listTools();
  const openAiTools = tools.map(mcpToolToOpenAI);

  console.log(JSON.stringify(openAiTools, null, 2));

  await client.close();
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

说明: 真实 Agent 会把这类 schema 传给 Chat Completions 的 tools 参数;收到 tool_calls 后再 callTool 把结果写回对话。

8. 知识点速查 #

主题 记住这一句
包名 @modelcontextprotocol/sdk
Server 核心 McpServer + registerTool + StdioServerTransport
Client 核心 Client + StdioClientTransport + listTools / callTool
参数类型 用 zod 写 inputSchema
本地测试 Client spawn Server,不要单独测 Server stdin
← 上一节 mcp 下一节 readline →

访问验证

请输入访问令牌

Token不正确,请重新输入