chatgpt-deepseek-bridge
chatgpt-deepseek-bridge
Let ChatGPT (or any MCP client) delegate coding tasks to a local Hermes-backed coding agent, with async job management so slow model runs never block the MCP frontend.
This project is not an official OpenAI product and is not endorsed by
OpenAI. It uses the official Secure MCP Tunnel
and tunnel-client as the transport,
and Hermes Agent as the local agent
runtime. It is tested with DeepSeek models served through OpenCode Go
(opencode-go provider), but the model/provider are Hermes configuration
values — other Hermes-supported providers work without code changes.
What it does
ChatGPT (MCP client)
│ tools: deepseek_investigate / deepseek_execute / deepseek_continue
│ deepseek_job_status / deepseek_job_result / bridge_status
▼
OpenAI Secure MCP Tunnel (tunnel-client daemon)
▼
mcp_bridge_server.py (stdio MCP server)
▼
bridge_core.py (job queue, dedup, single-task lock, git verification)
▼
hermes chat -q -Q (local agent, one-shot invocation)
▼
DeepSeek / any Hermes-supported modelFeatures
Async jobs:
investigate/execute/continuereturn ajob_idin ~1s; Hermes keeps working in the background (5–30 min is normal).Job persistence: job state and results are stored on disk (
state/jobs/<job_id>.json) — surviving MCP reconnects, tunnel restarts, and bridge process restarts.deepseek_job_status/deepseek_job_result: local reads only, never invoke the model again, zero extra token cost.Idempotency: identical requests (tool + normalized task + project root) within a dedup window reuse the existing job — a retried
executenever runs a second writer agent.Single-task lock with TTL + dead-process detection; safe queueing.
Read-only verification:
investigateis checked with git before/after snapshots; any change is reported as aviolation.Safety recovery: on Hermes session-persistence failures the bridge retries automatically — investigate only when verified read-only; execute/continue only when no side effects were detected, otherwise it spawns a fresh session that completes only the remaining work (
partial_execution_possibleflag, original session id preserved).Watchdog: auto-restarts a dead tunnel daemon (~30s).
Windows notifications: tray bubble on job completion/failure (fails silently, never affects job results).
Environment hardening: spawns Hermes with validated TEMP/TMP/TMPDIR and verifies the Hermes home / session DB are writable.
Requirements
Windows (PowerShell 7+; scripts use
pwsh)Python 3.11+
Hermes Agent CLI installed and configured with a model provider (e.g. DeepSeek via
opencode-go)An OpenAI account with Developer Mode and a Secure MCP Tunnel (create at https://platform.openai.com/settings/organization/tunnels)
A git repository you want the bridge to operate on
Installation
pwsh -NoProfile -ExecutionPolicy Bypass -File .\scripts\install-chatgpt-deepseek.ps1This creates .venv, installs the pinned mcp==1.28.1 SDK, locates
hermes.exe (config → -HermesPath → common install locations), and
downloads the official tunnel-client release from GitHub. Add
-SkipTunnelClient to skip the download (bridge-only setups).
Configuration
Copy the templates and fill in your values:
Copy-Item .env.example .env
Copy-Item config.example.json config.json.env→CONTROL_PLANE_API_KEY=...— your tunnel runtime key (create in the OpenAI tunnels page; this is not the tunnel id). Never commit this file.config.json→project_root: absolute path of the git project the bridge may operate onhermes_command: absolute path tohermes.exemodel/provider: any Hermes-supported combination (defaults are DeepSeek viaopencode-go)
Running the tests
Requires Python 3.11+ with only requirements.txt installed (see
Installation) and a local config.json (see Configuration) whose
project_root points at any directory. The stdio compat test
(tests/test_server_discover_compat.py) bootstraps a minimal config on a
clean checkout; the bridge_core tests (test_recovery.py,
test_async_flow.py, tests/test_git_verification.py) import
bridge_core at load time and need config.json to already exist.
test_async_flow.py spawns the configured hermes_command — point it at
a real agent CLI, or a stub that prints an answer and exits 0.
\.venv\Scripts\python.exe tests est_server_discover_compat.py
\.venv\Scripts\python.exe tests est_git_verification.py
\.venv\Scripts\python.exe test_recovery.py
\.venv\Scripts\python.exe test_async_flow.pyGit must be available on PATH for verification; if it is not, jobs fail with
error_type: git_verification_failed instead of silently reporting a
verified run.
Starting the bridge
pwsh -NoProfile -File .\scripts\init-tunnel.ps1 -TunnelId tunnel_xxxxx
pwsh -NoProfile -File .\scripts\start-chatgpt-deepseek.ps1
pwsh -NoProfile -File .\scripts\status-chatgpt-deepseek.ps1
pwsh -NoProfile -File .\scripts\stop-chatgpt-deepseek.ps1start launches tunnel-client (which spawns the bridge server) plus a
watchdog that auto-restarts the daemon if it dies. Then, in
ChatGPT → Developer Mode → Plugins, create a developer app and connect it to
your tunnel id. Use Refresh Tools after any tool description change.
MCP tools
Tool | Purpose |
| Starts a background read-only investigation job; returns |
| Starts a background implementation job (serialized, deduped) |
| New background job continuing a previous Hermes session's context |
| Local status read ( |
| Returns the persisted full result (report, git verification, session id, duration) — never invokes the model |
| Bridge/tunnel health, lock state, recent jobs |
Async job workflow (for MCP clients)
Call
deepseek_investigate/deepseek_execute/deepseek_continue→ you get{status: "accepted", job_id, mode}almost immediately.Do not poll in a tight loop. Jobs commonly take 5–30 minutes. Check
deepseek_job_statusat most once every 5 minutes; if you cannot defer a check that long, return control to the user and tell them the job is running in the background. A Windows notification appears when it finishes.Once status is
completed, calldeepseek_job_resultonce and stop polling. It only reads saved data — no model quota is consumed.deepseek_continueis for new work on an old session, not for fetching a previous job's result.
Security model / limitations
See SECURITY.md — read it before deploying.
This bridge drives a local agent with shell and filesystem access.
investigateread-only is enforced by git before/after verification, not by an OS sandbox.Only point the bridge at projects you trust (agent reads AGENTS.md etc.).
The tunnel credential in
.envis high-value — protect it, rotate it, never commit it.
Troubleshooting
ChatGPT reports "connection timed out" on a tool call: the model run exceeded the MCP frontend's patience; the job keeps running in the background. Wait for the local notification, then call
deepseek_job_resultwith thejob_id. The watchdog restores a dead daemon within ~30s.warning: Failed to set cwd to temp dirin Hermes output: emitted by the uv trampoline when TEMP/TMP is invalid; non-fatal. The bridge now sanitizes these variables before spawning Hermes.hermes_failedwith session persistence errors: the bridge auto-recovers (see Features). If jobs keep failing, runhermes sessions repairwhile no Hermes process is running.tunnel-client exits at startup: make sure
CONTROL_PLANE_API_KEYin.envis the runtime key (starts withsk-proj-), not the tunnel id (starts withtunnel_).MSYS/git hangs: the bridge isolates git through a helper process; if you still see hangs, avoid running the bridge from an MSYS shell.
License
MIT — see LICENSE. The tunnel-client binary is distributed under Apache-2.0 by OpenAI (downloaded at install time, not bundled here).