Skip to main content
Glama
stellarie

dsh-session-bridge-mcp

by stellarie

♡ dsh-session-bridge ♡

Let your MCP client talk to DeepSeek Harness sessions~

English · 简体中文 · 繁體中文

@stellarie/dsh-session-bridge (≧∀≦)

Unofficial. This project has no tie to DeepSeek. It targets DeepSeek Harness 0.2.1-rc.3. It also runs on 0.2.1-rc.2.

What is this?

DeepSeek Harness (DSH) is a desktop agent app. This package lets another agent drive it.

You get two small parts:

  • A host plugin. It runs inside the DSH app. It serves a token-guarded loopback HTTP bridge.

  • A stdio MCP server. Your MCP client (Claude Code, for example) starts it. It talks to the bridge.

Your client opens a normal DSH session, sends it messages, waits for the reply, and reads it. The session shows in the app like any other session. You can watch it, or take it over, any time ♡

Related MCP server: dsh-acp-mcp-bridge

Requirements

  • DeepSeek Harness 0.2.1-rc.3 or 0.2.1-rc.2, with a profile you can edit.

  • Node.js ^22.19.0 or >=24.0.0.

  • An MCP client that speaks stdio.

Install

1. Install the plugin

Use the dsh CLI. Replace default with the name of your profile.

dsh plugin --profile default add @stellarie/dsh-session-bridge

Or install straight from GitHub. The install builds the package on your machine, so the profile must allow build scripts:

dsh plugin --profile default add github:stellarie/dsh-session-bridge

Or edit the profile by hand. Add the package to the profile package.json. Then list it in the bundles, after @deepseek-ai/dsh-web-app.

{
  "dependencies": {
    "@stellarie/dsh-session-bridge": "^0.1.0"
  },
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "@stellarie/dsh-session-bridge"
      ]
    }
  }
}

The package ships a cordis.patch.yml. It inserts the plugin row for you. Restart the app. The log shows session-bridge: serving http://127.0.0.1:…/session-bridge.

2. Register the MCP server

Point your MCP client at the copy inside the profile (<profile-dir> is your DSH profile directory):

claude mcp add dsh-session-bridge -- node <profile-dir>/node_modules/@stellarie/dsh-session-bridge/lib/mcp.js

Or run it from npm, with no profile install:

claude mcp add dsh-session-bridge -- npx -y -p @stellarie/dsh-session-bridge dsh-session-bridge-mcp

Any other MCP client works too. The command is dsh-session-bridge-mcp. The transport is stdio.

The MCP server reads the endpoint file on every call. An app restart needs no MCP restart.

Tools

Tool

What it does

dsh_list_sessions

List sessions: id, title, preset, working directory, running or idle.

dsh_open_session

Open a session in the Workspace of cwd. The app creates the Workspace when none exists. Reuses the newest idle session with the same preset and cwd. Pass reuse: false for a new one. A new session starts at effort (default high).

dsh_send

Send a message. Mode queue runs after the current turn. Mode steer joins the running turn. Returns afterSeq.

dsh_wait

Wait until the session ends a turn after afterSeq. Default 600 s, maximum 600 s.

dsh_read

Read your prompts and the assistant text after afterSeq. Tool calls and thinking are left out.

dsh_cancel

Interrupt the running turn. Queued messages stay queued.

A typical round trip:

dsh_open_session { cwd: "C:/repo", preset: "my-preset" }  → { sessionId, reused, workspaceId, effort }
dsh_send         { sessionId, text: "Fix the failing test" } → { accepted, afterSeq: 41 }
dsh_wait         { sessionId, afterSeq: 41 }               → { ended: true, lastSeq: 58 }
dsh_read         { sessionId, afterSeq: 41 }               → { messages: [ … ] }

dsh_open_session defaults preset to yuu, the author's own preset. Pass your own preset id. See BACKLOG 1.

A new session sets its effort through the app's model selection. The app also saves that effort as its default for every session. See BACKLOG 5.

How the bridge stays safe (`ω´)ゞ

The bridge gives full owner control of your sessions. Read this part, please.

Every request must pass these checks, in this order:

  1. No Origin header. Browser pages always send one, so they are refused.

  2. A loopback Host (127.0.0.1, localhost, or [::1]) with the server port.

  3. A bearer token, compared in constant time.

  4. POST only, with a JSON body of at most 1 MiB.

  5. A method on the allowlist. Session methods: create, prompt, page, projections, list, cancel, selectModel, modelCatalog. Workspace method: create.

The token is 32 random bytes. The plugin mints a new one at each start. It writes endpoint.json (url, token, pid, startedAt) with mode 0600 (POSIX) and deletes it on shutdown.

  • Treat the endpoint file as a secret. Anyone who reads it can prompt your agents.

  • The bridge listens only where the DSH web server listens. It adds no port of its own.

  • The bridge speaks as the app owner. A prompt you send acts like a prompt you type in the app.

  • dsh_open_session creates a Workspace for cwd when none exists, and it saves the new session's effort as the app default.

Configuration

Setting

Where

Default

endpointPath

plugin config in cordis.patch.yml

$DSH_HOME/session-bridge/endpoint.json

DSH_SESSION_BRIDGE_ENDPOINT

environment of the MCP server

unset

DSH_HOME

environment

~/.dsh

Set the same path on both sides when you move the file.

Develop

pnpm install
pnpm run typecheck
pnpm test
pnpm run build

The build writes lib/index.js (the plugin) and lib/mcp.js (the MCP server).

License

MIT © stellarie. Made with ♡ (๑˃ᴗ˂)ﻭ

Available Tools

6 tools
dsh_cancelA

Interrupt the running turn of a Session. Queued messages stay queued.

NameRequiredDescriptionDefault
sessionIdYesSession id from dsh_open_session or dsh_list_sessions.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses a non-obvious side effect — queued messages stay queued rather than being dropped — but says nothing about whether partial output is preserved, error behavior when no turn is running, or permissions required for a state-mutating operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, with the primary action front-loaded before the queue-behavior caveat. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with no output schema or annotations, the description covers the core action and one important behavioral trait. It stops short of covering failure modes (no running turn) or reversibility, which an agent canceling work would benefit from knowing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single sessionId parameter already documents its provenance ('Session id from dsh_open_session or dsh_list_sessions'). The description adds no format or sourcing detail beyond that, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('Interrupt') and a precise scope ('the running turn of a Session'), which is unambiguous about what state is affected. It does not, however, name or contrast itself against any sibling like dsh_wait or dsh_read, so sibling differentiation is left to the agent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Use case is implied by the verb — interrupt the currently running turn — but there is no explicit guidance on when to cancel versus waiting (dsh_wait) or reading (dsh_read), and no stated preconditions such as whether a turn must actually be running.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dsh_list_sessionsA

List Sessions of the running DeepSeek Harness app: id, title, agent preset, working directory, and whether a turn runs.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. 'List' strongly implies a safe read, and it discloses that a 'whether a turn runs' state flag is returned, but it says nothing about ordering, pagination, permissions, or scope of the listing beyond 'the running app'. Adequate but thin for a zero-annotation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence, properly front-loaded with the action and resource, with the returned fields attached as a compact list. There is no filler, hedging, or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must describe returns and it does via the field enumeration. Given zero parameters and low complexity this is close to complete; it only lacks details like result ordering or which sessions are in scope when multiple apps run.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, so the baseline is 4. The description adds value by naming the fields in each returned entry (id, title, agent preset, working directory, turn state) rather than leaving the result shape opaque.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List Sessions of the running DeepSeek Harness app') and enumerates the returned fields, which distinguishes it from siblings like dsh_open_session and dsh_read. It does not explicitly name how it differs from the other read-like siblings, which keeps it below a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: listing sessions is naturally the discovery step before dsh_open_session, dsh_send, or dsh_read, but the description never says when to call this versus those tools. No prerequisites, exclusions, or ordering guidance are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dsh_open_sessionA

Open a Session in the running app. By default it reuses the newest idle Session with the same preset and cwd. Set reuse to false for a new Session.

NameRequiredDescriptionDefault
cwdYesAbsolute working directory for the Session.
reuseNoReuse an idle Session with the same preset and cwd.
presetNoAgent preset id.yuu

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It usefully discloses the reuse-matching semantics and the override, but says nothing about side effects (does it spawn a process?), failure modes when cwd is invalid, permissions/auth, or whether reopening affects existing sessions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero waste, with the primary action and default behavior front-loaded before the override instruction.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description never indicates what opening a Session returns (presumably an identifier an agent needs for dsh_send / dsh_read). For a tool at the entry point of a session workflow, that return-value gap plus missing failure semantics leaves it only partially complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all three parameters are documented. The description adds context only for 'reuse' (matching rule, override), while cwd and preset are essentially restatements of the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Open a Session in the running app'), and the resource is distinct from every sibling (list/send/wait/read/cancel), so an agent can route confidently.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly explains the default behavior (reuse newest idle Session with same preset and cwd) and the condition for opting out ('Set reuse to false for a new Session'). Lacks guidance on when to prefer checking dsh_list_sessions first or what to do when no idle session matches.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dsh_readA

Read caller prompts and assistant text messages of a Session with seq greater than afterSeq. Messages the app injects, tool calls, and thinking are not included.

NameRequiredDescriptionDefault
afterSeqYesReturn messages after this seq. Use -1 for the start.
sessionIdYesSession id from dsh_open_session or dsh_list_sessions.
maxMessagesNoNewest messages to consider.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It does usefully disclose content filtering (injected app messages, tool calls, thinking are excluded), which is real behavior beyond the schema, but omits ordering, truncation direction when maxMessages is hit, and whether reads have side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, with the primary scope stated first and the exclusions immediately after. No filler or restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read tool with no output schema or annotations, the description covers content scope and seq-based paging adequately. It leaves result ordering and the semantics of truncation against maxMessages unstated, which is a modest gap for a paginated read.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the '-1 for the start' convention and the maxMessages default, so the schema does the heavy lifting. The description adds no parameter-level detail beyond what the schema already states, matching the baseline for full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Read) and precisely scoped resource (caller prompts and assistant text messages of a Session), then narrows it further with explicit content exclusions. An agent can distinguish this from dsh_send/dsh_wait purely from the description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The afterSeq-based framing implies a polling/continuation pattern, but the description never says when to prefer this over dsh_wait for new messages, nor does it state prerequisites beyond the schema's sessionId hint. Usage is inferable, not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dsh_sendA

Send a user message to a Session. Returns afterSeq: pass it to dsh_wait and dsh_read to see only the new work.

NameRequiredDescriptionDefault
modeNoqueue runs after the current turn; steer joins the running turn.queue
textYesMessage text.
sessionIdYesSession id from dsh_open_session or dsh_list_sessions.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full disclosure burden. It usefully reveals the return payload (afterSeq) and implies a non-blocking enqueue-then-poll model, but says nothing about permissions, failure modes, what happens if the session is mid-turn, or whether queued messages can be retracted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the action first, then the return value and its downstream use. Every clause carries information an agent needs, with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by naming the key return field and how to consume it, which is exactly the gap that would otherwise exist. Remaining omissions (auth, error behavior, queue-vs-steer selection) are modest for a three-parameter messaging tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so sessionId, text, and the queue/steer mode semantics are already fully documented in the schema. The description adds no parameter-level detail beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource — sending a user message to a Session — which is clearly distinct from the read/wait/cancel siblings. It stops short of explicitly contrasting itself with alternatives (e.g., when to prefer this over dsh_open_session), so it is clear but not fully differentiating.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear forward context: the returned afterSeq should be handed to dsh_wait and dsh_read 'to see only the new work,' which tells the agent how this tool fits into the workflow. It does not state when-not to use it or how dsh_send relates to dsh_cancel, but the sequencing guidance is concrete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dsh_waitB

Wait until the Session ends a turn after afterSeq, or until the timeout.

NameRequiredDescriptionDefault
afterSeqYesThe afterSeq that dsh_send returned.
sessionIdYesSession id from dsh_open_session or dsh_list_sessions.
timeoutSecNoLongest wait in seconds.

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose the essential blocking behavior and that timeouts terminate the wait. However, it omits what happens on timeout (return current state vs error), whether concurrent waits are allowed, and any rate/long-poll constraints, which are important for a blocking call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence that front-loads the blocking condition and back-loads the timeout fallback. It earns its place, though the phrasing 'ends a turn after afterSeq' is slightly awkward and could be tighter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a blocking wait tool with no annotations and no output schema, the description should resolve the biggest ambiguity: what the call returns/does when the timeout fires versus when the turn ends. That distinction, central to correct invocation, is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all three parameters are already documented in the schema, including that afterSeq comes from dsh_send. The description only echoes afterSeq and adds no syntax or edge-case meaning beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (wait) plus the exact terminating condition (session ends a turn after afterSeq, or timeout). It is distinguishable from siblings like dsh_read/dsh_send, though it never names them or clarifies the read-vs-block distinction explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance is given: nothing says to prefer this over polling with dsh_read, nor when a caller should skip waiting. The only implicit cue is the term 'wait' itself, which the agent must interpret unaided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observeddsh_cancel
    • First observeddsh_list_sessions
    • First observeddsh_open_session
    • First observeddsh_read
    • First observeddsh_send
    • First observeddsh_wait

TDQS

A3.8/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing, opening, sending to, waiting on, reading from, and cancelling a session. The send/wait/read trio is a coordinated workflow but each step is unambiguous and descriptions clarify the afterSeq handoff.

Naming Consistency4/5

All tools share a consistent dsh_ prefix and use a verb-first style (list_sessions, open_session, send, wait, read, cancel). The only minor deviation is that send/wait/read/cancel omit the noun, but the pattern is still predictable.

Tool Count5/5

Six tools is well-scoped for a session bridge, covering the full interaction loop without redundancy. Every tool earns its place.

Completeness4/5

The surface covers listing, opening/reusing, messaging, waiting, reading, and interrupting sessions—a complete interaction lifecycle. Minor gaps like explicitly closing/deleting a session exist but agents can work around them via open with reuse=false.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    An experimental MCP gateway for controlling durable DeepSeek Harness agent sessions from MCP clients, enabling session creation, observation, steering, and resumption across chat sessions.
    5
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables any MCP client to operate DeepSeek Harness sessions, execute tasks, and manage workspaces through an MCP server running inside the dsh process.
    482 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables permission-scoped MCP clients to interact with DeepSeek Harness Desktop over a local loopback HTTP bridge, including checking status, listing models/workspaces/sessions, reading bounded session history, and creating, sending, waiting for, or canceling chats. Access is restricted per bearer token and only exposes the tools and sessions granted to that token.
    MIT