dsh-echo
Record MCP once. Replay it safely inside DeepSeek Harness.
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 27, 2026
- Updated
- Aug 27, 2026
Introduction
An unofficial DeepSeek Harness plugin for deterministic MCP record/replay.
Capture a real tool session once, replay it without credentials or network, and inspect every match and contract change inside DSH.
简体中文 · Website · Install · Quick start · Architecture · Security
[!NOTE] DSH Echo is not affiliated with or endorsed by DeepSeek. Version 0.1 is installable from source but has not been published to npm.
Why DSH Echo?
MCP tools often sit in front of APIs, databases, and services that make agent tests slow, costly, nondeterministic, or unsafe. DSH Echo puts a cassette between DSH and the real MCP server: record once against reality, then replay the exact conversation offline.
| Record reality | Replay safely |
|---|---|
| stdio and Streamable HTTP/SSE | deterministic request matching |
| append-only, versioned JSONL | fail-closed on an unrecorded call |
| secrets redacted before disk | no real server on a normal replay |
| duration and response captured | structured nearest-call diff |
| See what happened | Guard the contract |
|---|---|
| Session-scoped Web inspector | contract snapshots |
| arguments, results, hit/miss state | classified schema drift |
| compact Trajectory annotations | breaking-change CI gate |
| second redaction pass before UI | scanned fixture export |
Install into DSH
Requirements:
- Node.js 22.19+ on the Node 22 line, or Node.js 24+
- DeepSeek Harness compatibility baseline:
0.1.1-rc.2 - a fresh or explicitly selected DSH profile
Build a local package and install it into an isolated profile:
git clone https://github.com/bleakbelladonnals/dsh-echo.git
cd dsh-echo
npm ci
npm run build
npm pack --ignore-scripts
export DSH_HOME="$(mktemp -d)"
dsh plugin --profile web add ./dsh-echo-0.1.0.tgz
dsh --profile web --no-open
Open a Session and choose the Echo / 录制回放 tab. Installation adds the
plugin with bindings: [], so it does not intercept or change an MCP
server until you explicitly bind one.
To remove it:
dsh plugin --profile web remove dsh-echo
Omit the temporary DSH_HOME only when you intentionally want to
install into your normal DSH profile.
Record and replay
Record a stdio MCP server. Redaction is enabled by default:
dsh-echo record -o .dsh-echo/demo.cassette.jsonl -- \
node examples/fixture/server.mjs
Replay the same interaction offline:
dsh-echo replay .dsh-echo/demo.cassette.jsonl
An unrecorded request returns JSON-RPC error -32601 and exits
non-zero. The real server is not started. Live fallback exists only when you
explicitly pass --on-miss passthrough together with a real server
command.
Streamable HTTP works through a loopback endpoint:
# Record
dsh-echo record -o .dsh-echo/http.cassette.jsonl \
--http http://127.0.0.1:3000/mcp \
--listen 127.0.0.1:6402
# Replay
dsh-echo replay .dsh-echo/http.cassette.jsonl \
--listen 127.0.0.1:6402
Connect one DSH MCP server
DSH currently constructs MCP transports directly, so DSH Echo uses a reversible profile overlay instead of modifying DSH or editing your source profile in place:
dsh-echo profile patch \
--source ./cordis.yml \
--out ./cordis.echo.yml \
--recovery ./cordis.echo.recovery.json \
--root ./.dsh-echo \
--server-row mcp-demo \
--cassette-id demo \
--cassette demo.cassette.jsonl \
--mode replay
The generated replay row does not contain the original server command. Record/passthrough rows use argv arrays, never a shell-concatenated command. The source file is untouched. Restore the saved row into another file with:
dsh-echo profile restore \
--recovery ./cordis.echo.recovery.json \
--out ./cordis.restored.yml
Review generated YAML before applying it. HTTP record/replay is supported; HTTP passthrough is intentionally unavailable in v0.1.
What appears in DSH
For DSH tool names shaped like mcp__<serverName>__<tool>,
the Host plugin adds a compact tool/result.meta.dshCassette
reference. Full tool payloads stay in the cassette rather than being duplicated
into the Session log.
The Echo / 录制回放 tab shows:
- cassette identity, mode, transport, format, and redaction status;
- each interaction's arguments, result, duration, and origin;
- recorded, hit, miss, passthrough, and error state;
- a structured argument diff for the nearest miss;
- contract and schema drift, plus a snapshot action;
- the annotations attached to the current Session/Trajectory.
Host APIs accept configured cassette IDs rather than caller-provided paths. All cassette and snapshot paths must resolve below the configured root, and values are redacted again before reaching the browser.
Contract gate
Capture a baseline:
dsh-echo snapshot --stdio "node examples/fixture/server.mjs" \
-f mcp-contract.snapshot.json
Fail CI when a tool is removed or a breaking schema change appears:
dsh-echo snapshot --check --fail-on breaking \
--stdio "node examples/fixture/server.mjs" \
-f mcp-contract.snapshot.json
The repository's own CI fixture deliberately removes a tool and adds a required property, then asserts that the gate fails.
Export a reviewable fixture
Raw recordings live under the ignored .dsh-echo/ directory.
Export is a separate, explicit step:
dsh-echo export-fixture \
.dsh-echo/demo.cassette.jsonl \
--root ./fixtures \
--out demo.cassette.jsonl
Export refuses paths outside the selected fixture root and blocks detected secrets. A passing scan still requires human review: pattern-based redaction is defense in depth, not proof that a recording is safe to publish.
Architecture
flowchart LR
DSH["DeepSeek Harness"] --> Adapter["DSH Echo profile adapter"]
Adapter --> Core["record / replay core"]
Core --> Live["real MCP server"]
Core --> Tape[("versioned cassette")]
Tape --> Core
Core --> Session["Session annotations"]
Session --> UI["Echo Web inspector"]
The transport engine remains usable as a standalone CLI, while the DSH layer
lives under src/dsh/. See
architecture for lifecycle, trust boundaries, and
integration decisions.
Development
npm ci
npm run lint
npm run typecheck
npm test
npm run test:e2e
npm run audit:pack
npm pack --dry-run --ignore-scripts
The current suite covers 463 tests, including real stdio record/replay, a no-server replay tripwire, profile recovery, path containment, UI redaction, contract drift, lifecycle cleanup, and package inspection. Acceptance runs use temporary homes, loopback listeners, isolated npm caches, and isolated DSH profiles; they do not read or write the user's DSH configuration.
More detail:
Upstream and license
DSH Echo is derived from
ivermin1123/mcp-cassette
at commit 9e48be26cbf1f7fca5edde142673a9b102a25e86 (upstream
version 0.4.0). The retained engine provides stdio and Streamable
HTTP/SSE record/replay, matching, redaction, contract diff, safety lint, and
Vitest integration.
See UPSTREAM.md and NOTICE for the exact import and modification record. Licensed under Apache-2.0.