Documentation Index Fetch the complete documentation index at: https://www.pid0.cn/llms.txt
Use this file to discover all available pages before exploring further.
上一篇 列出了 5 个必须上 VPS 的场景,决定上云了就来这里。把 MCP Server 部署到 VPS 上,结果 Claude Desktop 死活连不上——八成是因为你用的还是 stdio transport。stdio 是进程间通信协议,只能在本机两个进程之间跑,跨网络必须换成 Streamable HTTP。再加上主流客户端强制要求 HTTPS,裸 HTTP 端点直接拒连。这篇把完整链路走一遍:transport 选型 → Node.js 服务部署 → Nginx HTTPS 反代 → Bearer Token 鉴权 → systemd 守护 → 客户端接入验证,每步给可直接粘贴的命令。
前置条件:你需要什么
VPS 基础要求
最低配置:1 核 CPU、512MB 内存、Ubuntu 22.04 LTS。MCP Server 本身不重,但如果你的 Server 会调用 AI API 或做文件处理,建议 1GB 内存起步。
必须满足的三个条件:有独立公网 IP(不是 NAT 后的内网机)、80 和 443 端口未被防火墙屏蔽、有一个指向该 IP 的域名(Let’s Encrypt 签发证书需要)。
# 检查 Node.js 版本,需要 >= 18
node -v
# 确认 443/80 端口监听状态(新机器应为空)
ss -tlnp | grep -E ':(80|443)'
# 查看系统版本
lsb_release -a
本地开发环境确认
本文假设你已经有一个可以在本地跑起来的 MCP Server 项目。如果还没有,用官方 SDK 建一个最小示例:
# 初始化项目
mkdir my-mcp-server && cd my-mcp-server
npm init -y
# 安装 MCP SDK,锁定版本避免 breaking change
npm install @modelcontextprotocol/sdk@1.10.2
transport 选型:为什么 stdio 不能用于远程
transport 通信方式 能否跨网络 主流客户端支持 适用场景 stdio 标准输入输出(进程管道) 仅本机 Claude Desktop 本地模式 本地工具、IDE 插件 SSE HTTP 长连接,服务端推送 是 Claude Desktop、Cursor(部分版本有断连问题) 中等并发,只需服务端推送 Streamable HTTP 标准 HTTP POST + 流式响应 是 Claude Desktop、Cursor、所有支持 HTTP 的客户端 远程部署首选
新项目直接用 Streamable HTTP。MCP 官方文档已将 SSE 标注为 legacy,Streamable HTTP 是 2025 年推荐的远程 transport,兼容性更好,实现也更简单。
部署 MCP Server 并配置 Nginx HTTPS 反代
安装依赖与启动 MCP Server 进程
把项目上传到 VPS,安装依赖:
# 上传项目(本地执行,替换路径和 IP)
scp -r ./my-mcp-server root@your-vps-ip:/opt/mcp-server
# SSH 进入 VPS
ssh root@your-vps-ip
# 进入项目目录,安装生产依赖
cd /opt/mcp-server
npm install --production
# 先手动跑一次确认没报错,监听在 3000 端口
node server.js
# 看到 "MCP Server listening on :3000" 再继续,Ctrl+C 停掉
server.js 中 Streamable HTTP transport 初始化的关键代码:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ;
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js" ;
import express from "express" ;
const app = express ();
app . use ( express . json ());
const server = new McpServer ({ name: "my-server" , version: "1.0.0" });
// 在这里注册你的 tools / resources / prompts
const transport = new StreamableHTTPServerTransport ({
sessionIdGenerator: undefined ,
});
app . all ( "/mcp" , async ( req , res ) => {
await transport . handleRequest ( req , res , req . body );
});
await server . connect ( transport );
// 注意:绑定 127.0.0.1,不直接暴露到公网,由 Nginx 做唯一入口
app . listen ( 3000 , "127.0.0.1" );
Nginx 配置:反代 + 长连接支持
apt update && apt install -y nginx
创建站点配置文件:
cat > /etc/nginx/sites-available/mcp-server << 'EOF'
server {
listen 80;
server_name your-domain.com; # 替换为你的域名
location /mcp {
proxy_pass http://127.0.0.1:3000/mcp;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 流式响应禁止缓冲
proxy_buffering off;
proxy_cache off;
# MCP 工具调用可能耗时较长,超时拉大
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
EOF
# 启用站点
ln -s /etc/nginx/sites-available/mcp-server /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
Let’s Encrypt 证书申请与自动续期
# 安装 Certbot
apt install -y certbot python3-certbot-nginx
# 申请证书,替换邮箱和域名
certbot --nginx -d your-domain.com --email you@example.com --agree-tos --non-interactive
# 验证自动续期定时任务
systemctl status certbot.timer
# 测试续期流程(dry-run,不真正续期)
certbot renew --dry-run
证书申请成功后,Certbot 会自动把 Nginx 配置改为 listen 443 ssl 并填入证书路径。
systemd 守护进程配置
cat > /etc/systemd/system/mcp-server.service << 'EOF'
[Unit]
Description=Remote MCP Server
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/mcp-server
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5s
Environment=NODE_ENV=production
# 在此行追加注入 API Key 等环境变量:Environment=KEY=VALUE
[Install]
WantedBy=multi-user.target
EOF
# 重载配置并启动
systemctl daemon-reload
systemctl enable mcp-server
systemctl start mcp-server
# 确认运行状态
systemctl status mcp-server
鉴权:用 Bearer Token 防止公网裸奔
MCP Server 挂上公网之后,不加鉴权等于把工具调用接口全部公开。有两个方案,按需选。
方案一:Nginx map 层鉴权(轻量,不改应用代码)
# 在 http 块内(server 块外层)添加:
map $ http_authorization $ auth_valid {
default 0 ;
"Bearer your-secret-token-here" 1 ;
}
# 在 location /mcp 块内添加:
if ($ auth_valid = 0) {
return 401 '{"error":"Unauthorized"}' ;
}
生成强度足够的 token:
验证鉴权是否生效:
# 不带 token,应返回 401
curl -s -o /dev/null -w "%{http_code}" https://your-domain.com/mcp
# 带正确 token,应返回 200 或正常 MCP 响应
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer your-secret-token-here" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}' \
https://your-domain.com/mcp
方案二:应用层鉴权(适合多用户场景)
// 加在 app.all("/mcp", ...) 之前
app . use ( "/mcp" , ( req , res , next ) => {
const auth = req . headers [ "authorization" ];
if ( ! auth || auth !== `Bearer ${ process . env . MCP_SECRET_TOKEN } ` ) {
return res . status ( 401 ). json ({ error: "Unauthorized" });
}
next ();
});
在 systemd service 文件的 [Service] 段注入 token:
Environment = MCP_SECRET_TOKEN = your-secret-token-here
客户端接入:Claude Desktop 与 Cursor 配置
服务跑起来之后,在客户端填入远程 MCP Server 的连接信息。
Claude Desktop (macOS 配置文件路径:~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers" : {
"my-remote-server" : {
"url" : "https://your-domain.com/mcp" ,
"headers" : {
"Authorization" : "Bearer your-secret-token-here"
}
}
}
}
Cursor (.cursor/mcp.json,放在项目根目录或用户目录均可):
{
"mcpServers" : {
"my-remote-server" : {
"url" : "https://your-domain.com/mcp" ,
"headers" : {
"Authorization" : "Bearer your-secret-token-here"
}
}
}
}
保存配置后重启客户端。先用 curl 做端到端连通性验证:
curl -s \
-H "Authorization: Bearer your-secret-token-here" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}' \
https://your-domain.com/mcp | python3 -m json.tool
返回以下结构说明整条链路通了:
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"result" : {
"protocolVersion" : "2024-11-05" ,
"serverInfo" : { "name" : "my-server" , "version" : "1.0.0" },
"capabilities" : {}
}
}
常见问题
Remote MCP Server 和本地 stdio MCP Server 有什么区别?
stdio transport 通过标准输入输出在两个本地进程之间传数据,客户端和 Server 必须在同一台机器上。Remote MCP Server 用 HTTP-based transport(SSE 或 Streamable HTTP),Server 运行在任意有公网地址的机器上,客户端通过 URL 远程调用。两者的 MCP 协议层完全一致,只是传输层不同。
MCP Server 需要 HTTPS 才能远程使用吗?
是的。Claude Desktop、Cursor 等主流客户端在连接远程 MCP Server 时强制要求 HTTPS,纯 HTTP 端点直接拒绝。用 Let’s Encrypt 申请免费证书,配合 Certbot 自动续期,操作不超过 5 分钟。
VPS 上运行 MCP Server 需要什么配置要求?
MCP Server 本身极轻,512MB 内存的 VPS 完全够跑。如果 Server 内部有 AI 推理或大文件处理逻辑,建议 1–2GB 内存。CPU 要求不高,1 核足够处理正常并发。
Streamable HTTP 和 SSE 该选哪个?
新项目直接用 Streamable HTTP。MCP 官方文档已将 SSE 标注为 legacy,主流客户端的 SSE 实现在高频调用下有稳定性问题。Streamable HTTP 是当前推荐的远程 transport,兼容性更好,实现也更简单。
本文最后更新于 2026-03,MCP SDK 版本:1.10.2,Nginx 版本:1.24,测试系统:Ubuntu 22.04 LTS。MCP 协议迭代较快,建议每 3 个月检查 SDK 版本和客户端配置格式变更。