拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

mcp-for-beginners 实战:用 TypeScript 与 MCP SDK 构建计算器服务器(工具注册、Zod 校验与 stdio 传输全解析)

mcp-for-beginners 实战:用 TypeScript 与 MCP SDK 构建计算器服务器(工具注册、Zod 校验与 stdio 传输全解析)
  • 教程
  • 文档
  • 人工智能

【免费下载链接】mcp-for-beginners

This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.

项目地址:https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners
点击查看免费下载

这篇技术指南以 mcp-for-beginners 开源课程中的 TypeScript 示例为蓝本,完整讲解如何使用@modelcontextprotocol/sdk与zod从零构建一个基于 stdio 传输的 MCP 计算器服务器。读完本文,你将掌握 MCP Server 的标准工程结构(McpServer实例、server.tool工具注册、内容响应与错误处理)、TypeScript 项目的编译与运行配置,以及如何借助 MCP Inspector 和自写客户端对服务器进行验证。

示例定位:Getting Started 模块的 TypeScript 计算器

在 03-GettingStarted 模块 中,课程为每一种主流语言都配套了可直接运行的计算器示例,TypeScript 版本位于 03-GettingStarted/samples/typescript/,与 Java、.NET、JavaScript、Python、Rust 的同名示例一一对应,用于巩固第一课 “你的第一个 MCP Server” 中讲解的工具(Tools)概念。

该示例的核心代码非常精简:一个McpServer实例、四个算术工具(add、subtract、multiply、divide)以及一个 stdio 传输连接。它演示了 MCP TypeScript 开发中三个最关键的基础能力:

  1. 使用官方 SDK 创建并命名一个 MCP Server;
  2. 用server.tool()注册带 Zod 参数模式的工具;
  3. 通过StdioServerTransport让服务器在标准输入/输出上接收和发送 JSON-RPC 消息。

项目结构与工程配置

先看整个示例的目录布局:

03-GettingStarted/samples/typescript/ ├── README.md # 示例说明(本文的主体文档) ├── package.json # 依赖与 npm 脚本 ├── package-lock.json # 依赖锁定文件 ├── tsconfig.json # TypeScript 编译配置 └── src/ └── index.ts # 服务器唯一入口源码

package.json:依赖与脚本

package.json 中的关键配置如下:

{ "name": "tutorial-mcp", "version": "1.0.0", "main": "index.js", "type": "module", "scripts": { "start": "tsc && node ./build/index.js", "build": "tsc && node ./build/index.js" }, "dependencies": { "@modelcontextprotocol/sdk": ">=1.26.0", "openai": "^4.95.0", "zod": "^3.24.2" }, "devDependencies": { "@types/node": "^22.13.17", "typescript": "^5.8.2" } }

逐项解读:

  • "type": "module":声明项目使用 ES Module 规范,这也是源码中import语句能直接使用.js扩展名导入 SDK 子路径(如@modelcontextprotocol/sdk/server/mcp.js)的前提。
  • @modelcontextprotocol/sdk(>=1.26.0):MCP 官方 TypeScript SDK,提供McpServer、StdioServerTransport、Client等核心构造。
  • zod(^3.24.2):运行时 schema 校验库,用于声明工具的输入参数结构;SDK 会将这些 Zod schema 自动转换为 MCP 协议要求的 JSON Schema,供客户端(或 LLM)发现与调用。
  • openai(^4.95.0):从源码结构看,src/index.ts 当前并未引用该依赖,它是为后续把客户端接入 LLM(如 03-llm-client 课程)预留的。
  • start/build脚本:二者逻辑相同,均为tsc && node ./build/index.js——先编译 TypeScript,再直接运行编译产物。这意味着示例文档中的npm start实际等价于“编译 + 启动”。

tsconfig.json:编译目标

tsconfig.json 的编译配置与 01-first-server 课程中的工程模板完全一致:

{ "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "outDir": "./build", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules"] }

关键点:

  • outDir: "./build"、rootDir: "./src":源码从src/编译到build/,因此index.ts编译后成为build/index.js,这正是 npm 脚本与 Inspector 命令所指向的文件。
  • module/moduleResolution: Node16:与"type": "module"配套,让 Node.js 以 ESM 方式解析node build/index.js中的导入。
  • strict: true:开启严格类型检查,符合工程化最佳实践。

核心实现:从 SDK 到四个算术工具

示例文档展示的“计算器部分”直接取自 src/index.ts 的完整源码。下面按代码逻辑逐层展开。

创建 McpServer 实例

// mcp_calculator_server.ts - Sample MCP Calculator Server implementation in TypeScript import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; // Create an MCP server const server = new McpServer({ name: "Calculator MCP Server", version: "1.0.0" });
  • McpServer来自 @modelcontextprotocol/sdk/server/mcp.js 所引用的官方 TypeScript SDK,它封装了协议层的握手、能力声明与方法分发,开发者只需关注业务注册。
  • name与version会在协议初始化阶段通过initialize响应返回给客户端,MCP Inspector 的服务器信息面板中即可看到。

用server.tool()注册四个计算工具

示例文档给出的工具注册代码,正是本示例的核心资产:

// Define calculator tools for each operation server.tool( "add", { a: z.number(), b: z.number() }, async ({ a, b }) => ({ content: [{ type: "text", text: String(a + b) }] }) ); server.tool( "subtract", { a: z.number(), b: z.number() }, async ({ a, b }) => ({ content: [{ type: "text", text: String(a - b) }] }) ); server.tool( "multiply", { a: z.number(), b: z.number() }, async ({ a, b }) => ({ content: [{ type: "text", text: String(a * b) }] }) ); server.tool( "divide", { a: z.number(), b: z.number() }, async ({ a, b }) => { if (b === 0) { return { content: [{ type: "text", text: "Error: Cannot divide by zero" }], isError: true }; } return { content: [{ type: "text", text: String(a / b) }] }; } );

server.tool()的签名由三部分组成,理解它是掌握 MCP TypeScript 开发的关键:

  1. 工具名称(第一个参数):如"add"、"divide",客户端调用tools/call时需精确匹配该名称。

  2. 输入 schema(第二个参数):由zod声明的对象模式。z.number()表示参数必须是数字;SDK 会自动将其序列化为符合 MCP 规范的 JSON Schema,listTools返回的结果中即可看到每个工具的inputSchema。这也是 MCP 得以让 LLM“看懂”工具边界的基础——模型依据 schema 决定填入什么参数。

  3. 执行回调(第三个参数):接收已通过校验的入参,返回 MCP 内容结果。注意返回结构是

    { content: [{ type: "text", text: String(a + b) }] }

    其中content是一个内容块数组,{ type: "text", text: ... }是文本块的标准形态,客户端最终会把text内容呈现给用户或 LLM。

错误处理:isError标志

divide工具演示了 MCP 语义化的错误返回方式:

if (b === 0) { return { content: [{ type: "text", text: "Error: Cannot divide by zero" }], isError: true }; }

当除数为零时,工具并不抛异常,而是返回一个带isError: true的常规结果。该标志会在协议层被标记为工具执行错误,客户端与 LLM 可以据此识别“调用失败但服务器未崩溃”的情况。这是 MCP 工具开发中非常重要的实践:参数校验失败、业务异常都应优先考虑isError返回,而不是让进程崩溃。

stdio 传输:本地服务器的运行骨架

工具的注册只是“业务层”,要让服务器真正工作,还必须挂载传输。源码末尾的两行是关键:

// Connect the server using stdio transport const transport = new StdioServerTransport(); server.connect(transport).catch(console.error); console.log("Calculator MCP Server started");
  • StdioServerTransport让服务器通过标准输入读取 JSON-RPC 请求、通过标准输出写回响应。正如 03-GettingStarted 模块 第 5 课所述,stdio 是本地 MCP 服务器与客户端通信的推荐标准,它基于子进程通信,自带进程隔离,适合运行在本机的服务器场景。
  • server.connect(transport)返回的 Promise 需要被catch兜底,避免未处理的拒绝导致进程异常退出。
  • console.log输出会混入 stdout,而 stdout 已被 stdio 传输占用为协议通道,因此生产实践中更推荐把日志写到 stderr;这一点在 01-first-server 课程 的 TypeScript 示例中可以看到(其main()内使用console.error("MCPServer started on stdin/stdout"))。

安装与运行

示例文档给出了最简的两步操作,它们基于上文分析的工程配置可直接落地:

# 1. 安装依赖(下载 MCP SDK、zod 等) npm install # 2. 编译并启动服务器 npm start

npm start实际执行的是tsc && node ./build/index.js,即:

  1. tsc依据tsconfig.json将src/index.ts编译为build/index.js;
  2. node ./build/index.js启动服务器并挂载 stdio 传输。

如果你只想编译不运行,可单独执行npx tsc;修改源码后重新npm start即可完成重编译。启动成功后,终端会打印Calculator MCP Server started,此时进程处于“等待标准输入消息”的阻塞状态——这正是 stdio 服务器的正常形态,它本身不会打印日志输出结果,而是要等客户端(如 Inspector 或自写客户端)发起请求。

验证与调试:Inspector 与自写客户端

使用 MCP Inspector 交互测试

MCP Inspector 是课程推荐的图形化调试工具。参照 01-first-server 课程 中 TypeScript 的启动方式,对本示例可运行:

npx @modelcontextprotocol/inspector node build/index.js

Inspector 会用给定的命令拉起服务器进程,随后在浏览器中打开本地 Web 界面。连接成功后,在Tools → List Tools中应能看到add、subtract、multiply、divide四个工具;选中任一工具填入参数并点击运行,即可实时看到结果。例如选中divide并输入a=1, b=2,返回内容为1 / 2 = 0.5(除法结果),工具列表与运行效果如下图所示:

连接建立阶段,Inspector 左侧配置区会显示传输类型(STDIO)与启动命令,连接成功后界面左下角出现绿色Connected标识:

用自写客户端做编程化验证

除了图形界面,课程 02-client(编写客户端) 展示了编程化验证服务器的方式。参照其中的 TypeScript 客户端模式,可以写一个最小客户端连接本示例:

import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; // 用 node 拉起我们的计算器服务器 const transport = new StdioClientTransport({ command: "node", args: ["build/index.js"] }); const client = new Client({ name: "example-client", version: "1.0.0" }); await client.connect(transport); // 列出服务器暴露的工具 const tools = await client.listTools(); // 调用 add 工具 const result = await client.callTool({ name: "add", arguments: { a: 5, b: 3 } });

注意两点:

  • StdioClientTransport的command/args必须与服务器的启动方式一致,本示例即node build/index.js(先npm start前的编译产物)。
  • listTools返回的 schema 中可以看到每个工具的inputSchema,这正是zod声明被协议化的直接证据:add的参数为{ a: number, b: number }。

扩展方向:资源、提示词与多语言对照

本示例聚焦“工具(Tools)”这一 MCP 原语,而一个完整的 MCP Server 通常还包括资源(Resources)与提示词(Prompts)。如果你希望在此基础上继续深化:

  • 参考 01-first-server 课程 的完整 TypeScript 服务器,它额外演示了server.resource()(如greeting://{name}动态资源模板)与server.prompt()(如review-code代码审查提示词)的注册方式,并给出了可一键复制的 完整解决方案。
  • 对照同一计算器在不同语言下的实现,可快速理解 MCP 的“一次掌握、多语言复用”特性:Java 计算器、.NET 计算器、JavaScript 计算器、Python 计算器 与 Rust 计算器。

小结

TypeScript 计算器示例虽短,却浓缩了 MCP 服务器开发的完整链路:McpServer实例化 →zod驱动的工具 schema →server.tool()注册 →StdioServerTransport挂载 → Inspector/客户端验证。理解这套骨架后,你可以把add/divide替换为任意业务工具(读取文件、查询数据库、调用远程 API),并按照 01-first-server 与 02-client 的课程路径,逐步构建出资源、提示词齐备的生产级 MCP Server。

  • 教程
  • 文档
  • 人工智能

【免费下载链接】mcp-for-beginners

This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.

项目地址:https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表