frontzhm/simple-mcp-server
If you are the rightful owner of simple-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
This document provides a comprehensive overview of a simple Model Context Protocol (MCP) server implemented using Node.js, supporting WebSocket communication and JSON-RPC 2.0 protocol.
Simple MCP Server
一个用Node.js实现的简单MCP(Model Context Protocol)服务器,支持WebSocket通信和JSON-RPC 2.0协议。
📋 目录
✨ 功能特性
- 🌐 基于WebSocket的MCP协议实现
- 🔧 内置三个示例工具:
get_weather: 获取城市天气信息calculate: 执行数学计算get_time: 获取当前时间
- 📡 完整的JSON-RPC 2.0协议支持
- 🧪 包含完整的客户端示例代码
- 🎨 集成Next.js前端界面
- 🛠️ 支持工具扩展和自定义开发
- 📝 详细的日志记录和错误处理
🏗️ 项目架构
┌─────────────────┐ WebSocket ┌─────────────────┐
│ MCP Client │ ◄──────────────► │ MCP Server │
│ │ │ │
│ - WebSocket连接 │ │ - 工具管理 │
│ - JSON-RPC请求 │ │ - 消息处理 │
│ - 响应处理 │ │ - 错误处理 │
└─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ 工具实现 │
│ │
│ - 天气查询 │
│ - 数学计算 │
│ - 时间获取 │
└─────────────────┘
📁 目录结构
simple-mcp-server/
├── app/ # Next.js前端应用
│ ├── globals.css # 全局样式
│ ├── layout.tsx # 应用布局
│ └── page.tsx # 主页面
├── components/ # React组件
│ ├── theme-provider.tsx # 主题提供者
│ └── ui/ # UI组件库
├── hooks/ # React Hooks
├── lib/ # 工具库
├── public/ # 静态资源
├── styles/ # 样式文件
├── mcp-server.js # MCP服务器核心逻辑
├── server.js # WebSocket服务器启动文件
├── client-example.js # 客户端示例代码
├── package.json # 项目配置
└── README.md # 项目说明
🔧 系统要求
- Node.js: >= 18.12.0 (pnpm需要) 或 >= 16.0.0 (npm)
- pnpm: >= 7.0.0 (推荐) 或 npm: >= 8.0.0
- 操作系统: Windows, macOS, Linux
安装 pnpm
如果还没有安装 pnpm,可以通过以下方式安装:
# 使用 npm 安装
npm install -g pnpm
# 或使用 curl (macOS/Linux)
curl -fsSL https://get.pnpm.io/install.sh | sh -
# 或使用 PowerShell (Windows)
iwr https://get.pnpm.io/install.ps1 -useb | iex
# 验证安装
pnpm --version
Node.js 版本升级
如果当前Node.js版本低于18.12,建议升级:
# 使用 nvm 管理Node.js版本
# 安装 nvm (如果还没有)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 安装并使用Node.js 18
nvm install 18
nvm use 18
# 或安装最新LTS版本
nvm install --lts
nvm use --lts
注意: 如果无法升级Node.js,可以使用npm代替pnpm,所有功能都完全兼容。
🚀 安装和运行
快速开始
- 克隆项目
git clone https://github.com/frontzhm/simple-mcp-server.git
cd simple-mcp-server
- 安装依赖
# 推荐使用 pnpm
pnpm install
# 或使用 npm
npm install
- 启动服务器
# 启动MCP服务器
pnpm run dev:server
# 或直接运行
node server.js
- 启动前端界面 (可选)
# 在另一个终端窗口
pnpm run dev
- 测试客户端
# 在第三个终端窗口
pnpm run test:client
# 或直接运行
node client-example.js
运行模式
开发模式
# 启动Next.js开发服务器 (前端)
pnpm run dev
# 启动MCP服务器 (后端)
pnpm run dev:server
生产模式
# 构建前端
pnpm run build
# 启动生产服务器
pnpm start
端口配置
- MCP服务器:
ws://localhost:8080(默认) - 前端界面:
http://localhost:3000(默认)
可以通过环境变量修改端口:
PORT=9000 pnpm run dev:server # MCP服务器端口
可用的 pnpm 脚本
| 脚本 | 描述 |
|---|---|
pnpm install | 安装项目依赖 |
pnpm run dev | 启动Next.js开发服务器 |
pnpm run dev:server | 启动MCP服务器 |
pnpm run dev:client | 运行客户端测试 |
pnpm run build | 构建生产版本 |
pnpm start | 启动生产服务器 |
pnpm run start:server | 启动MCP服务器 |
pnpm run test:client | 测试客户端连接 |
pnpm run lint | 运行代码检查 |
pnpm run clean | 清理项目文件 |
pnpm run reinstall | 重新安装依赖 |
pnpm run publish:mcp | 发布到MCP注册表 |
pnpm run version:patch | 更新补丁版本号 |
pnpm run version:minor | 更新小版本号 |
pnpm run version:major | 更新大版本号 |
pnpm 优势
- 🚀 更快的安装速度: 比 npm 快 2-3 倍
- 💾 节省磁盘空间: 使用硬链接和符号链接
- 🔒 更严格的依赖管理: 避免幽灵依赖
- 📦 更好的 monorepo 支持: 内置工作空间功能
📖 使用方法
连接到服务器
服务器默认运行在 ws://localhost:8080
基本连接流程
- 建立WebSocket连接
- 发送初始化请求
- 获取可用工具列表
- 调用工具
支持的方法
| 方法 | 描述 | 参数 |
|---|---|---|
initialize | 初始化MCP连接 | protocolVersion, capabilities, clientInfo |
tools/list | 获取可用工具列表 | 无 |
tools/call | 调用指定工具 | name, arguments |
📚 API文档
初始化连接
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "my-client",
"version": "1.0.0"
}
}
}
响应:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"serverInfo": {
"name": "simple-mcp-server",
"version": "1.0.0"
}
}
}
获取工具列表
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
响应:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"inputSchema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
]
}
}
工具调用示例
1. 获取天气信息
请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"city": "北京"
}
}
}
响应:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "北京的天气信息:\n温度: 15°C\n天气: 晴天\n湿度: 45%"
}
]
}
}
2. 数学计算
请求:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "calculate",
"arguments": {
"expression": "2 + 3 * 4"
}
}
}
响应:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "计算结果: 2 + 3 * 4 = 14"
}
]
}
}
3. 获取当前时间
请求:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_time",
"arguments": {
"timezone": "Asia/Shanghai"
}
}
}
响应:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "当前时间 (Asia/Shanghai): 2024/1/15 14:30:25"
}
]
}
}
错误处理
当请求出错时,服务器会返回错误响应:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32601,
"message": "Tool not found: invalid_tool"
}
}
常见错误代码:
-32700: 解析错误-32601: 方法未找到-32602: 无效参数-32603: 内部错误
🛠️ 开发指南
添加新工具
要添加新工具,请在 mcp-server.js 中按以下步骤操作:
1. 在 initializeTools() 方法中定义工具
initializeTools() {
return {
// 现有工具...
// 新工具定义
my_new_tool: {
name: "my_new_tool",
description: "我的新工具描述",
inputSchema: {
type: "object",
properties: {
param1: {
type: "string",
description: "参数1描述"
},
param2: {
type: "number",
description: "参数2描述"
}
},
required: ["param1"]
}
}
}
}
2. 在 handleToolCall() 中添加调用逻辑
async handleToolCall(params) {
const { name, arguments: args } = params
switch (name) {
case "get_weather":
return await this.getWeather(args.city)
case "calculate":
return await this.calculate(args.expression)
case "get_time":
return await this.getTime(args.timezone)
// 添加新工具调用
case "my_new_tool":
return await this.myNewTool(args.param1, args.param2)
default:
throw new Error(`Tool implementation not found: ${name}`)
}
}
3. 实现具体的工具方法
// 工具实现:我的新工具
async myNewTool(param1, param2) {
try {
// 工具逻辑实现
const result = `处理结果: ${param1} - ${param2}`
return {
content: [
{
type: "text",
text: result
}
]
}
} catch (error) {
throw new Error(`工具执行错误: ${error.message}`)
}
}
项目结构说明
mcp-server.js # MCP服务器核心逻辑
├── MCPServer类
│ ├── initializeTools() # 工具定义
│ ├── handleMessage() # 消息处理
│ ├── handleInitialize() # 初始化处理
│ ├── handleToolsList() # 工具列表处理
│ ├── handleToolCall() # 工具调用处理
│ └── 工具实现方法
│ ├── getWeather()
│ ├── calculate()
│ └── getTime()
开发最佳实践
- 错误处理: 始终使用 try-catch 包装工具实现
- 参数验证: 验证输入参数的有效性
- 日志记录: 使用 console.log 记录重要操作
- 响应格式: 确保返回标准的MCP响应格式
- 类型安全: 使用 TypeScript 进行类型检查(可选)
测试新工具
# 启动服务器
pnpm run dev:server
# 在另一个终端测试
pnpm run test:client
自定义客户端
参考 client-example.js 创建自定义客户端:
import WebSocket from "ws"
class MyMCPClient {
constructor(url) {
this.ws = new WebSocket(url)
// 客户端实现...
}
async callTool(name, args) {
return await this.sendRequest("tools/call", {
name,
arguments: args
})
}
}
🔧 故障排除
常见问题
1. 连接失败
Error: connect ECONNREFUSED 127.0.0.1:8080
解决方案:
- 确保MCP服务器正在运行
- 检查端口是否被占用
- 验证防火墙设置
2. 工具调用失败
Error: Tool not found: my_tool
解决方案:
- 检查工具名称拼写
- 确认工具已在
initializeTools()中定义 - 验证
handleToolCall()中的调用逻辑
3. 参数验证错误
Error: Invalid arguments
解决方案:
- 检查参数格式是否符合
inputSchema - 确认必需参数已提供
- 验证参数类型是否正确
调试技巧
- 启用详细日志
// 在 server.js 中添加
console.log("Received message:", JSON.stringify(message, null, 2))
- 使用浏览器开发者工具
- 打开
http://localhost:3000 - 使用浏览器控制台测试WebSocket连接
- 检查网络连接
# 测试端口是否开放
telnet localhost 8080
🤝 贡献指南
如何贡献
- Fork 项目
- 创建功能分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开 Pull Request
代码规范
- 使用 ESLint 进行代码检查
- 遵循现有的代码风格
- 添加适当的注释和文档
- 编写测试用例
报告问题
使用 GitHub Issues 报告问题,请包含:
- 操作系统和Node.js版本
- 错误信息和堆栈跟踪
- 重现步骤
- 预期行为
📄 许可证
本项目基于 MIT 许可证开源 - 查看 文件了解详情。
📦 发布到公共MCP注册表
准备工作
- 安装MCP Publisher CLI
# macOS/Linux (使用Homebrew)
brew install mcp-publisher
# 或下载预构建二进制文件
curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher && sudo mv mcp-publisher /usr/local/bin/
# Windows PowerShell
$arch = if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq "Arm64") { "arm64" } else { "amd64" }
Invoke-WebRequest -Uri "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_windows_$arch.tar.gz" -OutFile "mcp-publisher.tar.gz"
tar xf mcp-publisher.tar.gz mcp-publisher.exe
- 配置server.json
项目根目录已包含
server.json配置文件,请根据实际情况修改:
- 更新作者信息
- 修改仓库URL
- 调整描述和关键词
- 身份验证
mcp-publisher login
- 发布服务器
mcp-publisher publish
发布检查清单
- 更新
server.json中的个人信息 - 确保所有工具功能正常
- 测试客户端连接
- 更新版本号
- 编写清晰的文档
- 添加适当的标签和关键词
版本管理
# 更新版本号
pnpm version patch # 1.0.0 -> 1.0.1
pnpm version minor # 1.0.0 -> 1.1.0
pnpm version major # 1.0.0 -> 2.0.0
# 发布新版本
mcp-publisher publish
📞 支持
- 📧 邮箱: [your-email@example.com]
- 🐛 问题报告: GitHub Issues
- 💬 讨论: GitHub Discussions
- 🌐 MCP注册表: MCP Registry
📋 协议版本
当前实现基于 MCP 协议版本 2024-11-05
协议特性
- ✅ JSON-RPC 2.0 支持
- ✅ WebSocket 通信
- ✅ 工具调用机制
- ✅ 错误处理
- ✅ 初始化握手