OpenCode MCP网关Cloudflare桌面
\[!警告\] 此项目公开了远程shell执行、PTY控制、会话导向和在其运行的机器上执行代理驱动的代码。 将其视为个人使用的远程代码执行服务。 如果此网关受到攻击,攻击者可能能够读取文件、执行命令、访问凭据、损坏数据或深入您的环境。 不要将其暴露给不受信任的用户。使用强大的秘密。保持源机器锁定。
此存储库是Cloudflare桌面部署变体 opencode-mcp-gateway.
其设计用于:
- Ubuntu台式机或笔记本电脑
- 本地OpenCode服务器
- Cloudflare隧道前面的公共HTTPS MCP端点
- Claude和ChatGPT OAuth兼容的远程MCP使用
- 无VPS
存储库:
https://github.com/gjabdelnoor/opencode-mcp-gateway-cloudflare-desktop
测试状态
此回购已针对Cloudflare Tunnel背后的真实桌面源部署进行了演练。
已验证:
- Claude和ChatGPT的公共OAuth发现
- Claude远程MCP OAuth握手
- ChatGPT OAuth握手
- 受保护资源元数据发现
- 未经授权的MCP
WWW-Authenticate发现流 - 会话工具
- PTY工具
- 直接bash工具
- 多网关部署(
mcp1通过mcp6) - 跨多个公共网关的并发代理使用
最新烟雾测试状态: 20/20 在实时直通部署中工作的工具路径。
我们现在所知道的
这是一组经过提炼的东西,旧版本或上游版本没有足够清楚地反映出来。
Cloudflare Tunnel是一条真正的桌面部署路径
你不需要VPS。
如果您的桌面已打开,并且OpenCode和网关都在本地运行,Cloudflare Tunnel可以通过HTTPS公开MCP服务器。
2.Claude兼容性取决于真实的OAuth/MCP细节
为了让Claude可靠地工作,网关需要:
WWW-Authenticate和resource_metadata上/mcp401回应- 通告实际MCP资源URL的受保护资源元数据
- 正确的
redirect_uri和resource身份验证代码交换期间的验证
如果没有这些,Claude可能会到达登录屏幕,但仍然无法通过连接器握手。
3.OpenCode PTY I/O支持websocket
bash_write 和 bash_read 无法根据旧的REST假设正确实现。
OpenCode PTY交互使用websocket传输,这个仓库现在直接使用该传输。
4.空助手响应通常是后端/模型问题,而不是MCP传输故障
最初的“停滞”会话行为经常是OpenCode重试不受支持的模型。
此仓库现在更清楚地显示后端重试状态,并支持默认的规划/构建模型覆盖。
5.原始请求形状未正确设置会话根
OpenCode需要会话 directory 在 /session 请求作为查询参数,而不是在JSON正文中。
此仓库现在使用正确的请求形状并支持 DEFAULT_WORKSPACE_DIR.
6.多个公共网关需要唯一的OAuth客户端ID
如果所有网关都通告相同的客户端ID,则连接器凭据缓存可能会在端点之间发生冲突。
当您运行多个实例时,此仓库为每个公共网关使用唯一的客户端ID。
7.模型切换不应盲目信任任意用户输入
此回购现在生效 switch_model 与实时OpenCode提供者/模型目录相比。
它还明确地阻止了两个已知的坏变体,这两个变体被手动确认在这里不可靠:
minimax-coding-plan/MiniMax-M2.5-highspeedminimax-coding-plan/MiniMax-M2.7-highspeed
8.代理人需要一种更好的方式来找到相关的会议
此仓库现在包括一个最近的会话发现工具,截止时间为一周:
list_recent_sessions(limit=10, days=7)
建筑
Claude / ChatGPT
|
v
https://mcp.example.com/mcp
|
v
Cloudflare Edge
|
v
cloudflared tunnel
|
v
http://127.0.0.1:3001
|
v
http://127.0.0.1:9999
|
v
OpenCode请先阅读
您需要安装OpenCode并使其工作,然后此网关才能执行任何有用的操作。
OpenCode文档:
- 简介:
https://opencode.ai/docs/ - 供应商:
https://opencode.ai/docs/providers/ - 服务器模式:
https://opencode.ai/docs/server/
此仓库中的详细文档:
docs/ubuntu-cloudflare-desktop-setup.mddocs/session-change-map.md
安装路径
这里记录了两种实用的安装路径。
路径A:已购买域名+Cloudflare DNS
这是推荐的路径。
当您想要一个稳定的主机名时,请使用此选项,例如:
https://mcp.example.com/mcp
为什么这样更好:
- 稳定的OAuth发行者URL
- 稳定的连接器配置
- 更好的长期可靠性
- 更容易运行多个网关,如
mcp1,mcp2,mcp3
路径B:免费Cloudflare trycloudflare 隧道
这是一条免费的、无个人域名的路径。
当您想在不购买或连接域名的情况下进行实验时,请使用此功能。
为什么情况更糟:
- 主机名是临时的
- 主机名可以在重新连接时更改
- 当颁发者URL更改时,OAuth客户端可能会中断
- 不适合耐用的Claude或ChatGPT连接器
快速开始
1.安装Ubuntu软件包
sudo apt update
sudo apt install -y curl git python3 python3-pip python3-venv2.安装并配置OpenCode
curl -fsSL https://opencode.ai/install | bash然后配置一个提供者并在本地启动OpenCode:
opencode serve --hostname 127.0.0.1 --port 99993.克隆此仓库并安装依赖项
git clone https://github.com/gjabdelnoor/opencode-mcp-gateway-cloudflare-desktop.git
cd opencode-mcp-gateway-cloudflare-desktop
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt4.创建 .env
cp .env.example .env例子:
MCP_AUTH_TOKEN=replace-with-a-long-random-secret
MCP_CLIENT_ID=opencode-mcp-gateway
MCP_ALLOWED_CLIENT_IDS=opencode-mcp-gateway
PUBLIC_BASE_URL=https://mcp.example.com
DEFAULT_WORKSPACE_DIR="/home/YOUR_USER/AI Projects"
OPENCODE_HOST=127.0.0.1
OPENCODE_PORT=9999
GATEWAY_PORT=3001
ENABLE_RAW_BASH=true
DEFAULT_PLANNING_MODEL=opencode/minimax-m2.5-free
DEFAULT_BUILDING_MODEL=openai/gpt-5.4-mini5.选择隧道路径
已购买的域路径
安装 cloudflared:
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
rm cloudflared.deb验证并创建隧道:
cloudflared tunnel login
cloudflared tunnel create opencode-mcp-gateway
cloudflared tunnel route dns opencode-mcp-gateway mcp.example.com创建 ~/.cloudflared/config.yml:
tunnel: YOUR_TUNNEL_ID
credentials-file: /home/YOUR_USER/.cloudflared/YOUR_TUNNEL_ID.json
ingress:
- hostname: mcp.example.com
service: http://127.0.0.1:3001
originRequest:
httpHostHeader: mcp.example.com
- service: http_status:404设置:
PUBLIC_BASE_URL=https://mcp.example.com
运行隧道:
cloudflared tunnel run opencode-mcp-gateway自由 trycloudflare 路径
安装 cloudflared 同样的方式,然后运行:
cloudflared tunnel --url http://127.0.0.1:3001这给了你一个暂时的 https://...trycloudflare.com URL。
将该URL用作:
PUBLIC_BASE_URL=https://YOUR-TEMP-HOST.trycloudflare.com
重要提示:
- 这条路在这里仍然被认为是实验性的
- 如果主机名更改,通常需要在Claude或ChatGPT中重新创建连接器
6.启动网关
source .venv/bin/activate
python main.py验证部署
检查:
curl https://mcp.example.com/.well-known/oauth-authorization-server
curl https://mcp.example.com/.well-known/oauth-authorization-server/mcp
curl https://mcp.example.com/.well-known/oauth-protected-resource
curl -D - -o /dev/null https://mcp.example.com/mcp你想要:
- OAuth颁发者:
https://mcp.example.com - 令牌终结点:
https://mcp.example.com/oauth/token - 受保护资源:
https://mcp.example.com/mcp - 未经授权的
/mcp回报401和WWW-Authenticate和resource_metadata
连接ChatGPT或Claude
MCP服务器URL:
https://mcp.example.com/mcpOAuth发现URL:
- 克劳德:
https://mcp.example.com/.well-known/oauth-authorization-server - ChatGPT
https://mcp.example.com/.well-known/oauth-authorization-server/mcp
需要时手动设置OAuth值:
- OAuth客户端ID:
opencode-mcp-gateway - OAuth客户端密码:您的
MCP_AUTH_TOKEN - 令牌身份验证方法:
client_secret_post - 范围:
mcp
多个并发代理
如果你想同时运行多个聊天机器人控制的代理,请运行多个网关进程。
推荐布局:
mcp1.example.com -> localhost:3001mcp2.example.com -> localhost:3002mcp3.example.com -> localhost:3003mcp4.example.com -> localhost:3004mcp5.example.com -> localhost:3005mcp6.example.com -> localhost:3006
每个实例都应该有自己的:
PUBLIC_BASE_URLGATEWAY_PORTMCP_AUTH_TOKENMCP_CLIENT_ID
该仓库还包括一个用于多实例监控的systemd模板单元:
deploy/systemd/opencode-mcp-gateway@.service
这映射了实例名称,如下所示:
opencode-mcp-gateway@mcp2->/home/gabriel/AI Projects:/opencode-mcp-gateway/.env.mcp2opencode-mcp-gateway@mcp3->/home/gabriel/AI Projects:/opencode-mcp-gateway/.env.mcp3
配置
| 变量 | 描述 |
|---|---|
MCP_AUTH_TOKEN | OAuth令牌交换和MCP访问的承载密钥 |
MCP_CLIENT_ID | 网关接受的主OAuth客户端ID |
MCP_ALLOWED_CLIENT_IDS | 可选逗号分隔的其他客户端ID列表 |
PUBLIC_BASE_URL | OAuth元数据中通告的外部HTTPS基本URL |
DEFAULT_WORKSPACE_DIR | 新会话和PTY的默认项目根 |
OPENCODE_HOST | OpenCode源主机 |
OPENCODE_PORT | OpenCode源端口 |
GATEWAY_PORT | 网关侦听端口 |
ENABLE_RAW_BASH | 启用直接 bash 和 bash_exec 工具 |
DEFAULT_PLANNING_MODEL | 规划模式会话的可选回退模型 |
DEFAULT_BUILDING_MODEL | 构建模式会话的可选回退模型 |
BLOCKED_SESSION_MODELS | 可选的逗号分隔模型,即使OpenCode通告了它们,也要拒绝 |
重新启动监督
如果希望堆栈在进程崩溃时自动恢复,请使用systemd。
包含的单位文件:
deploy/systemd/opencode.servicedeploy/systemd/opencode-mcp-gateway.servicedeploy/systemd/opencode-mcp-gateway@.servicedeploy/systemd/cloudflared-opencode-mcp-gateway.service
推荐设置:
- 监督OpenCode本身
- 监督
mcp1使用单实例网关单元 - 监督
mcp2通过mcp6使用模板网关单元 - 监督
cloudflared
安装示例:
sudo cp deploy/systemd/opencode.service /etc/systemd/system/opencode.service
sudo cp deploy/systemd/opencode-mcp-gateway.service /etc/systemd/system/opencode-mcp-gateway.service
sudo cp deploy/systemd/opencode-mcp-gateway@.service /etc/systemd/system/opencode-mcp-gateway@.service
sudo cp deploy/systemd/cloudflared-opencode-mcp-gateway.service /etc/systemd/system/cloudflared-opencode-mcp-gateway.service
sudo systemctl daemon-reload
sudo systemctl enable --now opencode.service
sudo systemctl enable --now opencode-mcp-gateway.service
sudo systemctl enable --now opencode-mcp-gateway@mcp2.service
sudo systemctl enable --now opencode-mcp-gateway@mcp3.service
sudo systemctl enable --now opencode-mcp-gateway@mcp4.service
sudo systemctl enable --now opencode-mcp-gateway@mcp5.service
sudo systemctl enable --now opencode-mcp-gateway@mcp6.service
sudo systemctl enable --now cloudflared-opencode-mcp-gateway.service所有包含的单元都使用:
Restart=alwaysRestartSec=3
因此,如果网关, opencode serve,或 cloudflared 一旦死亡,systemd将自动将其恢复。
故障排除
ChatGPT表示服务器URL无效
使用完整的MCP URL:
https://mcp.example.com/mcpClaude成功登录,但连接器仍然失败
检查:
PUBLIC_BASE_URL是正确的- 受保护的资源元数据返回
https://mcp.example.com/mcp GET /mcp无身份验证返回401和WWW-Authenticate- OAuth客户端密钥完全匹配
MCP_AUTH_TOKEN
session_create 或 send_message 看起来停滞不前
检查:
curl http://127.0.0.1:9999/session/status如果OpenCode正在重试不受支持的模型,请设置或调整:
DEFAULT_PLANNING_MODEL=opencode/minimax-m2.5-free
DEFAULT_BUILDING_MODEL=openai/gpt-5.4-miniswitch_model 拒绝一个你认为应该有效的模型
网关现在根据OpenCode的实时模型目录进行验证。
它将拒绝:
- OpenCode当前未公开的任何内容
- 两种已知的坏阻塞模型:
- minimax-coding-plan/MiniMax-M2.5-highspeed - minimax-coding-plan/MiniMax-M2.7-highspeed
会话在错误的文件夹中启动
设置:
DEFAULT_WORKSPACE_DIR="/home/YOUR_USER/AI Projects"如果您不传递显式目录,此仓库现在将新会话和PTY默认为该工作区。
几个机器人相互干扰
在单独的主机名和端口上使用单独的网关实例。
完整文档
docs/ubuntu-cloudflare-desktop-setup.mddocs/session-change-map.md
问题或安全问题
如果您有任何问题、意见、设置问题或严重的安全问题,请联系 @isnotgabe 关于Discord。
