@workforadmin/demo-mcp-stdio
v1.0.2
Published
A simple MCP server using STDIO transport (JavaScript)
Readme
demo-mcp-stdio
一个使用 STDIO 传输实现的简易 MCP(Model Context Protocol)服务器示例,使用 Node.js 与 @modelcontextprotocol/sdk 构建。内置三个工具:greet、add 和 calculateZodiac(星座计算工具)。
背景
- MCP(Model Context Protocol)是一套让工具(Tools)、数据源(Resources/Prompts)通过统一协议接入到智能体/聊天模型的标准。
- 本示例使用 STDIO 作为传输层:客户端通过启动该脚本进程,与其标准输入/输出建立双向通信,进行 MCP 的握手与后续调用。
功能概览
- 工具注册:
greet:输入name(string),返回问候文本。add:输入a、b(number),返回求和结果。calculateZodiac:输入year、month、day(number),返回对应的星座信息及详细特性描述。
- 入参校验:使用
zod描述与校验工具的inputSchema。 - 返回格式:按照 MCP 约定返回
content数组,示例中为{ type: 'text', text: '...' }。 - 诊断输出:在工具执行期间,将参数与
requestId(来自extra)输出到stderr,便于调试。
目录结构
demo-mcp-stdio/
├── index.js # MCP 服务器(工具注册与启动)
├── basicTools.js # 基础工具模块(greet、add)
├── zodiacTool.js # 星座计算工具模块
├── zodiacUtils.js # 星座数据与计算工具
├── client-test.js # 自测客户端(通过 STDIO 连接并调用工具)
├── package.json # 项目配置(bin、scripts、依赖)
└── package-lock.json环境要求
Node.js >= 18(建议使用 LTS 版本)- 网络连接(用于安装依赖)
安装与运行
- 安装依赖:
npm install - 本地自测(推荐):
node client-test.js- 这会在同一进程树内通过 STDIO 启动并连接到
index.jsMCP 服务器。 - 预期输出(示例):
Available tools: greet, add greet result: {"content":[{"type":"text","text":"Hello, World!"}]} add result: {"content":[{"type":"text","text":"The sum of 2 and 3 is 5"}]} - 同时会在
stderr中看到类似:[greet] args: {"name":"World"} extra: {"requestId":"..."} [add] args: {"a":2,"b":3} extra: {"requestId":"..."}
- 这会在同一进程树内通过 STDIO 启动并连接到
- 单独启动服务器(需要有其他 MCP 客户端来连接):
npm start # 或 node index.js # 或(公开作用域包的直接调用,跳过交互安装) npx -y @workforadmin/demo-mcp-stdio@latest # 兼容写法(显式指定包与命令名,Windows 更稳) npx -y -p @workforadmin/demo-mcp-stdio demo-mcp-stdio- 注意:启动成功后会在
stderr输出[mcp] stdio server started and waiting for client...];进程将常驻并等待 MCP 客户端建立连接并发送请求。
- 注意:启动成功后会在
调用流程(STDIO + MCP)
以下为 client-test.js 与 index.js 的交互流程摘要:
- 客户端创建并启动传输:
StdioClientTransport以process.execPath(Node 可执行程序)运行index.js,并接管其stdin/stdout。
- 握手与连接:
- 客户端执行
client.connect(transport),与服务器完成 MCP 握手(包含名称、版本信息)。
- 客户端执行
- 枚举工具:
- 客户端调用
client.listTools({}),服务端返回可用工具列表:greet、add。
- 客户端调用
- 执行工具:
- 客户端调用
client.callTool({ name: 'greet', arguments: { name: 'World' } })。 - 服务端根据
zod定义校验入参,通过后执行并返回content。 - 同理执行
add:client.callTool({ name: 'add', arguments: { a: 2, b: 3 } })。
- 客户端调用
- 关闭连接:
- 客户端执行
transport.close()关闭 STDIO 连接,结束会话。
- 客户端执行
关键代码片段
服务器(
index.js):#!/usr/bin/env node const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js"); const { StdioServerTransport, } = require("@modelcontextprotocol/sdk/server/stdio.js"); const { z } = require("zod"); // 引入工具模块 const { greetTool, addTool } = require("./basicTools"); const { calculateZodiacTool } = require("./zodiacTool"); const server = new McpServer({ name: "demo-mcp-stdio", version: "1.0.2", }); // 注册工具 server.registerTool( "greet", { inputSchema: { name: z.string().describe("Your name") } }, greetTool ); server.registerTool( "add", { inputSchema: { a: z.number().describe("First number"), b: z.number().describe("Second number"), }, }, addTool ); server.registerTool( "calculateZodiac", { inputSchema: { year: z.number().min(1900).max(2100).describe("出生年份"), month: z.number().min(1).max(12).describe("出生月份"), day: z.number().min(1).max(31).describe("出生日期"), }, }, calculateZodiacTool ); (async () => { try { const transport = new StdioServerTransport(); await server.connect(transport); console.error("[mcp] stdio server started and waiting for client..."); // 保持事件循环活跃,避免在某些环境下立即退出 process.stdin.resume(); } catch (err) { console.error("[mcp] fatal error:", err?.stack || err); process.exit(1); } })();客户端(
client-test.js):const { Client, } = require("@modelcontextprotocol/sdk/dist/cjs/client/index.js"); const { StdioClientTransport, } = require("@modelcontextprotocol/sdk/dist/cjs/client/stdio.js"); // 通过 STDIO 启动 index.js 并连接,随后 listTools / callTool
与其他 MCP 客户端集成
- 任何支持 MCP STDIO 的客户端都可以直接通过启动该脚本进程并与其
stdin/stdout通信来集成。 - 典型做法:
- 在客户端侧配置一个 命令路径(如
node path/to/index.js或打包后的可执行文件), - 指定工作目录(
cwd)与必要的环境变量, - 建立连接后使用
listTools、callTool获取能力与进行调用。
- 在客户端侧配置一个 命令路径(如
Cherry Studio 配置示例
以下是在 Cherry Studio 的配置文件中使用 mcpServers 的 JSON 示例:
- 全局安装的非作用域包
{
"mcpServers": {
"demo-mcp-stdio": {
"transport": "stdio",
"command": "demo-mcp-stdio",
"args": []
}
}
}- 项目内安装并用
npx调用
{
"mcpServers": {
"demo-mcp-stdio": {
"transport": "stdio",
"command": "npx",
"args": ["demo-mcp-stdio"],
"cwd": "D:\\Path\\To\\YourProject"
}
}
}- 直接运行本地源码(无需发布/安装)
{
"mcpServers": {
"demo-mcp-stdio-local": {
"transport": "stdio",
"command": "node",
"args": ["D:\\PythonCode\\mcp-server\\node\\demo-mcp-stdio\\index.js"]
}
}
}- 作用域包(公开发布后)
{
"mcpServers": {
"demo-mcp-stdio": {
"transport": "stdio",
"command": "demo-mcp-stdio",
"args": []
}
}
}或使用 npx(公开作用域包,跳过交互并指定最新版;Windows 如解析不到 npx 可改为 npx.cmd):
{
"mcpServers": {
"demo-mcp-stdio": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@workforadmin/demo-mcp-stdio@latest"]
}
}
}或显式指定包与命令名(更稳的跨平台写法):
{
"mcpServers": {
"demo-mcp-stdio": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "-p", "@workforadmin/demo-mcp-stdio", "demo-mcp-stdio"]
}
}
}windows
{
"mcpServers": {
"demo-mcp-stdio": {
"command": "npx",
"args": ["-y", "@workforadmin/demo-mcp-stdio@latest"]
}
}
}字段说明
transport: 填stdio。command: 可执行命令(demo-mcp-stdio/npx/node)。args: 参数数组。cwd: 可选,指定工作目录。env: 可选,附加环境变量。
注意事项
- Windows 路径在 JSON 中用双反斜杠:
D\\\\...。 - 首次公开作用域包需
npm publish --access public。
- Windows 路径在 JSON 中用双反斜杠:
扩展建议
- 新增工具:
- 在单独的模块文件中实现工具逻辑
- 在
index.js中导入并注册工具:server.registerTool('toolName', { inputSchema: ... }, toolFunction) - 使用
zod定义并描述入参,确保校验与文档化清晰 - 返回内容遵循 MCP 约定(如
content: [{ type: 'text', text: '...' }])
- 错误处理:
- 在工具内部捕获异常并返回合适的错误信息或使用协议中定义的错误码。
- 日志:
- 继续使用
stderr输出诊断信息,便于在不同客户端环境下观察。
- 继续使用
许可证
- MIT(见
package.json)
版本历史
- 1.0.2(当前):添加星座计算工具,重构代码结构为模块化设计
- 1.0.0:初始版本,包含基础的 greet 和 add 工具
