Back to home@balaleikaerina

dsh-paper

paper design mcp for deepseek harness (unofficial port)

Stars
0
Language
JavaScript
Created
Aug 20, 2026
Updated
Aug 20, 2026
GitHub repo

Introduction

dsh-paper

⚠️ Not official Paper or DeepSeek stuff. This is my own freestyle build (balaleikaerina) — a small, thin wrapper I wrote for my own DeepSeek Harness setup. Use at your own risk, no warranties, no official support.

An unofficial, thin wrapper that lets DeepSeek Harness talk to Paper (paper.design). It mounts the official @deepseek-ai/dsh-mcp-client bridge against Paper's Streamable-HTTP endpoint and sets Paper's URL as the default. Model-facing tools appear as mcp__paper__*.

It is deliberately a wrapper, not a reimplementation: all of the protocol, reconnect, and tool-registration logic stays in the official mcp-client. Every field is overridable via config.

Files

FilePurpose
dsh-paper.mjsThe wrapper plugin (name + apply). Defaults to Paper's endpoint; every field overridable.
cordis.patch.ymlA ready-to-apply overlay that inserts the wrapper.
fixture-http-server.mjsStandalone Streamable-HTTP MCP server with fake tools (get_basic_info/greet) for offline verification without Paper.
verify.mtsStandalone verification: boots a minimal composition, mounts the wrapper against the fixture, and checks that mcp__paper__* tools appear.

Prerequisites

  • A DeepSeek Harness checkout with pnpm install.
  • For real use: Paper Desktop must be running — Paper owns the /mcp server at http://127.0.0.1:29979/mcp.

Real use (with Paper running)

Pass the overlay to the dsh CLI, e.g. with the web profile:

pnpm --filter @deepseek-ai/dsh dev:web -- --patch cordis.patch.yml

…or merge the rows into your persistent user patch layer ($DSH_HOME/profiles/<name>/cordis.patch.yml):

- insert:
    - id: dsh-paper
      name: ./dsh-paper.mjs
      config:
        serverName: paper
        url: http://127.0.0.1:29979/mcp

The file plugin is only resolved if the relative path is valid from the profile module root; if you run into trouble, point name at an absolute path to dsh-paper.mjs, or paste the wrapper logic inline.

Every config field is optional and overridable:

config:
  serverName: paper            # tool namespace: mcp__paper__*
  url: http://127.0.0.1:29979/mcp
  headers: {}                  # extra HTTP headers
  toolCallTimeoutMs: 60000     # per-call timeout
  failOnStartupError: false    # fail the load when Paper is absent

Offline verification (no Paper needed)

node fixture-http-server.mjs 39281   # terminal 1
pnpm exec tsx verify.mts             # terminal 2

Expected output:

OK: saw mcp__paper__get_basic_info and mcp__paper__greet via wrapper

Gotchas

  • serverName must be unique per composition. The underlying mcp-client rejects a second instance with the same serverName at load time. If you previously added a config-only row with serverName: paper, replace it with the wrapper row instead of keeping both.

  • Config-only alternative. Strictly speaking you don't need the wrapper — the generic bridge works on its own:

    - insert:
        - id: mcp-paper
          name: '@deepseek-ai/dsh-mcp-client'
          config:
            serverName: paper
            transport: streamable-http
            url: http://127.0.0.1:29979/mcp
    

    The wrapper just bundles those defaults together so callers only need to specify the parts they change.