【无标题】
使用DevSpace 让 ChatGPT 能够远程操作本机项目
要解决的问题
购买了codex的plus版本,但额度有限,我希望 ChatGPT 能安全地连接到自己的远程 Linux 电脑,直接读取、修改和运行本机项目中的文件,而不是每次都手动复制代码、日志和命令输出。
最终要实现的效果是:
- ChatGPT 可以通过 DevSpace 访问我明确授权的项目目录。
- VS Code、本机终端和 ChatGPT 操作的是同一份文件。
- 电脑重启后 DevSpace 可以自动恢复,不需要重新创建 ChatGPT 应用。
- 外网访问走 Tailscale Funnel,不需要单独购买域名或配置公网 IP。
整体链路如下:
ChatGPT Web
│ HTTPS + OAuth
▼
https://<设备名>.<tailnet>.ts.net/mcp
│ Tailscale Funnel
▼
http://127.0.0.1:7676/mcp
│ DevSpace
▼
本机已授权项目目录
本文记录的是本次部署中真正必要的步骤。已验证环境:Ubuntu 22.04、Node 22、@waishnav/devspace@1.0.1、Tailscale。
可直接把链接复制给codex,让其复现。
1. 安全边界
DevSpace 连接成功后,ChatGPT 可以在已打开的 workspace 中读写文件并运行命令,权限等同于启动 DevSpace 的 Linux 用户。
因此需要注意:
- 不要用 root 用户启动 DevSpace。
Allowed root只授权项目目录或项目父目录,不要授权整个磁盘。- 不要泄露
~/.devspace/auth.json、~/.local/share/devspace/oauth-state.json和授权页面中的 Owner 密码。 - Tailscale Funnel 是公网入口,日志中看到扫描请求是正常现象;真正的 MCP 调用仍需要 OAuth 授权。
- 涉及写文件、运行命令时,应在 ChatGPT 里明确限定操作范围。
2. 准备变量和基础依赖
在仓库根目录执行。本文假设端口为 7676,授权目录按实际情况修改:
export DEVSPACE_PORT=7676
export DEVSPACE_ALLOWED_ROOT="$HOME/IsaacLab"
mkdir -p "$DEVSPACE_ALLOWED_ROOT"
sudo apt update
sudo apt install -y curl git jq patch ripgrep
如果希望 ChatGPT 同时操作多个项目,建议把 DEVSPACE_ALLOWED_ROOT 设为它们共同的父目录,例如 $HOME 或 $HOME/projects。授权范围越大,风险越高。
3. 安装 Node 22 和 DevSpace
安装 Volta:
curl https://get.volta.sh | bash
source "$HOME/.bashrc"
安装 Node 22:
volta install node@22
node --version
npm --version
安装固定版本 DevSpace:
npm install -g @waishnav/devspace@1.0.1
volta which devspace
本文后面的补丁只针对 @waishnav/devspace@1.0.1,不要直接套到其他版本。
4. 应用 OAuth 持久化补丁
原版 DevSpace 1.0.1 把 OAuth 客户端和令牌保存在进程内存中。DevSpace 一旦重启,ChatGPT 仍持有旧 client_id,服务端却不认识它,会出现:
{"error":"invalid_client","error_description":"Invalid client_id"}
本仓库补丁会把 OAuth 状态持久化到:
~/.local/share/devspace/oauth-state.json
应用补丁:
export DEVSPACE_CLI="$(readlink -f "$(volta which devspace)")"
export DEVSPACE_ROOT="$(dirname "$(dirname "$DEVSPACE_CLI")")"
export DEVSPACE_PATCH="$PWD/scripts/devspace/devspace-1.0.1-persistent-oauth.patch"
jq -r '.name + "@" + .version' "$DEVSPACE_ROOT/package.json"
输出必须是:
@waishnav/devspace@1.0.1
备份并打补丁:
test -e "$DEVSPACE_ROOT/dist/oauth-provider.js.upstream" || \
cp -p "$DEVSPACE_ROOT/dist/oauth-provider.js" \
"$DEVSPACE_ROOT/dist/oauth-provider.js.upstream"
test -e "$DEVSPACE_ROOT/dist/server.js.upstream" || \
cp -p "$DEVSPACE_ROOT/dist/server.js" \
"$DEVSPACE_ROOT/dist/server.js.upstream"
patch --dry-run -d "$DEVSPACE_ROOT" -p1 < "$DEVSPACE_PATCH"
patch -d "$DEVSPACE_ROOT" -p1 < "$DEVSPACE_PATCH"
node --check "$DEVSPACE_ROOT/dist/oauth-provider.js"
node --check "$DEVSPACE_ROOT/dist/server.js"
node scripts/devspace/test_persistent_oauth.mjs "$DEVSPACE_ROOT"
测试通过时应看到:
OAuth persistence test passed
如果提示 Reversed (or previously applied) patch detected,说明可能已经打过补丁。先检查:
rg 'oauth-state.json' "$DEVSPACE_ROOT/dist/server.js"
以后如果重新安装 DevSpace,补丁可能被覆盖,需要重新检查并应用。
5. 安装并配置 Tailscale Funnel
安装并登录 Tailscale:
curl -fsSL https://tailscale.com/install.sh | sh
sudo systemctl enable --now tailscaled
sudo tailscale up
允许当前用户管理 Funnel:
sudo tailscale set --operator="$USER"
生成固定公网地址:
export TAILSCALE_DNS_NAME="$(tailscale status --json | jq -r '.Self.DNSName | rtrimstr(".")')"
export DEVSPACE_PUBLIC_BASE_URL="https://$TAILSCALE_DNS_NAME"
printf 'MCP URL: %s/mcp\n' "$DEVSPACE_PUBLIC_BASE_URL"
开启 Funnel,把公网 HTTPS 转发到本机 DevSpace 端口:
tailscale funnel --bg --yes "http://127.0.0.1:$DEVSPACE_PORT"
tailscale funnel status
预期能看到类似结构:
https://<设备名>.<tailnet>.ts.net (Funnel on)
|-- / proxy http://127.0.0.1:7676
6. 初始化 DevSpace
执行:
devspace init
按提示填写:
Allowed root:$DEVSPACE_ALLOWED_ROOT的实际路径。Port:7676。Public base URL:$DEVSPACE_PUBLIC_BASE_URL的实际值,末尾不要加/mcp。
检查配置:
devspace doctor
devspace config get
stat -c '%a %n' "$HOME/.devspace/config.json" "$HOME/.devspace/auth.json"
config.json 和 auth.json 权限应为 600。
如果公网地址填错,可以改:
devspace config set publicBaseUrl "$DEVSPACE_PUBLIC_BASE_URL"
7. 配置 DevSpace 自动启动
使用仓库脚本生成用户级 systemd 服务:
scripts/devspace/install_user_service.sh --dry-run
scripts/devspace/install_user_service.sh
验证服务:
systemctl --user is-enabled devspace.service
systemctl --user is-active devspace.service
systemctl --user status devspace.service --no-pager -l
curl -fsS "http://127.0.0.1:$DEVSPACE_PORT/healthz"
正常健康检查返回:
{"ok":true,"name":"devspace"}
本配置是“用户登录后自动启动”。如果无人登录也要启动,需要额外配置 systemd linger,但这会让远程入口更早暴露,默认不建议开启。
8. 验证公网链路
curl -fsS --max-time 20 "$DEVSPACE_PUBLIC_BASE_URL/healthz"
curl -fsS --max-time 20 "$DEVSPACE_PUBLIC_BASE_URL/.well-known/oauth-authorization-server"
curl -fsS --max-time 20 "$DEVSPACE_PUBLIC_BASE_URL/.well-known/oauth-protected-resource/mcp"
需要确认:
/healthz返回{"ok":true,"name":"devspace"}。- OAuth 元数据里的 URL 都是当前固定的
*.ts.net域名。 - 不应残留
trycloudflare.com或旧地址。
9. 在 ChatGPT 中创建应用
在 ChatGPT Web 中:
-
打开
Settings → Apps。 -
打开
Advanced settings → Developer mode。 -
点击
Create app。 -
名称填写
DevSpace。 -
MCP URL 填写:
https://<你的设备名>.<tailnet>.ts.net/mcp -
保存并连接。
-
在 DevSpace 授权页输入
~/.devspace/auth.json里的 Owner 密码。 -
新建对话,在加号菜单里选择 Developer mode,并启用 DevSpace 应用。
不要把 Owner 密码发给 ChatGPT,也不要截图分享。
10. 端到端测试
在 ChatGPT 中要求它只做只读操作,例如:
只使用 DevSpace:打开 /home/j/IsaacLab,读取 README.md,执行 git status。不要修改文件。
本机查看日志:
journalctl --user -u devspace.service -n 100 --no-pager
应该能看到 /mcp 请求、mcp_session_created 和 HTTP 200。
再测试重启持久化:
systemctl --user restart devspace.service
systemctl --user is-active devspace.service
stat -c '%a %n' "$HOME/.local/share/devspace/oauth-state.json"
oauth-state.json 权限应为 600。回到同一个 ChatGPT 应用再次执行只读任务,不应出现 invalid_client。
11. 日常检查命令
export TAILSCALE_DNS_NAME="$(tailscale status --json | jq -r '.Self.DNSName | rtrimstr(".")')"
export DEVSPACE_PUBLIC_BASE_URL="https://$TAILSCALE_DNS_NAME"
systemctl is-active tailscaled
systemctl --user is-active devspace.service
tailscale funnel status
curl -fsS "$DEVSPACE_PUBLIC_BASE_URL/healthz"
重启 DevSpace:
systemctl --user restart devspace.service
查看实时日志:
journalctl --user -u devspace.service -f
12. 常见问题
invalid_client
通常是 OAuth 持久化状态失效或补丁被覆盖。
检查:
export DEVSPACE_CLI="$(readlink -f "$(volta which devspace)")"
export DEVSPACE_ROOT="$(dirname "$(dirname "$DEVSPACE_CLI")")"
rg 'oauth-state.json' "$DEVSPACE_ROOT/dist/server.js"
stat "$HOME/.local/share/devspace/oauth-state.json"
devspace config get
如果补丁不存在,确认版本仍是 1.0.1,重新应用第 4 节补丁并重启服务。
公网无法访问
systemctl status tailscaled --no-pager -l
tailscale status
tailscale funnel status
systemctl --user status devspace.service --no-pager -l
重新提交 Funnel:
tailscale funnel --bg --yes "http://127.0.0.1:$DEVSPACE_PORT"
DevSpace 服务启动后立即退出
可能是 Node 或 DevSpace 的真实路径变了,重新生成用户服务:
volta which node
volta which devspace
scripts/devspace/install_user_service.sh
日志中出现 /.env、/.git/config 等扫描
这是公网入口常见扫描。只要 MCP 调用仍需要 OAuth,且 Allowed root 没有授权过大,一般不影响使用。仍建议保持系统和依赖更新。
13. 紧急关闭
关闭公网入口:
tailscale funnel reset
停止 DevSpace:
systemctl --user disable --now devspace.service
恢复使用:
systemctl --user enable --now devspace.service
tailscale funnel --bg --yes "http://127.0.0.1:$DEVSPACE_PORT"
14. 最终验收标准
部署完成后,应同时满足:
- 本地
/healthz返回 HTTP 200。 - 公网
/healthz返回 HTTP 200。 - OAuth 元数据都指向同一个
*.ts.net域名。 - ChatGPT 能读取授权目录内文件并执行只读命令。
- 重启 DevSpace 后,同一个 ChatGPT 应用仍能连接,不出现
invalid_client。 ~/.devspace/auth.json和~/.local/share/devspace/oauth-state.json权限为600。
参考资料
- DevSpace README
- Volta Getting Started
- Tailscale Install on Linux
- Tailscale Funnel
- OpenAI ChatGPT Developer mode
更多推荐

所有评论(0)