Skip to main content
Glama

dsh-mcp-expose

Turn your DeepSeek Harness into an MCP server — hand another agent (Codex, WorkBuddy, Claude Code, Cursor, n8n, anything that speaks MCP) either the whole Harness or exactly one conversation you pick in the UI.

A DeepSeek Harness (dsh) plugin. No extra process, no extra port, no bridge: it registers routes on the Harness Web server and speaks MCP Streamable HTTP on the same origin as the GUI.

npm license node

English | 简体中文


Why

DeepSeek Harness already is a full agent runtime: model routing, shell, filesystem, web, skills, subagents, MCP clients, sandbox and approval policy. If you also run Codex or WorkBuddy, you end up with two agents that cannot see each other's work.

This plugin closes that gap in the smallest possible way:

  • Runtime endpoint — /mcp/dsh exposes the whole Harness. The caller passes a session_id to continue an existing conversation or omits it to start a new one.

  • Session endpoints — /mcp/dsh/<sessionId> exposes one session. It is a different MCP server per session, and there is no way to reach any other session through it. Use it when you want to give a client a narrowly scoped capability instead of the keys to the whole machine.

Both surfaces are the same code path an ordinary DSH session uses, so the delegated agent gets your model, tools, workspace, sandbox mode and permission policy.

Related MCP server: dsh-mcp-bridge

Requirements

  • DeepSeek Harness 0.2.x (@deepseek-ai/dsh), desktop app or dsh web.

  • Node.js >= 22.19 (the version the Harness itself runs on).

  • An MCP client that supports Streamable HTTP (sometimes called "HTTP" or "streamable" transport). stdio-only clients can bridge with mcp-remote.

Install

# add it to the profile that should host it (the desktop app's profile is "desktop")
npx @deepseek-ai/dsh plugin --profile desktop add dsh-mcp-expose

Then restart the Harness (close the desktop app and reopen it, or restart dsh web). The plugin registers its routes on startup, so a restart is what makes them live.

Installing by path works without any registry account, and is also how you work on the plugin itself:

git clone https://github.com/wangpeng123-ux/dsh-mcp-expose.git
npx @deepseek-ai/dsh plugin --profile desktop add ./dsh-mcp-expose

dsh resolves plugin specs through npm/pnpm, so a GitHub spec usually works too:

npx @deepseek-ai/dsh plugin --profile desktop add github:wangpeng123-ux/dsh-mcp-expose

Or run it without touching any profile at all:

npx @deepseek-ai/dsh web --patch /path/to/dsh-mcp-expose/cordis.patch.yml

To update a clone-based install later: git pull in the checkout and restart.

Verify

With the Harness running, open the URL it printed and go to Settings → Plugins → 「MCP 服务器」 (the "MCP server" tab). The page lists every visible session, exports the ones you choose, and shows the endpoint each one gets.

Prefer curl? The same data comes from the control API:

curl http://127.0.0.1:57787/mcp/dsh/api

The port is whatever the Harness Web UI uses — take it from the URL the Harness printed, or from the settings page.

Use

1. Pick what to expose

What you want

What to do

Endpoint

The whole Harness

nothing — it is on by default

http://127.0.0.1:57787/mcp/dsh

One specific conversation

Settings page → 「导出」, or the 「导出 MCP」 button in that session's header

http://127.0.0.1:57787/mcp/dsh/<sessionId>

Exporting is instant and reversible: 「取消导出」 makes the URL answer 404 immediately, without deleting the session or its transcript. Exports persist across restarts in ~/.dsh/mcp-expose/exports.json.

2. Connect an MCP client

Codex (~/.codex/config.toml) — whole Harness:

[mcp_servers.dsh]
url = "http://127.0.0.1:57787/mcp/dsh"
startup_timeout_sec = 30
tool_timeout_sec = 900

Codex — just one conversation:

[mcp_servers.dsh_web_project]
url = "http://127.0.0.1:57787/mcp/dsh/session-49def6c7-d76f-429c-8871-dfdea254a481"
tool_timeout_sec = 900

Claude Code / any mcp.json client:

{
  "mcpServers": {
    "dsh": {
      "type": "http",
      "url": "http://127.0.0.1:57787/mcp/dsh"
    }
  }
}

WorkBuddy / stdio-only clients — bridge the same endpoint:

npx -y mcp-remote http://127.0.0.1:57787/mcp/dsh

If you configured a token, add Authorization: Bearer <token> (or ?token=<token>); the Codex equivalent is bearer_token_env_var = "DSH_MCP_TOKEN".

3. Delegate

dsh_run  prompt="in this repo, add a CHANGELOG entry for 1.2.0 and run the tests"
dsh_run  prompt="what did we decide about the retry policy?"  session_id="session-49de…"

dsh_run blocks until the turn ends and returns the assistant's final answer. The repository, shell and tools it uses are all inside your Harness workspace, so the result is real work, not a suggestion.

Tools

The runtime endpoint exposes seven tools:

Tool

Arguments

Purpose

dsh_run

prompt, session_id?, cwd?, timeout_ms?, provider?, model?

Delegate one task; continue a session or start a new one.

dsh_sessions

limit?

List sessions, newest activity first.

dsh_history

session_id, limit?, max_text_chars?

Read a transcript: user prompts, answers, tool calls and results.

dsh_tools

query?

List the tools a delegated agent can call, from its preset scope.

dsh_models

—

Routable providers/models and the deployment default.

dsh_cancel

session_id

Cancel the running turn, keeping the history.

dsh_status

—

Endpoint, process, model, presets, capability and auth summary.

A session endpoint exposes four:

Tool

Arguments

Purpose

dsh_run

prompt, timeout_ms?

Always drives that session — there is no session_id parameter.

dsh_history

limit?, max_text_chars?

That session's transcript only.

dsh_cancel

—

Cancel that session's running turn.

dsh_info

—

Title, workspace, liveness and turn state of that session.

Resources and prompts are advertised as empty; tools are the exposed surface.

The plugin UI

The plugin ships a browser half (no build step, two slots):

  • Settings → Plugins → 「MCP 服务器」 — the full page: runtime endpoint with a copy button, the list of exported sessions with their URLs, and every visible session with a filter box and an 「导出」/「取消导出」 toggle.

  • Session header → 「导出 MCP」 — one-click export/revoke for the conversation you are reading, plus 「复制地址」 once it is exported. A green dot marks exported sessions.

Both talk to the same-origin control API below; the page never constructs MCP traffic itself.

Control API

Not MCP — a small JSON API for the UI (and for scripts). It follows the same auth rule as the MCP routes.

GET /mcp/dsh/api
{
  "ok": true,
  "origin": "http://127.0.0.1:57787",
  "runtimeEndpoint": "http://127.0.0.1:57787/mcp/dsh",
  "auth": "loopback-only",
  "sessions": [
    {
      "session_id": "session-49def6c7-…",
      "title": "MCP plugin",
      "running": true,
      "live": true,
      "blank": false,
      "cwd": "C:\\Users\\me\\Documents\\project",
      "updatedAt": 1792407838229,
      "exported": false,
      "endpoint": "http://127.0.0.1:57787/mcp/dsh/session-49def6c7-…"
    }
  ]
}
POST /mcp/dsh/api
{ "action": "export" | "revoke" | "refresh", "sessionId": "session-49def6c7-…" }

→ { "ok": true, "state": <same shape as GET> }

sessions[].endpoint is always the URL that session would use, so you can write a client config before exporting anything; exported says whether it currently answers.

Configuration

Field

Default

Meaning

path

/mcp/dsh

Base route on the Harness Web server. Session endpoints live under it.

token

''

Bearer token. Empty means loopback callers only.

defaultCwd

''

Working directory for new sessions; empty uses the Harness default directory.

defaultPreset

''

Agent preset for new sessions; empty uses the registry default (see dsh_status).

maxPromptWaitMs

600000

Default dsh_run budget when the caller sends no timeout_ms.

Override them in your profile's cordis.patch.yml (usually ~/.dsh/profiles/<profile>/cordis.patch.yml):

- id: dsh-mcp-expose
  config:
    token: 'your-long-random-token'
    defaultPreset: standard

The plugin ships no settings form, so this file is the configuration surface.

How it works

MCP client (Codex / WorkBuddy / …)
   │  POST /mcp/dsh                      POST /mcp/dsh/<sessionId>
   ▼                                        ▼
dsh-mcp-expose  ── JSON-RPC over Streamable HTTP ──┐
   │  exports registry (~/.dsh/mcp-expose/exports.json)
   │                                               │
   └──────────────► ctx.agents / session log ◄─────┘
                        │
                        ▼
                 DSH agent loop → model, tools, sandbox, approvals
  • One exact route (runtime), one prefix route (session endpoints), one exact route for the control API.

  • The transport is stateless: no Mcp-Session-Id, notification-only POSTs answer 202, GET/DELETE answer 405, batches and request-scoped SSE are supported.

  • dsh_run admits a real user message into the session log, waits for the turn to start, then waits for the agent to go idle (or for timeout_ms).

Security

  • Loopback by default. With no token, every route accepts only 127.0.0.1, ::1 and ::ffff:127.0.0.1, so a hostile page cannot reach it through DNS rebinding. Set token before exposing the Harness on a non-loopback interface.

  • The caller acts as you. dsh_run can read and write files and run commands under your Harness permission policy. Point a client here only if you would give it the same access to a DSH terminal.

  • dsh_run cannot approve itself. An approval prompt still goes to the Harness UI, exactly as for a human turn.

  • A session endpoint is a capability URL. Anyone who can reach the route and knows the session id can continue that conversation. Revoke the export when you are done.

Limitations

  • Stateless transport: a client that insists on a server-initiated SSE session cannot use it (request-scoped SSE is fine).

  • dsh_run waits for idleness, so a long turn can exceed a client-side tool timeout. Raise the client timeout or pass a smaller timeout_ms.

  • No sampling, elicitation, resources or prompts.

  • Session endpoints are single-session by construction. For a second conversation, export that session too — or use the runtime endpoint.

License

MIT

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes any stdio-based MCP server to the internet via HTTP/SSE transport, enabling remote agents to access MCP tools over a network.
    11 npm
    MIT
  • 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.
    607 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables a remote omp client to invoke the host omp's tools over HTTP using the MCP protocol, with no LLM API calls on the host.
    MIT