- 教程
- 文档
- 人工智能
【免费下载链接】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.
本篇技术指南基于开源课程 mcp-for-beginners 中 05-stdio-server 章节 的 TypeScript 官方解决方案,完整讲解如何在 Node.js 环境中基于 MCP 规范 2025-06-18 推荐的stdio 传输(Standard Input/Output Transport)构建、运行、调试并接入 MCP 客户端。读完本文,你将掌握 stdio 服务器从依赖安装、编译、启动到使用 MCP Inspector 测试、配置 Claude Desktop 接入的全流程,并能从源码层面理解 JSON-RPC 消息处理、工具注册与优雅退出等实现细节。
为什么从 SSE 迁移到 stdio 传输
MCP 规范在 2025-06-18 版本中正式弃用了独立的 SSE(Server-Sent Events)传输,并将其替换为 Streamable HTTP;同时明确将stdio定为本地服务器的推荐传输方式。课程仓库中的 TypeScript 解决方案也同步完成了这一迁移,解决方案 README 的开头即给出了明确提示。
stdio 传输的工作模型非常直观:
- 简单通信:服务器从标准输入(
stdin)读取 JSON-RPC 消息,并向标准输出(stdout)写入消息; - 基于子进程:MCP 客户端将服务器作为子进程启动;
- 消息格式:每条消息都是独立的 JSON-RPC 请求、通知或响应,以换行符分隔;
- 日志通道:服务器可以(且应当)向标准错误(
stderr)写入 UTF-8 字符串用于日志。
与之配套的协议约束是:消息必须以换行符分隔且不得包含内嵌换行;服务器不得向stdout写入任何非 MCP 消息内容;客户端也不得向服务器stdin写入非 MCP 消息。这些约束决定了后续所有日志与调试实践。
环境准备与项目结构
运行本 TypeScript 解决方案需要:
- Node.js 18+(或更高版本);
- npm 或 yarn包管理器。
解决方案的目录结构如下(源码目录):
typescript/ ├── src/ │ └── index.ts # 主服务器实现 ├── build/ # 编译生成的 JavaScript ├── package.json # 项目配置 ├── tsconfig.json # TypeScript 配置 └── README.md # 本文档其中 package.json 声明了核心依赖:@modelcontextprotocol/sdk(版本要求>=1.26.0)提供Server与StdioServerTransport,zod(^3.24.2)用于工具入参的运行时校验;开发依赖包括typescript与@types/node。项目以"type": "module"使用 ESM 模块体系,并通过"bin"字段将编译产物build/index.js暴露为mcp-stdio-server可执行命令。tsconfig.json 采用ES2022目标、Node16模块解析,strict模式开启,编译输出到build目录。
安装与编译
进入解决方案目录后依次执行:
npm install npm run build第一步安装 MCP SDK、zod 及 TypeScript 工具链;第二步通过tsc将src/index.ts编译到build/目录(对应 package.json 中的"build": "tsc"脚本)。若未编译而直接启动,npm start将因找不到build/index.js而失败。
启动服务器:看起来“卡住”是正常现象
stdio 服务器与旧的 SSE 服务器运行方式完全不同——它不会启动任何 Web 服务器,而是通过 stdin/stdout 与客户端通信:
npm start启动后终端会“看似冻结”,这是正常现象:服务器正在等待来自stdin的 JSON-RPC 消息。真正的输入来源于客户端(如 MCP Inspector、Claude Desktop),进程会一直阻塞在消息读取循环上,直到收到SIGINT/SIGTERM信号。
源码剖析:TypeScript stdio 服务器的实现骨架
完整的服务器实现位于 src/index.ts,其核心脉络可分为五步:导入 SDK 组件、创建服务器实例、注册工具、连接传输、处理进程信号。
1. 创建服务器实例
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod"; const server = new Server( { name: "example-stdio-server", version: "1.0.0", }, { capabilities: { tools: {}, }, } );Server构造函数的第一个参数声明服务器标识(名称与版本),第二个参数声明能力集——此处仅声明了tools(工具调用)能力,这正是 MCP 初始化握手阶段返回给客户端的能力清单。
2. 注册工具清单与调用处理器
服务器通过两个请求处理器完成工具协议:ListToolsRequestSchema返回工具清单,CallToolRequestSchema分发具体调用:
server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "add", description: "Add two numbers together", inputSchema: { type: "object", properties: { a: { type: "number", description: "First number" }, b: { type: "number", description: "Second number" }, }, required: ["a", "b"], }, }, // multiply / get_greeting / get_server_info ... ], }; }); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; switch (name) { case "add": { const { a, b } = AddArgsSchema.parse(args); const result = a + b; console.error(`Adding ${a} + ${b} = ${result}`); return { content: [{ type: "text", text: `${a} + ${b} = ${result}` }], }; } // ... default: throw new Error(`Unknown tool: ${name}`); } });这里有两个值得注意的实现细节:
- zod 校验:
AddArgsSchema、MultiplyArgsSchema、GreetingArgsSchema分别定义了各工具的入参结构(数字对、名称字符串),在调用处理器中通过schema.parse(args)完成运行时校验,非法入参会抛出解析错误并作为 MCP 错误返回给客户端; - stderr 日志:每个工具在执行时通过
console.error()记录处理过程——这是 stdio 服务器的铁律,因为stdout专用于 MCP 消息,任何console.log()都会污染协议流、导致客户端解析失败。
3. 连接 stdio 传输与优雅退出
async function runServer() { console.error("Starting MCP stdio server..."); const transport = new StdioServerTransport(); await server.connect(transport); console.error("Server connected via stdio transport"); } process.on("SIGINT", () => { console.error("Received SIGINT, shutting down gracefully"); process.exit(0); }); process.on("SIGTERM", () => { console.error("Received SIGTERM, shutting down gracefully"); process.exit(0); }); runServer().catch((error) => { console.error("Server error:", error); process.exit(1); });StdioServerTransport封装了底层 stdin/stdout 流与换行分隔的 JSON-RPC 编解码;server.connect(transport)建立连接后即进入消息循环。源码额外注册了SIGINT/SIGTERM处理器,保证进程被终止时能输出日志并干净退出,运行期异常则统一记录后以退出码 1 结束。
使用 MCP Inspector 测试服务器
MCP Inspector 是官方推荐的调试与测试工具,它以 Web 界面方式将服务器作为子进程启动,并可交互式测试全部工具。解决方案在 package.json 中预置了脚本:
npm run inspector等效于直接执行:
npx @modelcontextprotocol/inspector node build/index.jsInspector 启动后会自动完成三步工作:
- 将
node build/index.js作为子进程启动; - 打开用于测试的 Web 界面;
- 允许你交互式地测试服务器的所有工具。
在 Web 界面中可以查看服务器能力(capabilities)、以不同参数调用各工具、实时监控客户端与服务器之间交换的 JSON-RPC 消息,并借此排查连接问题。
服务器提供的工具
该 TypeScript 解决方案注册了四个工具:
| 工具名 | 签名 | 功能 | 返回示例 |
|---|---|---|---|
add | add(a, b) | 两个数字相加 | 3 + 4 = 7 |
multiply | multiply(a, b) | 两个数字相乘 | 3 × 4 = 12 |
get_greeting | get_greeting(name) | 生成个性化问候 | Hello, Bob! Welcome to the MCP stdio server. |
get_server_info | get_server_info() | 获取服务器元信息 | JSON 形式的名称、版本、传输方式与能力清单 |
其中get_server_info返回的 JSON 包含server_name、version、transport: "stdio"、capabilities: ["tools"]以及对齐 MCP 2025-06-18 规范的描述文本,可直接用于客户端侧的状态自检。
接入 Claude Desktop 等 MCP 客户端
stdio 服务器的优势之一就是零网络配置接入。以 Claude Desktop 为例,在其claude_desktop_config.json中注册如下配置:
{ "mcpServers": { "example-stdio-server": { "command": "node", "args": ["path/to/build/index.js"] } } }配置要点:command为可执行程序(这里是node),args为编译产物的绝对或相对路径。客户端启动时会以子进程方式拉起该命令,并通过 stdin/stdout 完成 MCP 协议握手与工具调用。如果你已经npm install -g或将本地node_modules/.bin加入 PATH,也可以改用mcp-stdio-server作为命令。此模式同样适用于 VS Code 的 MCP 配置(可参考课程中的 04-vscode 章节)。
stdio 与 SSE 传输对比
| 维度 | stdio 传输(当前标准) | SSE 传输(已弃用) |
|---|---|---|
| 部署形态 | 子进程模型,客户端直接拉起服务器 | 需要 Express 等 HTTP 服务器 |
| 通信方式 | JSON-RPC over stdin/stdout | SSE 端点 + 复杂路由与会话管理 |
| 依赖数量 | 极少(仅 MCP SDK 与参数校验库) | 较多(Express、HTTP 处理等) |
| 安全考量 | 无 HTTP 端点暴露,攻击面更小 | 需要额外的 HTTP 安全措施 |
| 性能 | 进程间管道通信,开销低 | 基于 HTTP 与长连接,开销更高 |
| 状态 | 推荐用于本地服务器 | 自 MCP 2025-06-18 起弃用 |
简言之,stdio 方案以更简单的设置、更好的安全性和更优的性能取代了旧的 SSE 方式,是目前本地 MCP 服务器的主流实现路径;需要远程访问时则使用 Streamable HTTP(可进一步学习 06-http-streaming 章节)。
开发与调试建议
结合源码实现,这里整理几条直接可用的实践建议:
- 日志只走
stderr:源码中所有console.error(...)调用都指向这一原则——stdout是协议通道,绝不能混入日志; - 先编译再测试:每次修改
src/index.ts后执行npm run build,否则启动的是旧的build/index.js; - 优先用 Inspector 做可视化调试:它展示完整 JSON-RPC 消息流,能直观定位消息格式错误;
- 保证 JSON 消息格式正确:所有发给
stdout的内容必须是规范、换行分隔的 MCP 消息; - 处理进程信号:参照源码注册
SIGINT/SIGTERM监听,确保服务器被 Ctrl+C 或系统终止时能优雅退出; - 先注册简单工具再扩展:基础工具调通后再增加复杂逻辑,便于隔离问题。
跨语言参考:同构的 stdio 实现
该课程在同一章节下提供了多语言实现,代码逻辑与 TypeScript 版本高度对应,可作为跨语言迁移的参考:
- Python(server.py):使用
mcp.server.Server配合stdio_server()上下文管理器,通过@server.list_tools()与@server.call_tool()装饰器注册工具,同样将日志配置到 stderr; - .NET(Program.cs 与 Tools.cs):基于
Host.CreateApplicationBuilder+AddMcpServer().WithStdioServerTransport().WithTools<Tools>()的依赖注入风格,工具类通过[McpServerTool]特性声明,并显式配置AddConsole()日志输出; - 多语言解决方案总览见 solution/README.md。
三种实现遵循完全相同的协议语义(同一组工具名、相同的 JSON-RPC 消息处理、相同的 stderr 日志约束),这印证了 MCP 作为跨语言协议的互操作性设计。
小结与下一步
本文以课程仓库中的 TypeScript 官方解决方案为主线,完整覆盖了 stdio 传输的动机、工程搭建、源码实现、Inspector 调试、客户端接入与跨语言对照。核心要点可归纳为:stdio 是当前 MCP 规范推荐的本地服务器传输方式,其本质是客户端以子进程方式启动服务器并通过 stdin/stdout 交换换行分隔的 JSON-RPC 消息,而正确的日志通道(stderr)与工具注册方式是构建可靠服务器的关键。
若要继续深入,可以按课程路径学习:Streamable HTTP 传输(06-http-streaming)、MCP 安全最佳实践(02-Security)以及生产部署策略(09-deployment);也可参考 samples 目录 中 JavaScript、Java、Rust、C# 等语言的 Calculator 示例,观察不同运行时下相同的 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.
相关推荐
MCP for Beginners 实战指南:使用 stdio 传输构建跨语言 MCP 服务器
MCP for Beginners 实战指南:使用 stdio 传输构建跨语言 MCP 服务器 本篇技术指南以 mcp for beginners 开源课程中
教程文档人工智能MCP for Beginners:使用 TypeScript 构建基于 stdio 传输的 MCP 服务器(2025-06-18 规范)
MCP for Beginners:使用 TypeScript 构建基于 stdio 传输的 MCP 服务器(2025 06 18 规范) 本篇文章围绕开源课程
教程文档人工智能MCP stdio 传输实战:基于 mcp-for-beginners 课程构建 Python 本地 MCP 服务器
MCP stdio 传输实战:基于 mcp for beginners 课程构建 Python 本地 MCP 服务器 导读 本篇技术指南以 mcp for be
教程文档人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考