第 03 节:写出第一个 TypeScript tool server
本节 objectives:
- 能创建一个最小 Node.js MCP server 项目。
- 能用 TypeScript SDK 注册一个带输入 schema 的 tool。
- 能解释 stdio server 为什么不能随便往 stdout 打日志。
先让一条工具调用真的跑起来
MCP 的概念很多,但第一步可以很小:让 host 通过 stdio 连接一个 Node 进程,列出一个 tool,再调用它。
本节使用官方教程仍在采用的 v1 SDK 包路径 @modelcontextprotocol/sdk 与 zod@3。官方 TypeScript SDK 仓库的 main 分支在 2026-06-30 已经转向 v2 pre-alpha,并提示 v1.x 仍是生产推荐版本直到 v2 稳定发布。1 所以入门时先跑通 v1.x,比追 pre-alpha API 更稳。
讲解
一个最小 tool server 需要四块:
McpServer:声明 server 名称和版本。registerTool:注册 tool 名称、描述、输入 schema、handler。StdioServerTransport:让 host 通过 stdin/stdout 跟 server 说 JSON-RPC。server.connect(transport):把 server 挂到 transport 上。
stdio transport 有一个初学者很容易踩的坑:stdout 是协议通道。你往 stdout 随便 console.log("debug"),host 可能会把它当成坏掉的 JSON-RPC 消息。调试日志应该走 stderr,也就是 console.error。MCP spec 的消息层要求请求、响应、通知遵守 JSON-RPC 结构。2
跟我做一遍(worked example)
在一个空目录里创建项目:
创建 server.mjs:
这不是一个聪明摘要器,只是一个可验证的 tool。初学阶段先证明协议和 schema 能跑,再替换 handler 里的业务逻辑。
你可以先只检查 Node 是否能启动:
它会停在那里等待 stdio 消息。按 Ctrl+C 退出。不要期待它在终端打印"启动成功",因为 stdout 要留给协议。
换你补全(faded example)
把下面 tool 补完整:输入 a 和 b,返回它们的和。
参考答案:
关键不是加法,而是 schema 和 handler 对齐:输入 schema 说有两个 number,handler 就按两个 number 处理。
小结 + 通向下一节
你已经有了一个最小 tool server:server 声明身份,tool 声明输入和行为,stdio 负责协议连接。下一节我们把"上下文"和"交互模板"补进来,让 server 不再只有函数。
Footnotes
-
MCP TypeScript SDK — https://github.com/modelcontextprotocol/typescript-sdk ↩
-
MCP Base Protocol Overview — https://modelcontextprotocol.io/specification/2025-03-26/basic ↩
练习
Level 1: 在你自己的机器上创建 mcp-notes-lab,复制 worked example,确认 node server.mjs 不报错。
提示 1
用正则数 /- \[ \]/g 和 /- \[x\]/gi。
提示 2
先在普通 Node 脚本里测函数,再放回 handler。
提示 3
输出 text 用 JSON 字符串也可以,但要让人能读懂。