这是一个支持多种传输方式的MCP(模型上下文协议)服务器演示项目。该项目使用TypeScript和Nodejs构建,并支持三种传输方式:STDIO、SSE和StreamableHttp。
pnpm install
pnpm run build
node build/index.js --help
输出:
用法: mcp-server-demo [选项] [命令]
一个MCP服务器演示
选项:
-V, --version 显示版本号
-h, --help 显示命令帮助
命令:
stdio 使用STDIO传输启动MCP服务器
sse [选项] 使用SSE传输启动MCP服务器
http|streamable 使用StreamableHttp传输启动MCP服务器
help [命令] 显示命令帮助
node build/index.js stdio
这是标准的MCP传输方法,适用于与Claude Desktop和cursor等客户端集成。
node build/index.js sse
# 或指定端口
node build/index.js sse --port 3000
启动后,可以访问:
http://localhost:3000/ssehttp://localhost:3000/messagehttp://localhost:3000/healthhttp://localhost:3000/infonode build/index.js http
# 或者使用别名
node build/index.js streamable --port 3000
启动后,可以访问:
http://localhost:3000/mcphttp://localhost:3000/healthhttp://localhost:3000/infocurl 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": "一个MCP服务器演示",
"transport": "sse",
"endpoints": {
"health": "/health",
"info": "/info",
"sse": "/sse"
},
"timestamp": "2024-01-01T00:00:00.000Z"
}
使用JavaScript连接到SSE:
const eventSource = new EventSource('http://localhost:3000/sse');
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('收到:', data);
};
eventSource.onerror = function(error) {
console.error('SSE错误:', error);
};
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: "加法工具",
description: "两个数字相加",
inputSchema: { a: z.number(), b: z.number() }
}, async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
}));
}
src/
├── index.ts # 主服务器文件
└── tools/
└── add.ts # 加法工具实现
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: "乘法工具",
description: "两个数字相乘",
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
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
创建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
添加:
{
"mcpServers": {
"mcp-server-demo": {
"command": "node",
"args": ["/path/to/your/build/index.js", "stdio"]
}
}
}
对于支持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传输的客户端:
{
"mcpServers": {
"mcp-server-demo-http": {
"url": "http://localhost:3000/mcp",
"type": "streamable"
}
}
}
或者通过环境变量启动:
# 先启动StreamableHttp服务器
node build/index.js http --port 3000
# 然后配置客户端连接到 http://localhost:3000/mcp
// SSE连接示例
const eventSource = new EventSource('http://localhost:3000/sse');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('MCP消息:', 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();
};
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连接失败
运行时日志会显示:
主要配置在src/index.ts中间:
const MCP_INFO = {
name: "mcp-server-demo",
version: "0.0.1",
description: "一个MCP服务器演示"
};
const DEFAULT_PORT = 3000;
git checkout -b feature/amazing-feature)git commit -m '添加一些惊人的功能')git push origin feature/amazing-feature)isboyjc