[MCP] setRequestHandler

Schema

MCP 里面提供了一组 Schema.

Schema 由 TypeScript + Zod 定义,制作成 JSON Schema,用于验证协议消息结构

在 SDK 中,每个 JSON‑RPC 方法(如 resources/listtools/call)都对应相应的 Zod Schema,比如:

  • ReadResourceRequestSchema
  • ListResourcesRequestSchema
  • CallToolRequestSchema
  • ListPromptsRequestSchema

这些 schema 的功能包括:

  • 校验请求结构 严格保证参数类型与字段是否存在;
  • 生成 TS 类型,提高类型安全;
  • 生成 JSON Schema,用于能力声明或与客户端协商能力。

例如 ReadResourceRequestSchema 实际就等价于:

const ReadResourceRequestSchema = z.object({
  method: z.literal("resources/read"),
  params: z.object({
    uri: z.string().describe("资源的 URI,格式如 file://、http://、bananaphone://"),
  }),
});

因此 MCP 提供的 Schema 可以调用 zod 对象上面的方法:

import { ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";

// 模拟请求参数
const requestParams = {
  method: "resources/read",
  params: {
    uri: "bananaphone://info",
  },
};
// 校验请求
const result = ReadResourceRequestSchema.safeParse(requestParams);

if (!result.success) {
  console.error("参数格式不对:", result.error.format());
} else {
  console.log("✅ 参数合法:", result.data);
}

常见请求 Schema 结构一览

功能 Schema 名 结构
读取资源 ReadResourceRequestSchema { method: "resources/read", params: { uri } }
列出资源 ListResourcesRequestSchema { method: "resources/list", params: {} }
列出资源模板 ListResourceTemplatesRequestSchema { method: "resources/templates", params: {} }
列出工具 ListToolsRequestSchema { method: "tools/list", params: {} }
调用工具 CallToolRequestSchema { method: "tools/call", params: { function, args } }
列出提示词 ListPromptsRequestSchema { method: "prompts/list", params: {} }
调用提示词 CallPromptRequestSchema { method: "prompts/call", params: { id, input } }

setRequestHandler

这是 MCP SDK 提供的底层方法,用于注册对某个 JSON-RPC 请求类型 的处理函数。

MCP 使用 JSON-RPC 2.0 协议,客户端发送:

{
  "jsonrpc": "2.0",
  "method": "resources/read",
  "params": { ... }
}

SDK 内部为每种 method 提供一个对应的 Schema,setRequestHandler() 会:

  1. 接收请求:拦截特定 method(如 "tools/list"
  2. Schema 校验请求结构:如果校验失败,返回错误;否则进入 handler
  3. 执行你的 handlerFunction:将 params 提供给你处理逻辑
  4. 将你的返回值转为标准 JSON-RPC 响应:自动处理错误、封装 result 字段
server.setRequestHandler(SomeRequestSchema, async (request) => {
  const params = request.params;

  // 做点什么
  return {
    ...yourResponseObject,
  };
});
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  ListToolsRequestSchema,
  CallToolRequestSchema,
  ListResourcesRequestSchema,
  ReadResourceRequestSchema,
  ListResourceTemplatesRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server(
  {
    name: "resource-server",
    version: "0.1.0",
  },
  {
    capabilities: {
      resources: {},
      tools: {},
    },
  }
);

server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "sum",
        description: "计算两个数字的和",
        inputSchema: {
          type: "object",
          properties: {
            a: { type: "number", description: "加数 A" },
            b: { type: "number", description: "加数 B" },
          },
          required: ["a", "b"],
        },
      },
    ],
  };
});

server.setRequestHandler(CallToolRequestSchema, async (requests) => {
  const { name: toolName, arguments: args } = requests.params;

  if (toolName === "sum") {
    const { a, b } = args;
    const result = a + b;

    return {
      content: [
        {
          type: "text",
          text: `计算结果为:${result}`,
        },
      ],
    };
  }
});
posted @ 2025-10-01 14:09  Zhentiw  阅读(5)  评论(0)    收藏  举报