MCP服务器模板
一个支持HTTP/SSE传输的MCP(模型上下文协议)服务器的最小工作模板。
快速入门
1. 安装
npm install
cp .env.example .env
# Edit .env and set your AUTH_TOKEN2. 跑步
本地工作室 (用于开发):
npm startHTTP服务器 (用于远程访问):
npm run http带有PM2 (用于生产):
pm2 start ecosystem.config.cjs
pm2 save3. 连接Claude CLI
本地工作室:
claude mcp add my-server \
--transport stdio \
node /path/to/src/index.js本地HTTP:
claude mcp add my-server-http \
http://localhost:3020/sse \
--transport sse \
--header "Authorization: Bearer your-token"远程HTTPS (通过 nginx):
claude mcp add my-server-remote \
https://your-domain.com:8443/sse \
--transport sse \
--header "Authorization: Bearer your-token"港口
默认端口是 3020 (可通过配置 PORT 在 .env)。
为什么是3020? 端口3010被主项目占用,因此选择了3020作为模板的端口。
关键陷阱
1. HTTP/2 与 SSE 不兼容
问题HTTP/2 多路复用会中断服务器发送事件(SSE)的长连接。
解决方案使用单独的基于HTTP/1.1的HTTPS终端:
server {
listen 8443 ssl; # WITHOUT http2!
listen [::]:8443 ssl;
location / {
proxy_pass http://localhost:3020/;
proxy_http_version 1.1; # REQUIRED
proxy_set_header Connection ""; # REQUIRED
proxy_buffering off; # REQUIRED
proxy_read_timeout 86400; # 24 hours for long-lived connections
}
}❌ 别这么做:
listen 443 ssl http2; # HTTP/2 will break SSE!2. Nginx 代理设置
为了让SSE通过nginx工作,需要进行特殊设置:
# HTTP/1.1 and remove Connection: close
proxy_http_version 1.1;
proxy_set_header Connection "";
# Disable buffering for streaming
proxy_buffering off;
proxy_cache off;
proxy_request_buffering off;
# Long timeouts for SSE (24 hours)
proxy_connect_timeout 30;
proxy_send_timeout 86400;
proxy_read_timeout 86400;3. Docker 端口映射
在docker-compose中添加新端口时, --force-recreate 要求如下:
# ❌ Insufficient
docker-compose restart nginx
# ✅ Correct
docker-compose up -d --force-recreate nginx4. Claude CLI 健康检查
重要的即使公共端点正常工作,Claude CLI 也可能显示“连接失败”。这是一个外观问题。
功能检查:
curl -N -H "Accept: text/event-stream" \
-H "Authorization: Bearer your-token" \
http://localhost:3020/sse如果你看到 event: endpoint,它起作用了!
5. IPv4 与 IPv6
关键的;严重的Claude Code 需要 IPv6 支持。您必须同时监听 IPv4 和 IPv6!
在你的 Node.js 服务器中:
httpServer.listen(PORT, '0.0.0.0', () => { ... }); // IPv4在nginx中(这两行都是必需的):
listen 8443 ssl; # IPv4
listen [::]:8443 ssl; # IPv6 - REQUIRED for Claude Code!❌(表示错误或否定) 不要这样做:
listen 8443 ssl; # Missing IPv6 - Claude Code won't work!生产环境的Nginx配置
选项1:使用单独的HTTPS端口(推荐)
在8443端口上创建一个新的服务器块:
# /etc/nginx/sites-available/mcp-server
server {
listen 8443 ssl;
listen [::]:8443 ssl;
server_name your-domain.com;
# SSL certificates
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
location / {
proxy_pass http://localhost:3020/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
# CRITICAL for SSE
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 86400;
}
}如果使用 Docker,请在 docker-compose.yml 文件中添加端口
nginx:
ports:
- "443:443"
- "8443:8443" # MCP server选项2:SSH隧道
为了最大程度的安全:
# On the client
ssh -L 3020:localhost:3020 user@your-server.com -N &
# Then connect locally
claude mcp add my-server \
http://localhost:3020/sse \
--transport sse \
--header "Authorization: Bearer your-token"健康检查
健康检查
curl http://localhost:3020/healthSSE连接测试
curl -N -H "Accept: text/event-stream" \
-H "Authorization: Bearer your-token" \
http://localhost:3020/sse预期结果:
event: endpoint
data: /messages?sessionId=template-xxx-xxx-xxxHTTP/1.1 验证(用于 HTTPS)
curl -v https://your-domain.com:8443/health 2>&1 | grep ALPN应显示:
* ALPN, server accepted to use http/1.1应该 否 展示 h2 (HTTP/2)!
安全
令牌生成
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"建议
- 不要在没有SSL的情况下使用HTTP 用于生产
- 轮换令牌 定期地;时常地
- 使用不同的代币 针对不同的客户
- 监控日志 对于可疑活动
- 使用SSH隧道 或使用VPN以确保最高安全性
项目结构
mcp-server-template/
├── src/
│ ├── index.js # Stdio server (local)
│ └── http-server.js # HTTP server (remote)
├── package.json
├── .env.example
├── .gitignore
├── ecosystem.config.cjs # PM2 configuration
└── README.md扩展
在(此处)添加你的工具 tools/list 处理程序:
server.setRequestHandler('tools/list', async () => {
return {
tools: [
{
name: 'your_tool',
description: 'What your tool does',
inputSchema: {
type: 'object',
properties: {
param: { type: 'string', description: 'Parameter description' }
},
required: ['param']
}
}
]
};
});
server.setRequestHandler('tools/call', async (request) => {
if (request.params.name === 'your_tool') {
// Your implementation
return {
content: [{ type: 'text', text: 'Result' }]
};
}
});故障排除
在 Claude CLI 中“连接失败”
- 检查健康状态端点:
curl http://localhost:3020/health- 检查SSE终端点:
curl -N -H "Authorization: Bearer TOKEN" http://localhost:3020/sse- 对于HTTPS,请验证HTTP/1.1:
curl -v https://domain:8443/health 2>&1 | grep ALPNNginx 无法启动
nginx -t # Check configuration
tail -f /var/log/nginx/error.log服务器无响应
pm2 status
pm2 logs mcp-template-http --lines 50
netstat -tlnp | grep 3020有用链接
许可证
麻省理工学院(MIT)
