Skip to main content
Glama

chat2dsh

AI 助手正在读这个仓库?先看 AGENTS.md。 那里写了哪条路线适合你的用户、哪些事实不能编、以及面对初学者该怎么带。

把 ChatGPT(或任意 MCP 客户端)接到你自己电脑上的 DeepSeek Harness:云端模型负责想和指挥,本机 DSH 负责真正改文件、跑命令。

Operation and execution separated — the chat model plans, the local DSH agent executes.

ChatGPT 网页版 / 任意 MCP 客户端        ← 操作层:派活、定约束、看结果
      │  OpenAI Secure MCP Tunnel / HTTPS / stdio
      ▼
chat2dsh(本仓库的轻量桥)              ← 桥接层:目录白名单、工具暴露、输出回传
      │  本机调用
      ▼
DeepSeek Harness (dsh headless)         ← 执行层:读改文件、跑命令、跑测试

先选路线,别两头做

路线 A:Codex Bridge

路线 B:本仓库 chat2dsh

形态

桌面 App(Swift,含安装包)

一个 Node 脚本,无 GUI

接 ChatGPT 网页版

可以,走 OpenAI Secure MCP Tunnel

不可以(见下方限制)

接 Claude Code / Cursor / Codex CLI

可以

可以

审批 / 任务记录 / 多 Agent

有

无

适合

主要目标是「在 ChatGPT 里遥控本机」

主要目标是「让本机 agent 被任意 MCP 客户端调用」

如果目标就是 ChatGPT 网页版遥控本机,用路线 A,见 docs/chatgpt-setup.md(含 Tunnel、Workspace、DSH 接入的完整步骤和踩坑清单)。本仓库的代码不是那条路的必需品。

不想自己啃文档? 把 docs/agent-prompt.md 里那段提示词整段发给一个 AI(ChatGPT、Claude 都行),它会先问你几个问题,然后一个阶段一个阶段带你配,每步都告诉你验收标准。那是这份 README 的口语版。

路线 B 的限制,先说清楚:ChatGPT 的自定义 MCP 服务器只接受 HTTPS + OAuth 或「无认证」两种方式,没有地方填 Bearer token。所以本仓库这个桥直接挂到 ChatGPT 上,要么走无认证的公网隧道(谁拿到 URL 谁能执行你电脑上的代码),要么你自己在前面补一层 OAuth。两种情况都不该按默认做法用。它真正的用途是给本机或局域网里的 MCP 客户端当 dsh 适配器,以及当你要自己实现一个带 OAuth 的 ChatGPT 网关时,作为被包在里面的那一层。


Related MCP server: hermes-dsh-bridge

路线 B 快速开始

# 1. 装 DeepSeek Harness(需要 Node ^22.19.0 或 >=24)
npm install -g @deepseek-ai/dsh

# 2. 装本仓库
git clone https://github.com/lvoliverrrr/chat2dsh.git
cd chat2dsh
npm install

# 3. 配一个 token 和白名单目录
cp .env.example .env
node -e "console.log(require('crypto').randomBytes(24).toString('hex'))"   # 填进 CHAT2DSH_TOKEN
# 再把 CHAT2DSH_ROOTS 改成你要让 agent 干活的项目目录

# 3.5 填 DSH 的 key
# 打开 .env,把 DEEPSEEK_API_KEY= 那行取消注释填上。不填也能跑,但 dsh_run 会返回
# MISSING_CREDENTIAL —— 桥是好的,只是 dsh 没有模型可用。

# 4. 起服务(HTTP 模式)
npm start
# [chat2dsh] v0.1.0 listening on http://127.0.0.1:7317/mcp
# [chat2dsh] dsh: 0.2.0-rc.2 (.../@deepseek-ai/dsh/lib/bin.js)
# [chat2dsh] roots: C:\Users\me\projects\demo
# [chat2dsh] auth: bearer token required

# 5. 自检
npm run smoke             # 握手 + tools/list + dsh_health + 越界拦截
npm run smoke -- --with-run   # 再加一次真实 dsh 任务(要花一次模型调用)

dsh 执行本身需要 API Key。用官方的:platform.deepseek.com/api_keys 拿 key,填在 DSH Web 的 Models 页(写进 ~/.dsh/.credentials.yaml),或者直接作为环境变量 DEEPSEEK_API_KEY 传给本桥。


工具

桥只暴露两个工具,够用就行。

dsh_health

只读。返回 dsh 是否可达、版本、Node 版本、DSH_HOME、配置的工作区白名单、凭据文件是否存在。先调它,确认桥接层是活的。

dsh_run

把一个自包含任务交给本机 DSH 执行,阻塞到结束,返回 stdout、stderr 尾部、退出码、耗时。

参数

必填

说明

task

是

完整任务描述。必须自包含——headless 是一次性会话,agent 看不到你和它的上一轮对话,也问不了追问。把目标、涉及文件、约束、期望输出都写进去。

cwd

否

绝对路径,必须落在 CHAT2DSH_ROOTS 白名单内。省略则用白名单第一项。

timeout_ms

否

墙钟上限。默认 300000,硬上限 1800000。

任务在 cwd 里执行,DSH 用启动目录作为它的工作区根。


接到 MCP 客户端

Claude Code

claude mcp add-json chat2dsh -s user '{"type":"stdio","command":"node","args":["<abs>/chat2dsh/src/server.mjs","--stdio","--root","<workspace>"]}'

Cursor / 任意 JSON 配置的客户端

{
  "mcpServers": {
    "chat2dsh": {
      "command": "node",
      "args": ["<abs>/chat2dsh/src/server.mjs", "--stdio", "--root", "<workspace>"],
      "env": { "DEEPSEEK_API_KEY": "..." }
    }
  }
}

HTTP 模式(本机或局域网,Bearer 认证)

node src/server.mjs --http --port 7317 --token <secret> --root <workspace>
POST http://127.0.0.1:7317/mcp
Authorization: Bearer <secret>

无状态实现:每个 POST 独立,不维护 session,GET/DELETE 返回 405。GET /healthz 是不带凭据的存活探测,只回版本,不回任何敏感信息。


实测记录

2026-10-16,Windows 11 + Node v22.22.2 + DSH v0.2.0-rc.2,npm run smoke:

PASS  server boots and binds loopback — bridge 0.1.0, dsh 0.2.0-rc.2
PASS  dsh is reachable from the bridge process — resolved
PASS  unauthenticated request is rejected — HTTP 401
PASS  MCP handshake over Streamable HTTP — session 89ed50d7
PASS  tools/list returns the bridge surface — dsh_health, dsh_run
PASS  dsh_health reports a real dsh runtime — dsh 0.2.0-rc.2 @ .../@deepseek-ai/dsh/lib/bin.js
PASS  dsh_run refuses a cwd outside the roots — cwd "..." is outside the allowed roots
SKIP  dsh_run live task — pass --with-run to spend one real LLM call

7/7 checks passed

同一台机器上直接跑 dsh headless "<task>"(未配 key),14 秒返回:

dsh: MISSING_CREDENTIAL: llm-deepseek: no API key for provider route "deepseek-official";
store DEEPSEEK_API_KEY through the credentials service (the web Models page writes it),
or export DEEPSEEK_API_KEY in the launching environment

公网链路(同一台机器,cloudflared tunnel --url http://127.0.0.1:7317,quick tunnel):

$ curl https://<random>.trycloudflare.com/healthz
{"ok":true,"bridge":"0.1.0","dshVersion":"0.2.0-rc.2","authRequired":true}

$ curl -X POST https://<random>.trycloudflare.com/mcp -d '{"method":"tools/list",...}'
{"error":"unauthorized"}                       # HTTP 401,没带 token

$ curl -X POST https://<random>.trycloudflare.com/mcp \
    -H 'authorization: Bearer <token>' -d '{"method":"tools/list",...}'
event: message
data: {"result":{"tools":[{"name":"dsh_health",...},{"name":"dsh_run",...}]}}

也就是说 公网 HTTPS → Cloudflare 边缘 → 隧道 → 本机桥 → dsh 解析 这一段是实测通的。 顺带一个环境发现:本机(校园网)的 DNS 不解析 *.trycloudflare.com,nslookup 报 Non-existent domain, 换阿里 DNS 才拿到 Cloudflare 边缘 IP。你要是在类似网络里用自建隧道,先确认 DNS 这一层, 或者干脆走官方 Secure MCP Tunnel。

三件事说清楚了:桥接层、dsh 进程链路、公网可达性都真跑过; 唯一没跑的是带 API Key 的真实模型调用——那一步需要你自己的 key,npm run smoke -- --with-run 一跑就见分晓。


暴露到公网(可选,先读下面「安全」那节)

# 临时域名,不用注册账号
cloudflared tunnel --url http://127.0.0.1:7317
# 它会打印 https://<random>.trycloudflare.com
# 你的 MCP 端点就是它后面加 /mcp

三件事先知道:

  • 这个域名每次重启都变,而且没有可用性保证。要稳定域名用命名隧道,要接 ChatGPT 就用官方 Secure MCP Tunnel。

  • 本机 DNS 可能根本解析不了 *.trycloudflare.com。 实测某校园网 DNS 直接返回 Non-existent domain,换 223.5.5.5 才解析到 Cloudflare 边缘 IP,再用 curl --resolve host:443:IP 才通。排障时先单独验 DNS 这一层,别把它当成隧道没起来。

  • 公网暴露意味着谁拿到 URL 又拿到 token,谁就能在这台机器上执行代码。只给信任的人,用完就关。

安全

这个桥的存在意义就是让远端在本机执行代码,所以边界要自己划清楚:

  • 默认只绑 127.0.0.1。绑到别的地址会打印警告,别无视它。

  • HTTP 模式没有 token 就不启动。除非你显式 --no-auth,而且要清楚那意味着同网段谁能访问谁就能执行。

  • CHAT2DSH_ROOTS 是白名单,不是建议。越界的 cwd 会被拒绝(自检里有这一条)。别把整个用户目录或盘符根目录写进去。

  • 别把带 token 的隧道 URL 发出去。ChatGPT 那条路请用官方 Secure MCP Tunnel,不要自己拿 trycloudflare 的临时地址裸奔。

  • 输出默认截断在 64 KB(CHAT2DSH_MAX_OUTPUT),超时上限 30 分钟。


目录结构

chat2dsh/
├── README.md        开发者视角:代码怎么跑、实测记录
├── AGENTS.md        给 AI 的入口 —— AI 进仓库先读这个
├── SECURITY.md      威胁模型、部署必做项、不提供的保证
├── llms.txt         给 LLM 的文档索引
├── src/
│   ├── server.mjs   MCP server:stdio + Streamable HTTP,两个工具
│   ├── dsh.mjs      调 dsh:入口解析、spawn、超时、截断
│   └── config.mjs   参数与环境变量、白名单校验
├── scripts/
│   └── smoke.mjs    端到端自检(真起进程、真握手)
├── docs/
│   ├── chatgpt-setup.md  路线 A:ChatGPT 网页版 + Codex Bridge 完整配置
│   └── agent-prompt.md   交给 AI 的部署任务书(让它带你一步步配)
├── .env.example
└── package.json

为什么不用 shell 调 dsh

dsh 在 Windows 上是 .cmd shim,任务文本要经过 cmd.exe 的引号转义规则。所以 src/dsh.mjs 解析出 npm 包的 JS 入口(@deepseek-ai/dsh/lib/bin.js),直接 node <entry> <profile> <task>。任务作为真正的 argv 元素传递,不经过 shell,没有转义地狱,也没有注入面。解析不到入口时才退回 shell 模式。

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Exposes DeepSeek Harness agent capabilities as an MCP server, letting any MCP client drive Harness to execute real coding tasks with structured results, context isolation, and parallel execution.
    83 npm
    13
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables external MCP clients to drive DeepSeek Harness agents for real coding tasks, providing tools for task execution and queueing, session management, sandboxed file access, preset switching, and usage statistics.
    361 npm
    6
    GPL 3.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Exposes DeepSeek Harness tools to any MCP-compatible client over streamable HTTP, allowing allowlisted operations such as file read, glob, grep, and web search while preserving the harness's sandbox and approval pipeline.
    325 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Lets any MCP-capable coding harness (Cursor, Claude Code, Codex, Gemini CLI, VS Code/Copilot, opencode, and others) hand a self-contained task to a real, isolated DeepSeek Harness process that works in a chosen workspace with its own context window, model, and toolchain, then returns the final answer. Exposes task submission with time estimates and acceptance criteria, status polling with live progress and process-tree telemetry, graceful cancel and forced kill of whole process trees, and a health probe reporting concurrency, deadlines, and recent jobs.
    MIT