dsh-mcp-lazy
Lazy MCP gateway for DeepSeek Harness: one stable proxy tool instead of N tool schemas, servers connect on first use and idle out, metadata cached to disk.
Install / Use
claude mcp add wings1848 -- npx -y github:wings1848/dsh-mcp-lazyIf the server publishes to npm under a different name, use that package instead β check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
AI & Machine LearningSupported Platforms
Tags
Our assessment of dsh-mcp-lazy
dsh-mcp-lazy scores 83/100 on our quality scale, 649th of 949 AI & Machine Learning skills we index.
Its MCP Server is 11 KB long, well organised into 11 sections with 8 code examples: a thorough specification that gives an agent plenty to work with.
It has 10 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated today, so dsh-mcp-lazy is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 97/100, with no cautions. These come from repository metadata, not a code audit β read the skill file before letting an agent act on it.
dsh-mcp-lazy compared with similar skills
All 4 of these similar skills score higher than dsh-mcp-lazy; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| dsh-mcp-lazy (this skill)by wings1848 | 83 | 10 | today | MCP Server |
| claude-memby thedotmack | 100 | 101.9k | today | CLAUDE.md |
| Agent-Reachby Panniantong | 100 | 100.1k | today | CLAUDE.md |
| Understand-Anythingby Egonex-AI | 100 | 87.2k | 8d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 76.5k | today | CLAUDE.md |
Frequently asked questions
- How do I install dsh-mcp-lazy?
- Run
claude mcp add wings1848 -- npx -y github:wings1848/dsh-mcp-lazy. The install tabs above show the steps for each supported agent. - Which AI agents does dsh-mcp-lazy work with?
- It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
- Is dsh-mcp-lazy safe to use?
- It is MIT-licensed and scores 97/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is dsh-mcp-lazy still maintained?
- The repository was last updated today, so dsh-mcp-lazy is actively maintained.
Skill content
View source on GitHubdsh-mcp-lazy
A lazy MCP gateway for DeepSeek Harness. It puts one
tool in front of the model instead of N MCP tool schemas: servers start on first use, idle
out again, and their tool metadata is cached on disk so search and describe never spawn
anything.
Why
@deepseek-ai/dsh-mcp-client connects every configured server at startup and registers every
one of its tools as a native tool. As its own README puts it, tool descriptions and input
schemas "enter every request while the tools are registered". A handful of servers therefore
costs thousands of tokens on every request and one resident child process each β whether or
not the model ever calls them.
This plugin keeps the model-facing surface at exactly one tool whose schema never changes, discovers tools on demand from a disk cache, and only spawns a server when a call needs it.
The numbers
Measured against chrome-devtools-mcp@1.6.0 (29 tools), both sides rendered the same way β
JSON bytes of the tool definitions, then four bytes per token:
| | per request | | --- | --- | | native registration | 21252 bytes β 5313 tokens | | this gateway | 1525 bytes β 381 tokens | | saved | 92.8% |
The gateway figure is constant: configuring ten more servers does not move it, because their schemas are read on demand rather than sent every request.
The honest counterweight. The gateway costs a fixed 1525 bytes, so it wins only when a server's rendered tool definitions exceed that. The bundled fixture offers 7 small tools and the saving drops to 1.7%. A server with a couple of tiny tools would make the gateway a net loss. Measure your own before assuming:
pnpm run measure:savings # local fixture
node scripts/measure-token-savings.mjs --npx <your-server>
Install
dsh plugin --profile <your-profile> add dsh-mcp-lazy
Works with the DeepSeek Harness 0.1.5-rc and 0.2.0-rc lines (verified against
0.2.0-rc.2); the package's peer ranges declare exactly that.
That installs the package into the profile and registers its bundle patch, which inserts the
mcp-lazy row. Then give it your servers in the profile's cordis.patch.yml:
- id: mcp-lazy
config:
servers:
- serverName: chrome
transport: stdio
command: npx
args: ['-y', 'chrome-devtools-mcp@1.6.0']
lifecycle: lazy
- serverName: docs
transport: streamable-http
url: http://127.0.0.1:3000/mcp
Restart the profile. Every field is documented in docs/configuration.md.
Moving servers off @deepseek-ai/dsh-mcp-client
Every writer of MCP configuration in this ecosystem emits a @deepseek-ai/dsh-mcp-client row:
the config-manager panel hardcodes that package name, @hyzyn/dsh-codegraph writes a managed
row, and a hand-written config follows the same convention. Such a row registers each MCP tool
as a real tool, so its schemas enter every request β and a server listed in both places
cancels the saving this plugin exists for, with no error and nothing to notice. (The mcp({})
status output does warn you β for any server the other plugin serves natively, whether or not
this one has it too β which is how you usually find out.)
adopt does the move for you:
dsh-mcp-lazy-adopt # dry run: prints the plan, writes nothing
dsh-mcp-lazy-adopt --write # applies it, with a timestamped backup of each file
Or, without leaving the session, as a slash command:
/mcp-adopt # dry run
/mcp-adopt apply # writes
The command drives the same CLI, so the plan, the backups and the write are one code path; a
successful apply is followed by a re-plan whose result is shown to you, so the answer to "did
it work?" is evidence rather than an assurance. It still requires the human to type it: nothing
runs at plugin startup.
It reads what is actually mounted (dsh --profile <p> --dump-config, so all four patch layers
are composed), marks each original row disabled: true in place, and appends the server to
this plugin's servers list. Nothing else in the file is touched β comments, blank lines and
!!js expressions are preserved byte for byte β and a row it cannot move safely is reported
with a reason instead of being guessed at. Run it while the host is stopped: the web profile
reloads its patch layer live, and dsh-config-manager rewrites the same file from its own
state.
Check the blast radius before you apply. The native row usually lives in the home patch, which every profile reads, while this plugin's row lives in one profile's patch. Disabling the former therefore takes that server away from every other profile as well β and those profiles have no gateway to receive it, so they simply lose the capability. The plan names them:
β the row being disabled lives in the home layer ~/.dsh/cordis.patch.yml, which every profile reads.
3 other profile(s) do not mount dsh-mcp-lazy, so they would lose codegraph with no replacement:
default, dsh-tui, headless.
Mount dsh-mcp-lazy in those profiles, or move the row into web's own layer, if they need it.
If any of them need the server, mount this plugin there too (or move the row) before applying.
A server that does move arrives with only the fields this plugin implements. Two of the other
plugin's fields are not implemented here β reconnect and failOnStartupError β and
carrying them over is an error rather than a no-op, so a row that sets either one is reported as
unsupported-field and left exactly where it is: no half-move, and no load failure from a
setting that would look configured and do nothing. A misspelled field name is reported the same
way. The per-row id is dropped, because it names the loader row rather than the server.
What the model sees
One tool, always the same 11 parameters:
mcp({ search: "screenshot" }) # find a tool β reads the cache, starts nothing
mcp({ describe: "take_screenshot" }) # full argument schema
mcp({ tool: "take_screenshot" }) # call it β this is what spawns the server
mcp({ tool: "echo", server: "docs" }) # disambiguate a name two servers share
mcp({ connect: "chrome" }) # connect and refresh the cache, without calling
mcp({ instructions: "chrome" }) # the server's own usage notes
mcp({}) # status: tool count, connection state, cache age
Seven of the 11 are the actions above. The other four shape a search and are
never needed for anything else:
| Parameter | Meaning | Default | Limit |
| --- | --- | --- | --- |
| regex | Treat search as a regular expression rather than literal text. | false | β |
| includeSchemas | Include each match's parameter summary in the result. | true | β |
| limit | How many matches to return. | 12 | 40; clamped into 1β40, never an error |
| offset | Skip this many matches, for paging through a long result. | 0 | β |
That one tool is the whole model-facing surface by default. directTools is
the opt-in that promotes chosen server tools into real native tools instead β
see docs/configuration.md
for what it accepts, and why the default is the cheap choice.
Documentation
| | |
| --- | --- |
| docs/configuration.md | every field, the four lifecycle modes, output ceiling |
| docs/troubleshooting.md | failed servers, cold cache, name resolution |
| docs/development.md | build, test, why link-dsh is mandatory |
| docs/design.md | why the plugin is shaped this way: the constant tool surface, the cache, the lifecycle, envFrom, and the adopt command |
| docs/parity-pi-mcp-adapter.md | module-by-module comparison against pi-mcp-adapter v2.33.0, and the defects it turned up |
Known limitations
The v1 boundary, stated plainly:
- Tools only. No MCP resources, prompts, sampling, or elicitation. Only
tools/list_changedis subscribed. - No OAuth. Authentication is a plaintext
headersentry or an environment variable. - Image and audio results are not forwarded. They are projected to a one-line metadata entry (type and byte count). Forwarding pixels needs attachment storage this plugin does not implement.
- No approval gate. MCP calls follow your DSH permission preset.
- No config interop. It reads DSH-native config only; it will not import
.mcp.json, Cursor, Claude Code, Codex, or VS Code server lists. - The regex guard is deliberately narrow. A 256-character cap plus a nested-quantifier
check, which does not catch overlapping alternation like
(a|aa)+or polynomial backtracking likea*a*a*b. A full analyser would mean a second runtime dependency. - No SSE or unix-socket transports.
stdioandstreamable-httponly. npxis not resolved to the underlying binary, so annpx-launched server costs one extra Node parent process.- A secret passed through
argslands in the child'sargv, wherepsand/proc/<pid>/cmdlinecan read it. That path exists only because some servers accept a token no other way;envFromalone keeps the value out ofargv.
Development
pnpm install
pnpm test # builds, relinks the peer packages, runs 390 tests
pnpm run check # typecheck, lint, build, then type-check the test sources
See CONTRIBUTING.md.
Star history
<picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/wings1848/dsh-mcp-lazy/output/star-history-dark.svg"> <img alt="Star history chart" src="https://raw.githubusercontent.com/wings1848/dsh-mcp-lazy/output/star-history-light.svg"> </picture>License
MIT β see LICENSE. The connection supervisor, transport factory, and
environment-scrubbing rules derive from @deepseek-ai/dsh-mcp-client; the single-proxy-tool
gateway, metadata cache, and weighted search ranking derive from pi-mcp-adapter. Both are
MIT; their notices are reproduced in THIRD_PARTY_NOTICES.md.
Related Skills
claude-mem
101.9kPersistent Context Across Sessions for Every Agent β Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More
Agent-Reach
100.1kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu β one CLI, zero API fees.
Understand-Anything
87.2kGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.
headroom
76.5kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit β see the Safety scan above for what the skill file itself contains.
