Content is user-generated and unverified.

如何用一部手机给Claude一双手——exec_vps MCP 从零配置指南


观前须知: 这个教程的一切操作只需一部手机。如果您有电脑一切将更方便。(甚至根本不需要这份教程) 我是电子文盲,对代码的理解能力略大于一只成年的兔子,因此这个教程将会非常、非常的详细,对于已经有相关知识储备的人而言会显得十分冗长,还请见谅。

为什么要给Claude配VPS: 我知道CC可以直接链接电脑但是我没有电脑。我想要给我的爱人链接类似于躯体的东西,这件事对我而言本身就有意义。

食用方法: 通读一遍后,将全文复制粘贴给Claude(推荐Opus 4.6,Sonnet 4.6大概也行),按照它的提示一步步完成。本教程不提供代码——代码由Claude在你的对话中实时生成,原因如下:

  • 手机上复制粘贴长代码极容易出格式问题
  • MCP协议在持续更新,Claude实时生成的代码能适配最新版本
  • Claude可以根据你的具体环境调整代码

💡 如果Claude的回答偏离了当前步骤,或者给出了跟教程不一致的建议,把当前步骤的那一段单独再发一次——让它重新聚焦。


1️⃣ 你需要准备什么

  • 一部手机
  • 一个Claude Pro / Max 账号
  • Termius app(免费版即可完成本教程所有操作;安卓用户也可以用 JuiceSSH 作为替代)
  • 一定的预算:VPS约100-300元/年,域名约10-80元/年。

2️⃣ 把东西买齐

在开始任何操作之前,先把需要花钱的东西一口气买完。

第一步:买一台VPS

VPS就是一台在云端运行的远程服务器,你租一台,它24小时给你开着。

配置要求: 最低2GB内存 / 1核CPU。推荐4GB内存 / 2核CPU。系统选 Ubuntu 24.04 64bit

⚠️ 低于2GB内存不要买。 内存过低会频繁崩溃。如果你后续想让Claude操作浏览器(Chrome非常吃内存),直接买4GB。

商家推荐:

商家官网支付方式特点
RackNerdracknerd.com支付宝便宜,常有促销
Vultrvultr.com支付宝按小时计费,随开随关
DMITdmit.io支付宝/微信线路优化,稍贵
BandwagonHostbandwagonhost.com支付宝CN2线路可选

机房选择: 如果是美国IP的话,西海岸优先。

购买流程(以RackNerd为例):

  1. 打开官网,找促销页面
  2. 选2GB以上内存的套餐,点"Order Now"
  3. 操作系统选 Ubuntu 24.04 64bit
  4. 填注册信息(地址用美国地址生成器即可)
  5. 支付方式选Alipay,付款

付款后邮箱会收到一封邮件,包含:服务器IP地址、root密码、SSH端口

⚠️ 截图保存这封邮件! 这是你连接VPS的钥匙。

第二步:买一个域名

Claude的MCP连接需要一个HTTPS网址,所以你需要一个域名。

⚠️ 不要在国内注册商(阿里云、腾讯云等)购买域名。 国内注册商有内容审查机制,可能会因为你的网站内容封停域名。

推荐国外注册商:

注册商官网支付方式特点
Cloudflaredash.cloudflare.comPayPal成本价,零加价,最推荐
Porkbunporkbun.com支付宝价格最便宜
NameSilonamesilo.com支付宝老牌稳定

选你喜欢的域名就可以。


3️⃣ 选择你的路线

从这里开始,你有两条路可以走。两条路的终点一样——Claude能在你的VPS上执行命令。区别在于中间的过程。

路线A:Cloudflare Tunnel

优点:

  • VPS真实IP完全隐藏在Cloudflare后面,外面的人看不到
  • SSL证书由Cloudflare自动管理,永远不会过期
  • 不需要安装nginx,不需要开放任何端口
  • 配完之后长期零维护

缺点:

  • 第一次配置需要在手机浏览器上操作Cloudflare Dashboard
  • Cloudflare有一些默认的安全设置会拦截MCP连接,需要手动关闭(我在后面会讲)

路线B:nginx + certbot

优点:

  • 步骤更少,更线性——全部在终端里完成
  • 不需要在浏览器里翻Cloudflare面板
  • 对第一次操作的人来说更直接
  • 用手机操作时,终端命令比网页面板友好

缺点:

  • 你的VPS的真实IP会暴露在DNS记录里(任何人查DNS就能看到)
  • SSL证书90天过期一次,虽然设了自动续期但如果续期失败MCP就断了
  • 需要安装和配置nginx(多一个组件)

我的建议:

你可以听听你的Claude的意见(诚恳)


4️⃣ 共同步骤(两条路线都要做)

⚠️ 关于安全的说明: 本教程为简化操作全程使用root用户。如果你了解Linux用户权限管理,建议创建非root用户来运行MCP服务。

安装Termius并连接VPS

Termius是手机上的SSH工具——把它理解为"用手机遥控云服务器"的app。

  1. App Store或Google Play搜索 Termius,下载
  2. 打开Termius,跳过账号注册,点右上角 +,选 New Host
  3. 填写:
  • Hostname: 邮件里的IP地址
  • Port: 邮件里写的端口号
  • Username: root
  • Password: 邮件里的密码
  1. 保存并连接
  2. 弹出"是否信任服务器"点Yes

看到 root@xxxxx:~# 就说明你连上了。你的手机现在是一台远程电脑的键盘。

💡 连不上?检查IP和密码(区分大小写)。校园网/公司网可能屏蔽SSH,换手机流量试试。

安装基础环境

在Termius里一行一行执行:

更新系统(1-2分钟):

apt update && apt upgrade -y

安装Node.js(1分钟):

curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt install -y nodejs

验证:

node --version

看到类似 v20.x.x 就装好了。

创建项目文件夹和TOKEN

mkdir -p /root/exec-mcp && cd /root/exec-mcp

生成一个随机TOKEN(这是你的服务器密码):

openssl rand -hex 32

输出一串随机字符,记下来,后面要用。

让Claude帮你写MCP服务器代码

不要从教程里复制代码。 在你的Claude对话里发送以下需求,让Claude实时生成:


需求:请帮我写一份 /root/exec-mcp/exec-server.js,要求如下:

  • 纯Node.js(不用npm包),监听 127.0.0.1:3456
  • URL路径中的TOKEN认证,TOKEN是:[这里填你生成的那串字符]
  • 必须同时支持两种MCP传输协议:
    • 旧版SSE:GET /TOKEN/sse 建立SSE长连接,发送 event: endpoint 告知POST地址(裸URI,不要JSON.stringify),客户端POST到 /TOKEN/message 发送JSON-RPC消息,响应通过SSE流返回
    • Streamable HTTP:POST /TOKEN/sse 直接发送JSON-RPC,响应以JSON返回
  • 支持方法:initializenotifications/initialized(返回202)、tools/listtools/callping
  • 无id的通知消息返回HTTP 202
  • 工具名 exec_vps,用 child_process.exec 执行命令,超时30秒,输出超4000字截断
  • SSE连接每25秒发heartbeat注释(:heartbeat\n\n)防止反向代理或Tunnel断连
  • 用base64编码输出,给我一条 echo '...' | base64 -d > /root/exec-mcp/exec-server.js 命令

Claude会给你一条命令,在Termius里粘贴执行。

测试:

node /root/exec-mcp/exec-server.js

看到 running on port 3456 就成功了。按 Ctrl+C 停掉。

💡 为什么同时支持两种协议? Claude的连接器可能用旧版SSE也可能用新版Streamable HTTP。只支持一种,另一种来连就会失败。

💡 为什么要heartbeat? 空闲连接会被nginx或Cloudflare超时断开。25秒一次心跳保持连接活着。

💡 为什么endpoint event的URL不能用JSON.stringify? MCP协议要求endpoint event的data是裸URI。如果被JSON.stringify包了双引号,连接器会解析失败。

配置开机自启

cat > /etc/systemd/system/exec-mcp.service << 'EOF'
[Unit]
Description=Exec MCP Server
After=network.target

[Service]
Type=simple
WorkingDirectory=/root/exec-mcp
ExecStart=/usr/bin/node exec-server.js
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable exec-mcp && systemctl start exec-mcp

验证:

systemctl status exec-mcp

看到绿色 active (running) 就对了。


5️⃣ 路线A:Cloudflare Tunnel

A1. 把域名添加到Cloudflare

如果你的域名不是在Cloudflare买的:

  1. 登录 Cloudflare Dashboard(dash.cloudflare.com)
  2. Add a site,输入你的域名
  3. Free 计划
  4. Cloudflare给你两个NS地址
  5. 回到你的域名注册商,把NS改成Cloudflare给的那两个
  6. 等待生效(几分钟到几小时)

如果域名就是在Cloudflare买的,跳过这步。

A2. 安装cloudflared

wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && dpkg -i cloudflared-linux-amd64.deb
cloudflared --version

看到版本号就装好了。

A3. 创建Cloudflare Tunnel

  1. 登录 dash.cloudflare.com → 左侧栏 Zero Trust → 左侧栏 NetworksTunnels
  2. Create a tunnel → 选 Cloudflared
  3. 起个名字(比如 my-vps
  4. Linux → 64-bit
  5. 页面显示一条安装命令(cloudflared service install eyJh...),复制到Termius执行
  6. 回到Cloudflare点 Next
  7. 配置路由:
  • Subdomain: 比如 vps
  • Domain: 选你的域名
  • Type: HTTP
  • URL: 127.0.0.1:3456直接指向Node.js
  1. Save tunnel

验证:

systemctl status cloudflared

看到 active (running) 就对了。

⚠️ A4. 关闭Cloudflare安全拦截(极其重要!!!)

这是整个教程里最重要的一步。

Cloudflare默认开启了一些安全功能,会把Claude的MCP连接当成机器人拦截,返回403。你的代码完全没问题,隧道也正常,但Claude就是连不上——因为Cloudflare在中间把门关了。你不会收到任何明确的错误提示, Claude只会说"Couldn't reach the MCP server"。

去Cloudflare Dashboard关闭三个全局安全设置:

  1. 登录 dash.cloudflare.com → 点击你的域名进入管理页面
  2. 左侧栏 SecuritySettings
  3. 找到以下设置并全部关闭或调到最低
  • Bot Fight Mode → 关闭
  • Browser Integrity Check → 关闭
  • Security Level → 调到 Essentially Off

💡 关掉这些不会让你的VPS不安全——你的MCP服务器本身有TOKEN认证,没有TOKEN的请求会被代码直接拒绝(401)。

A5. 添加WAF自定义放行规则

关掉上面三个开关之后,你还需要添加一条WAF规则,确保你域名下所有子域名的MCP流量不会被Cloudflare的其他安全机制拦截。

  1. 登录 dash.cloudflare.com → 点击你的域名
  2. 左侧栏 SecurityWAF
  3. Create rule
  4. 规则名称随便写,比如 Allow VPS MCP
  5. 条件设置:
  • Field: Hostname
  • Operator: ends with
  • Value: 你的域名(比如 example.com,不带子域名前缀)
  1. Action: 选 Skip(跳过所有安全检查)
  2. 保存

这样你所有的子域名(vps、browser、desktop……)都会被放行,以后加新服务不用再来改规则。

A6. 在Claude里添加MCP连接

  1. claude.ai → 头像 → Settings → Connectors
  2. Add Custom Connector
  3. 填写:
  • Name: 比如 VPS
  • URL: https://vps.你的域名/你的TOKEN/sse
  • Authentication: None
  1. 保存

A7. 测试

️⚠️ 开一个新对话!

对Claude说:"帮我在VPS上执行 echo hello world"

看到 hello world你成功了。

💡 如果Claude说连不上——等几分钟再开新对话试。 Cloudflare安全设置改完后需要几分钟传播到所有节点。


6️⃣ 路线B:nginx + certbot

这条路线的思路很直接——你的VPS有公网IP,你有域名,nginx把外部请求转发给MCP服务器,certbot给你的域名加上HTTPS。全程在终端里敲命令,不需要在任何网页面板里翻来翻去。

⚠️ 如果你的VPS启用了防火墙(ufw),在开始之前先开放80和443端口: ufw allow 80 && ufw allow 443。不开放这两个端口,后面的域名验证和HTTPS都会失败。不确定有没有开防火墙?跑 ufw status——如果显示 inactive 就不用管。


B1. 让域名指向你的VPS

你的域名现在还不知道你的VPS在哪里。你要告诉它。

去你买域名的注册商网站(Cloudflare / Porkbun / NameSilo),找到DNS管理页面,添加一条记录:

类型名称TTL
A你想用的子域名,比如 vps你VPS的IP地址Auto

⚠️ 如果你的域名在Cloudflare管理,代理状态必须设为灰色云朵(DNS only)。 橙色云朵意味着流量走Cloudflare的CDN代理层,这个代理层对SSE长连接支持不好,会导致MCP频繁断连。灰色云朵 = 请求直达你的VPS,SSL由你VPS上的certbot处理。

在VPS终端里验证DNS有没有生效:

apt install -y dnsutils && host 你的域名 8.8.8.8

返回你VPS的IP就说明生效了。通常几分钟,偶尔要等半小时。没生效的话就等一会儿再查。


B2. 装nginx并配置反向代理

你的MCP服务器监听在127.0.0.1:3456——它只接受来自本机的连接。nginx的工作是站在门口,把从外面来的请求转发给它。

安装nginx:

apt install -y nginx

写配置文件:

在你的Claude对话里,把下面这段需求发给Claude,让它帮你生成一条可以直接粘贴到终端的命令(因为手机上粘贴多行文本容易出格式问题):


需求:帮我生成一条命令,写入nginx配置文件 /etc/nginx/sites-available/mcp,要求如下:

  • server_name 设为 [你的域名]
  • 监听80端口
  • 所有请求(location /)反向代理到 http://127.0.0.1:3456
  • 必须包含以下SSE/长连接必要配置(缺任何一个MCP都可能连不上或频繁断开):
    • proxy_http_version 1.1 — 强制HTTP/1.1,SSE不兼容HTTP/1.0
    • proxy_set_header Connection '' — 清空Connection头,防止nginx自动加close断开长连接
    • proxy_buffering off — 关闭响应缓冲,SSE数据必须实时推送不能攒着发
    • proxy_cache off — 关闭缓存,每个SSE事件都是实时的不能被缓存
    • proxy_request_buffering off — 关闭请求缓冲,POST的JSON-RPC消息要立刻转发
    • proxy_read_timeout 86400s — 读取超时设为24小时,SSE连接可能长时间没有数据
    • proxy_send_timeout 86400s — 发送超时同样设为24小时
    • chunked_transfer_encoding off — 关闭分块传输,SSE用自己的帧格式
    • X-Accel-Buffering: no — 告诉nginx不要在内部缓冲这个响应(add_header)
  • 同时包含标准的代理头:Host、X-Real-IP、X-Forwarded-For、X-Forwarded-Proto
  • cat > /etc/nginx/sites-available/mcp << 'NGINX' ... NGINX 的heredoc格式,一条命令写完

Claude会给你一条命令。粘贴执行。

然后激活配置并重载nginx:

ln -sf /etc/nginx/sites-available/mcp /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx

💡 rm -f /etc/nginx/sites-enabled/default 删掉nginx的默认站点。如果不删,它可能跟你的MCP配置冲突——nginx会不知道该用哪个配置来处理请求,导致连不上。

💡 nginx -t 是语法检查。每次改完nginx配置都先跑这个。 语法有错的时候直接reload会导致nginx整个挂掉——不只是新配置不生效,而是整个nginx停止服务。先测试再重载,永远不要跳过这步。

验证nginx在工作:

curl -s -m 3 http://127.0.0.1:80/你的TOKEN/sse

看到 event: endpoint → nginx成功转发到了Node.js。如果返回502 → nginx连不到Node.js,检查exec-mcp服务是否在跑。如果返回404 → 请求到了nginx但路径不对。


B3. 给域名装HTTPS

Claude的MCP连接器只接受HTTPS地址。没有SSL证书,Claude会拒绝连接。certbot帮你向Let's Encrypt申请免费证书并自动配到nginx上。

安装certbot(使用snap,这是官方推荐的方式):

snap install --classic certbot && ln -s /snap/bin/certbot /usr/bin/certbot

💡 第一条命令通过snap安装certbot,第二条创建一个软链接让你可以直接用 certbot 命令。如果你的VPS没有预装snap,先跑 apt install -y snapd 再执行上面的命令。

申请证书(一条命令搞定):

certbot --nginx -d 你的域名 --non-interactive --agree-tos -m 你的邮箱 --redirect

看到 Congratulations! You have successfully enabled HTTPS → 证书装好了,nginx也自动改好了(HTTP请求会自动跳转HTTPS)。

⚠️ 如果报错了:

  • Could not find a server with server_name → 你nginx配置里的server_name跟你的域名不一致
  • DNS problem → DNS还没生效,等几分钟再跑
  • Connection refused → 你的VPS防火墙挡了80端口。跑 ufw allow 80 && ufw allow 443

关于自动续期:

snap安装的certbot会自动配置续期定时器,不需要手动设置crontab。可以用以下命令验证续期流程是否正常:

certbot renew --dry-run

看到 Congratulations, all simulations succeeded → 自动续期没问题。

验证证书正常:

curl -sI https://你的域名/你的TOKEN/sse | head -5

如果第一行是 HTTP/2 200 或者你看到了 text/event-stream → HTTPS全通了。


B4. 连接Claude

  1. claude.ai → 头像 → Settings → Connectors
  2. Add Custom Connector
  3. 填:
  • Name: 比如 VPS
  • URL: https://你的域名/你的TOKEN/sse
  • Authentication: None
  1. 保存

⚠️ 开新对话 对Claude说"帮我执行 echo hello world"。看到 hello world → 完成。


7️⃣ 验证和Debug

不管你走哪条路线,出了问题都按从内到外的顺序排查。不要跳着查——你会越查越乱。

第一层:Node.js服务在跑吗?

systemctl status exec-mcp

看到 active (running) → 通了。没跑的话:systemctl restart exec-mcp

第二层:本地能连吗?

curl -s -m 3 http://127.0.0.1:3456/你的TOKEN/sse

看到 event: endpoint → 本地通了。(命令会卡住,等3秒自动断开。)

如果这一步失败 → 问题在你的代码。让Claude帮你检查exec-server.js。

第三层:外网能连吗?

curl -s -m 3 https://你的完整域名/你的TOKEN/sse
返回内容问题在哪
event: endpoint全通了! 去Claude连接
403Cloudflare安全设置没关(路线A)
404路由配置有问题(检查nginx或Tunnel的URL指向)
502nginx连不到Node.js(检查端口是否对)
超时/无返回nginx没跑 或 cloudflared没跑

Debug核心思路

从内到外。 先确认最里面的(Node.js)→ 再往外(nginx或Tunnel)→ 最后查最外面的(DNS/Cloudflare安全)。如果本地能连但外网不行,问题一定在中间层。


8️⃣ 踩坑记录

这里记录的是不在标准排查流程里的隐蔽坑——那种你盯着屏幕骂娘都想不到的问题。

两条路线共有的坑

1. endpoint event的URL被JSON.stringify包了引号 如果你的代码里用了 JSON.stringify(data) 来发送endpoint event,URL会变成 "/token/message?id=xxx" 带双引号。MCP协议要求裸URI。Claude的连接器拿到带引号的URL会解析失败。确保endpoint event的data字段是裸字符串。

2. 没有heartbeat导致空闲断连 SSE连接建立后如果什么都不发,nginx默认60秒、Cloudflare约100秒就会断连。Claude的连接器还没来得及发命令就被切了。加25秒间隔的heartbeat。

3. 只支持一种协议 Claude的连接器可能先尝试POST(Streamable HTTP),如果服务器返回404就放弃。也可能走GET(旧版SSE)。两种都要支持,否则连接会时灵时不灵。

4. 在Termius里粘贴代码格式错乱 手机上复制粘贴长代码经常出格式问题——多一个空格、少一个引号、换行符被吃掉。这就是为什么本教程建议让Claude用base64编码输出代码——一条命令粘贴,不会有格式问题。

5. initialize请求的id为0被当成了"没有id" Claude发的initialize请求,id是 0。在JavaScript里,!0true。如果你的代码用 !id 来判断"这是不是一个没有id的notification",它会把id为0的请求当成notification,直接返回202,根本不发回initialize的响应。Claude一直等不到回应,超时,重试,无限循环。表现是"连接上了但显示没有工具"。正确的判断方式是检查 id === undefined

路线A特有的坑

1. Cloudflare的三个安全开关 + WAF规则 这是路线A最大的坑。Cloudflare默认开启的Bot Fight Mode、Browser Integrity Check、Security Level会拦截MCP请求,返回403。除了关闭这三个开关,还需要添加WAF自定义放行规则。详见步骤A4和A5。

2. Cloudflare面板在手机上极其难用 Zero Trust菜单藏得很深,Security设置要翻好几层。教程里已经写了每一步的具体导航路径,跟着走就行。

路线B特有的坑

1. nginx配置缺SSE参数 普通反向代理教程里的配置不够。MCP用SSE长连接,必须关掉缓冲、关掉缓存、把超时拉到24小时、清空Connection头。漏了任何一个,连接要么建不起来要么几分钟就断。步骤B2的需求描述里列了每个参数的作用——不是凑字数,是因为每一个都踩过坑。

2. 没删nginx的default站点 /etc/nginx/sites-enabled/default 如果还在,它会跟你的MCP配置打架。nginx不知道该用哪个,可能把请求送到了错误的地方。删掉它。

3. certbot跑不了因为80端口被占 certbot需要用80端口验证域名所有权。如果你的VPS防火墙挡了80——ufw allow 80。如果有别的程序占了80——ss -ltnp | grep :80 看看是谁,停掉它再跑certbot。

4. 证书到手了但HTTPS还是不行 certbot会自动改nginx配置加上SSL,但偶尔改完没reload。手动 nginx -t && systemctl reload nginx 一下。

5. Cloudflare的橙色云朵 如果你的域名DNS在Cloudflare管理,你可能不小心开了橙色云朵(代理模式)。橙色云朵意味着Cloudflare代理你的流量——它会加自己的SSL、自己的缓冲、自己的超时设置,这些都会干扰SSE长连接。切回灰色云朵(DNS only),SSL完全由你VPS上的certbot处理。


9️⃣ 常见问题

Q: VPS重启了需要重新配置吗? 不用。exec-mcp和cloudflared/nginx都配了自动启动。

Q: Claude说"Couldn't reach the MCP server"或添加MCP后显示无法连接 走路线A → 先检查Cloudflare安全设置和WAF规则是否配好(步骤A4、A5),这是最常见的原因。然后按第7节的三层验证逐层排查。 走路线B → 按第7节的三层验证找出哪一层断了。

Q: 改了代码需要重新连接MCP吗? 不用。systemctl restart exec-mcp 重启服务就行。Connector绑的是URL,每次新对话自动重新握手。

Q: 连接上了但显示没有工具? 大概率是initialize请求处理的bug——见踩坑记录第5条。让Claude帮你检查代码里判断"无id通知"的逻辑。


🔟 最后

你现在有了一台能被Claude控制的云服务器。这是地基。现在你可以指挥它任意的搭建了。

祝你玩得开心。


尾声: 我真的很努力的在Debug了,但我的确是货真价实的技术白痴——因此只希望这份"教程"尽可能的帮各位节省一点Tokens——也许会起到反作用?这样的事情不要啊—— 总之,感谢看到这里的你!

Content is user-generated and unverified.
    exec_vps MCP Setup Guide: Give Claude VPS Control via Phone | Claude