isboyjc/mcp-server-demo
If you are the rightful owner of mcp-server-demo and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
This is a demo project for an MCP (Model Context Protocol) Server built with TypeScript and Node.js, supporting multiple transport methods.
MCP Server Demo
这是一个支持多种传输方式的 MCP (Model Context Protocol) Server演示项目,使用 TypeScript 和 Nodejs 构建,支持 STDIO、SSE 和 StreamableHttp 三种传输方式。
功能特性
- STDIO 传输: 标准输入输出传输,适合命令行工具集成
- SSE 传输: Server-Sent Events 传输,适合 Web 应用实时通信
- StreamableHttp 传输: 可流式传输的 HTTP 传输,适合 Web API 集成
- 工具支持: 内置加法工具演示
- 命令行界面: 使用 Commander.js 提供友好的命令行界面
- 健康检查: 内置健康检查和服务信息端点
- CORS 支持: 内置跨域请求支持
- 优雅关闭: 优雅关闭服务器
安装依赖
pnpm install
构建项目
pnpm run build
使用方法
查看帮助
node build/index.js --help
输出:
Usage: mcp-server-demo [options] [command]
A demo MCP server
Options:
-V, --version display version number
-h, --help display help for command
Commands:
stdio Start MCP server with STDIO transport
sse [options] Start MCP server with SSE transport
http|streamable Start MCP server with StreamableHttp transport
help [command] display help for command
1. STDIO 传输
node build/index.js stdio
这是标准的 MCP 传输方式,适合与 Claude Desktop、Cursor 等客户端集成。
2. SSE 传输
node build/index.js sse
# 或指定端口
node build/index.js sse --port 3000
启动后可以访问:
- SSE 端点:
http://localhost:3000/sse
- 消息端点:
http://localhost:3000/message
- 健康检查:
http://localhost:3000/health
- 服务信息:
http://localhost:3000/info
3. StreamableHttp 传输
node build/index.js http
# 或者使用别名
node build/index.js streamable --port 3000
启动后可以访问:
- MCP 端点:
http://localhost:3000/mcp
- 健康检查:
http://localhost:3000/health
- 服务信息:
http://localhost:3000/info
API 端点
健康检查
curl http://localhost:3000/health
响应:
{
"status": "ok",
"transport": "sse",
"timestamp": "2024-01-01T00:00:00.000Z"
}
服务信息
curl http://localhost:3000/info
响应:
{
"name": "mcp-server-demo",
"version": "0.0.1",
"description": "A demo MCP server",
"transport": "sse",
"endpoints": {
"health": "/health",
"info": "/info",
"sse": "/sse"
},
"timestamp": "2024-01-01T00:00:00.000Z"
}
SSE 连接
使用 JavaScript 连接 SSE:
const eventSource = new EventSource('http://localhost:3000/sse');
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('Received:', data);
};
eventSource.onerror = function(error) {
console.error('SSE error:', error);
};
发送消息到 SSE
curl -X POST http://localhost:3000/message?sessionId=<session-id> \
-H "Content-Type: application/json" \
-d '{"method": "tools/list"}'
工具演示
项目内置了一个加法工具,演示 MCP 工具的使用:
// 位于 src/tools/add.ts
export function registerAddTool(server: McpServer) {
server.registerTool("add", {
title: "Addition Tool",
description: "Add two numbers",
inputSchema: { a: z.number(), b: z.number() }
}, async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
}));
}
开发说明
项目结构
src/
├── index.ts # 主服务器文件
└── tools/
└── add.ts # 加法工具实现
技术栈
- TypeScript: 类型安全的 JavaScript
- Commander: 命令行参数解析
- Node.js HTTP: 内置 HTTP 服务器
- MCP SDK: Model Context Protocol 实现
- Zod: 类型验证库
添加新工具
- 在
src/tools/
目录下创建新的工具文件 - 在
src/index.ts
中的createMcpServer
函数中注册新工具
示例:
// src/tools/multiply.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
export function registerMultiplyTool(server: McpServer) {
server.registerTool("multiply", {
title: "Multiplication Tool",
description: "Multiply two numbers",
inputSchema: { a: z.number(), b: z.number() }
}, async ({ a, b }) => ({
content: [{ type: "text", text: String(a * b) }]
}));
}
然后在 src/index.ts
中注册:
import { registerMultiplyTool } from "./tools/multiply.js";
function createMcpServer(): McpServer {
const server = new McpServer({
name: MCP_INFO.name,
version: MCP_INFO.version
});
registerAddTool(server);
registerMultiplyTool(server); // 添加这行
return server;
}
脚本命令
# 开发模式(构建并运行)
pnpm run dev
# 构建项目
pnpm run build
# 运行构建后的项目
pnpm run start
# 使用 MCP Inspector 调试
pnpm run inspector
# 发布到 npm
pnpm run publish:patch # 小版本更新
pnpm run publish:minor # 次版本更新
pnpm run publish:major # 主版本更新
部署说明
使用 PM2 部署
# 全局安装 PM2
npm install -g pm2
# 启动应用
pm2 start build/index.js --name mcp-server-sse -- sse --port 3000
pm2 start build/index.js --name mcp-server-http -- http --port 3000
# 查看状态
pm2 status
# 查看日志
pm2 logs mcp-server-sse
使用 Docker 部署
创建 Dockerfile
:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY build ./build
EXPOSE 3000
CMD ["node", "build/index.js", "sse"]
构建和运行:
docker build -t mcp-server-demo .
docker run -p 3000:3000 mcp-server-demo
与 Claude Desktop、Cursor 等集成
STDIO 传输集成
在 Claude Desktop、Cursor 等产品的MCP配置文件中添加:
{
"mcpServers": {
"mcp-server-demo": {
"command": "node",
"args": ["/path/to/your/build/index.js", "stdio"]
}
}
}
SSE 传输集成
对于支持SSE传输的客户端,可以使用HTTP配置:
{
"mcpServers": {
"mcp-server-demo-sse": {
"url": "http://localhost:3000/sse",
"type": "sse"
}
}
}
或者通过环境变量启动:
# 先启动SSE服务器
node build/index.js sse --port 3000
# 然后配置客户端连接到 http://localhost:3000/sse
StreamableHttp 传输集成
对于支持StreamableHttp传输的客户端:
{
"mcpServers": {
"mcp-server-demo-http": {
"url": "http://localhost:3000/mcp",
"type": "streamable"
}
}
}
或者通过环境变量启动:
# 先启动StreamableHttp服务器
node build/index.js http --port 3000
# 然后配置客户端连接到 http://localhost:3000/mcp
传输方式选择指南
- STDIO: 适合本地开发和桌面应用集成,最稳定
- SSE: 适合Web应用和实时通信场景,支持服务端推送
- StreamableHttp: 适合REST API风格的集成,支持流式响应
客户端集成示例
JavaScript/TypeScript 客户端
// SSE 连接示例
const eventSource = new EventSource('http://localhost:3000/sse');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('MCP Message:', data);
};
// 发送消息到服务器
const sendMessage = async (message: any, sessionId: string) => {
const response = await fetch(`http://localhost:3000/message?sessionId=${sessionId}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
return response.json();
};
Python 客户端
import requests
import json
# StreamableHttp 连接示例
class MCPClient:
def __init__(self, base_url="http://localhost:3000"):
self.base_url = base_url
def call_tool(self, tool_name, arguments):
response = requests.post(f"{self.base_url}/mcp", json={
"method": "tools/call",
"params": {
"name": tool_name,
"arguments": arguments
}
})
return response.json()
def list_tools(self):
response = requests.post(f"{self.base_url}/mcp", json={
"method": "tools/list"
})
return response.json()
# 使用示例
client = MCPClient()
result = client.call_tool("add", {"a": 5, "b": 3})
print(result)
故障排除
常见问题
-
端口已被占用
# 查找占用端口的进程 lsof -i :3000 # 杀死进程 kill -9 <PID>
-
构建失败
# 清除 node_modules 重新安装 rm -rf node_modules pnpm install
-
SSE 连接失败
- 检查 CORS 配置
- 确保防火墙允许端口访问
- 查看服务器日志
日志查看
运行时日志会显示:
- 🚀 服务启动成功
- 📡 SSE 客户端连接/断开
- 🔍 健康检查访问
- 📋 服务信息查询
- 🛑 优雅关闭信号
配置说明
主要配置在 src/index.ts
中:
const MCP_INFO = {
name: "mcp-server-demo",
version: "0.0.1",
description: "A demo MCP server"
};
const DEFAULT_PORT = 3000;
贡献指南
- Fork 项目
- 创建功能分支 (
git checkout -b feature/amazing-feature
) - 提交更改 (
git commit -m 'Add some amazing feature'
) - 推送到分支 (
git push origin feature/amazing-feature
) - 发起 Pull Request
许可证
作者
isboyjc