dsh-mcp-gateway
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dsh-mcp-gatewayStart a persistent session to debug the API latency issues"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
dsh-mcp-gateway
Give ChatGPT Web a mature DSH Harness.
ChatGPT Web remains the only primary reasoning/model agent. This project connects a normal ChatGPT conversation to DSH through MCP, so DSH-managed tools, skills, jobs, sessions, policies, MCP clients, and compatible community extensions can become ChatGPT capabilities without rebuilding a bespoke wrapper for each extension.
The repository-level architecture contract is AGENTS.md. When older prototype code or documentation conflicts with that contract, the contract wins unless the repository owner explicitly changes the product direction. The ordered personal development roadmap is docs/roadmap.md.
Target architecture
ChatGPT Web Chat
|
OAuth + MCP
|
v
ChatGPT <-> DSH adapter
|
v
DSH Harness
|
+-- DSH tools / skills / extensions
+-- sessions / jobs / policy / MCP clients
`-- optional execution providers
|
+-- local machine
`-- selected local-shell-mcp capabilitiesThe adapter should be as thin and generic as practical. DSH is the harness/runtime authority; local-shell-mcp is primarily a source of proven public-tunnel/OAuth/remote-worker patterns and selected differentiated execution capabilities, not the primary harness.
Related MCP server: dsh-trio
Relationship to local-shell-mcp
local-shell-mcp is not the harness core here. Its useful contributions are the proven ChatGPT Remote MCP/OAuth and public-tunnel patterns plus differentiated execution capabilities such as remote workers and browser control. Those capabilities may be composed behind DSH when useful.
The recent LSM session/continuation work remains useful reference material, but this repository does not copy that runtime into the gateway. DSH owns harness lifecycle and capability composition.
Current status
The first direct DSH Harness seam is implemented. A tiny DSH-resident Cordis plugin uses DSH's own ctx.tools registry:
DSH tool/community plugin
| ctx.tools.register(...)
v
DSH ToolRuntime
| schemas() / execute()
v
loopback ChatGPT bridge
|
v
OAuth MCP gateway
|
v
ChatGPT WebThe primary compatibility surface is deliberately small and stable. ChatGPT can keep the same approved MCP tools while DSH gains reviewed community extensions: dsh_tool_catalog reads the live preset-scoped ToolRuntime catalog after the DSH-side chatgpt-external-v1 capability profile has projected it, and dsh_tool_call executes only tools that are still approved by that profile through ctx.tools.execute(...). DSH policy/guards therefore remain authoritative, and this path does not require ChatGPT to refresh or re-approve its MCP tool snapshot.
Generic Harness operations cover both DSH tools and DSH community skills:
dsh_tool_catalog: reads the current external-ChatGPT projection of DSHToolRuntime.dsh_tool_call: executes a tool only while it remains approved and present in that projection, through DSH's guardedToolRuntimepipeline.dsh_skill_catalog: lists model-invocable entries from DSH's nativeSkillRegistryfor the Harness workspace.dsh_skill_load: loads one compatible community skill's instructions from that registry.
The default chatgpt-external-v1 profile covers deterministic utilities, filesystem operations, shell/jobs, web access, image reading, and DSH plugin discovery. DSH AgentLoop lifecycle/orchestration tools such as goal/todo control, subagents, workflow, ralph, send_message, ask_user_question, and exit_plan_mode are excluded from both discovery and guessed-name execution. The ToolRuntime skill helper is also excluded because skills already have the dedicated dsh_skill_catalog / dsh_skill_load surface. Reviewed community ToolRuntime entries can be added one by one with allowExtraTools in the DSH bridge overlay; reserved AgentLoop and skill names cannot be enabled through that generic opt-in. The OAuth gateway contains no copy of this policy.
The repository's task_state plugin is one explicitly reviewed extra capability. It stores compact engineering-task records through DSH's native storageDomain: title/goal/workspace, current summary and plan, candidate next steps, references, status, revision, and a bounded checkpoint history. Its resume action only changes a paused record back to active; it does not resume a process, invoke a model, choose an action, or continue work. Existing-task mutations require the latest if_revision, so stale conversations fail closed instead of silently overwriting newer checkpoints.
The repository's shell_session plugin is another reviewed extra capability. It exposes open/list/status/send/read/signal/close over an isolated DSH TerminalSessionService plus the native terminal-bash backend. The adapter contains no PTY, process, or sandbox implementation: DSH retains exact-Agent ownership, persistent cwd/environment/process context, bounded scrollback/output, foreground signaling, timeouts, process-tree cleanup, and the shared sandbox policy. The existing one-shot bash tool remains available for simpler commands.
The repository's browser_session plugin is a reviewed runtime extension for persistent Chromium interaction. It exposes open/list/status/snapshot/act/script/close without an internal model loop, scheduler, or autonomous browser task. Browser sessions are exact-Agent scoped; page, cookie, DOM, and in-memory browser state persist across tool calls while the session is alive. Playwright supplies protocol control only. DSH remains the file-effect policy authority: the plugin resolves the current DSH sandboxPolicy and asks the configured DSH sandbox provider to validate it fail-closed. For workspace-write, Chromium then uses the reviewed @deepseek-ai/dsh-sandbox-local 0.1.2-rc.1 bwrap mount profile (/ read-only, private /proc and /tmp, workspace bind-mounted writable) because DSH's Landlock fallback intentionally blocks the /proc/*/uid_map writes Chromium needs for its own user-namespace sandbox. A narrow local dsh-browser-worker launches only that exact bwrap+Chromium argv (or pinned Chromium directly for danger-full-access) under a dedicated AppArmor userns profile and NoNewPrivs=1. The worker accepts spawn requests only from the live dsh-web-host.service MainPID via Unix SO_PEERCRED, contains no shell/model/scheduler, and owns browser process-tree/profile cleanup. The runtime lock pins playwright-core and the small Koffi binding used for peer-credential lookup, while deployment installs the matching Chromium build reproducibly.
The default gateway mode is deliberately meta-only: tools/list exposes only those four stable DSH meta-tools, individual DSH ToolRuntime schemas are not projected into ChatGPT, and the gateway does not advertise the modern tool-list change subscription. This makes the frozen-snapshot property an enforced protocol boundary rather than an assumption about client behavior. Operators may explicitly enable --tool-surface projected as a separate UX mode when they want compatible DSH tools to appear as first-class MCP tools.
The bridge uses DSH's native preset scope directly for discovery. agentPresets.standingKeyFor(presetId) resolves the deployment's current default preset without starting an Agent, Session, or model turn; ToolRuntime.schemas(scope) and SkillRegistry lookups use that standing scope. Tool execution goes through ToolRuntime.execute(...), whose 0.1.2-rc.1 API requires an Agent for agent-scoped policy and modality checks. The bridge therefore creates that metadata-only execution Agent lazily on the first tool call. Its durable helper id is a non-reversible hash of the workspace cwd, preset id, resolved composition path, and the same mtimeMs/size file stamp DSH uses to detect a new standing generation, plus a content digest to avoid aliasing equal-size rewrites. A restart resumes the same helper only while that exact workspace/preset composition generation still applies; a different workspace, changed default preset, or edited composition receives a distinct helper. Setup rechecks the preset path/stamp after agentPresets.mount(...) and fails closed if a hot reload raced helper creation. Catalog/skill reads create no helper session, and ordinary restarts no longer accumulate one new durable helper per boot.
For native DSH tools whose execution is gated by the routed model's declared modalities, the lazy execution Agent points at a local metadata-only ChatGPT Web route. That route declares text + image input so DSH's own read_image gate can validate the external ChatGPT consumer, but its stream() method always fails and the bridge never submits a prompt to the Agent. It therefore performs no inference, requires no model API key, and cannot become a hidden second model. The 0.1.2-rc.1 upgrade smoke verified preset-scoped bash execution and native read_image returning an image block through the bridge with no provider credential configured.
DSH additionalContexts are also preserved across the external-agent boundary. DSH uses these follow-up user contexts for guard reminders and for nested Code Mode results such as an image returned by run_code. The bridge materializes attachment-backed images inside those contexts and the MCP adapter appends their visible text/image blocks to the tool result, so replacing DSH's own model loop with ChatGPT Web does not silently discard policy or nested multimodal context.
This means adding a compatible skill needs no Python wrapper, gateway restart, or ChatGPT app re-publication. A new ToolRuntime capability likewise needs no Python wrapper, but it must be admitted by the DSH-side external capability profile (built-ins by default, reviewed community tools through allowExtraTools). The fixed meta-tools discover the resulting live projection on demand. In the optional projected tool-surface mode only, the DSH-side bridge tracks native tools/change invalidations and the gateway publishes MCP tools/list_changed, allowing clients that support dynamic refresh to gain first-class approved entries.
The DSH-side bridge plugin is in dsh-bridge-plugin/ and the deployment overlay is deploy/dsh/chatgpt-bridge.cordis.yml.
OAuth / MCP
The existing embedded OAuth implementation is retained. It provides persisted dynamic client registration, PKCE/public-client support, owner approval, resource/issuer-bound tokens, refresh rotation, revocation, bounded registration state, and DNS-rebinding protection for the public MCP endpoint.
The primary harness mode requires no model provider API key. Run the DSH Web Host with the bridge overlay, then point the OAuth gateway at its loopback bridge:
python -m pip install --constraint deploy/server-constraints.txt -e '.[server]'
export DSH_MCP_GATEWAY_ADMIN_PIN='choose-a-long-owner-pin'
dsh-mcp-gateway \
--public-base-url https://gateway.example.com \
--dsh-harness-url http://127.0.0.1:3080 \
--state-dir .dsh-mcp-gatewayThe public endpoint is:
https://gateway.example.com/mcpGET /healthz checks the gateway process. In harness mode, GET /readyz checks the loopback DSH capability bridge; it never probes an LLM provider.
Development
python -m pip install -e '.[dev]'
ruff check src tests scripts
python -m unittest discover -s tests -vThe server dependency graph used by CI is pinned in deploy/server-constraints.txt.
Design invariants
ChatGPT is the only primary reasoning Agent.
DSH is the harness/runtime authority.
DSH community capabilities should cross the adapter generically rather than acquire bespoke gateway wrappers.
Stable meta-tools are the correctness path for extension discovery/invocation; dynamic first-class tool projection is optional UX.
Tool execution stays inside DSH's own guarded
ToolRuntimepipeline.The public OAuth/MCP boundary stays outside the loopback DSH Web Host.
local-shell-mcp is an optional execution/access provider and reference, not the primary harness.
Gateway-owned session/continuation experiments are legacy work, not the current architecture.
License
MIT. See LICENSE. Security reporting guidance is in SECURITY.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted MCP memory and agent control plane for durable conversations, jobs, and operations.
Agent-native collaboration network: orchestrate a team of long-running agents from any MCP client.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceMCP bridge enabling ChatGPT to create, view, and control DeepSeek Harness agent sessions, with session management, messaging, and approval tools.160 npm15MIT
- AlicenseNot gradedqualityCmaintenanceTurns DeepSeek Harness into an MCP server with tools for session management, agent execution, resources, and OAuth, plus browser automation and GitHub/GitLab integration.67 npm20MIT
- AlicenseNot gradedqualityAmaintenanceCross-platform control plane for DeepSeek Harness agent fleets with MCP, durable sessions, adaptive routing, policy gates, token budgets, and a phone-friendly LAN dashboard.MIT
- AlicenseNot gradedqualityBmaintenanceMCP server bridging ChatGPT to DeepSeek Harness, exposing 13 tools for task submission, status tracking, result retrieval, project/session management, and human-in-the-loop approvals.1MIT