DeepSeek Harness takes “everything is a plugin” unusually far. Models, tools, sessions, the agent loop, and UI surfaces all live in a Cordis composition.
That freedom creates an interoperability problem: what if your primary agent is not DSH?
An MCP-capable desktop agent should not need to replace its runtime just to inspect or use a useful DSH plugin. It should be able to discover the plugin, review what it is, explicitly choose whether to install it, and—only when allowed—call its live tools.
I contribute to BitFun. We built an early bridge to test that idea: deepseek-harness-plugin-mcp.
This is not an official DeepSeek component. It is source preview. The npm package is not published yet, so do not copy the npx example from the current README and expect it to work.
One bridge, three trust boundaries
The first design mistake would be exposing one magical “install and run this plugin” tool. Discovery, local mutation, and execution do not deserve the same authority.
The server therefore has three planes.
Catalog: useful while read-only
The catalog plane searches repositories carrying the dsh-plugin GitHub topic, caches a compact index, and lets an MCP client inspect a candidate before touching local DSH state.
It can answer questions such as:
- Is this repository an installable Cordis bundle, an MCP server, a UI extension, or a directory?
- Does
package.jsondeclare a DSH bundle? - Is there a
cordis.patch.yml? - What GitHub install spec would the DSH CLI accept?
Catalog access is enabled by default. Install and runtime access are not.
That separation matters because a repository description is discovery metadata, not compatibility proof. The bridge also treats Cordis !!js config as opaque inspection data; it does not evaluate arbitrary config while cataloguing a repository.
Relevant source:
src/github/catalog.tssrc/plugin/inspect.tssrc/plugin/classify.tssrc/mcp/resources.ts
Profile: mutation requires an explicit opt-in
dsh_plugin_install and dsh_plugin_uninstall are disabled unless the operator starts the bridge with --allow-install (or the equivalent environment flag).
When enabled, the bridge delegates to the official command:
dsh plugin --profile <name> add|remove ...
It does not quietly edit a profile manifest itself. After the command returns, it reads the observed profile state back and returns the installed bundles and dependencies.
This is better than a boolean success response, but not enough for production. A mutating bridge should return a receipt containing at least:
- the immutable source commit;
- the profile diff;
- installed, skipped, and rejected components;
- requested capabilities;
- the first health check;
- an exact rollback action.
An external reviewer raised exactly this point on X, so it is now public issue #1.
Runtime: project live DSH tools into MCP
Runtime access is a second, independent opt-in: --allow-runtime.
When enabled, the host starts a dedicated DSH profile, reads the live ctx.tools registry, and projects compatible tools into the MCP server under deterministic dsh__* names.
MCP client
-> dsh__some_tool
-> bridge lookup and argument forwarding
-> live DSH ctx.tools.execute(...)
-> DSH policy and result pipeline
-> MCP result
The DSH runtime remains the execution owner. The bridge does not import arbitrary plugin executors into the MCP process.
This also means “plugin” does not automatically mean “MCP tool.” UI, TUI, theme, and configuration-only plugins can appear in the catalog without pretending to expose model-callable functions.
Relevant source:
src/runtime/host.tssrc/runtime/bridge.tssrc/dsh-plugin.tssrc/mcp/server.ts
Why we built this from BitFun
BitFun already uses MCP as one extension layer, while keeping workspace execution, permissions, sessions, remote control, and its desktop UI inside typed product boundaries.
DSH is interesting for the opposite reason: its runtime graph is deeply replaceable.
The bridge lets us test a middle path:
- BitFun keeps ownership of the workstation and user-facing control plane;
- DSH keeps ownership of a plugin composition and its live tool pipeline;
- MCP becomes the explicit boundary between them.
The same bridge can be used by any MCP-capable agent. It is not a BitFun-only protocol.
What we cannot say yet is “BitFun supports every DSH plugin.” Compatibility varies, packaging is unfinished, and install receipts and cancellation evidence still need work.
The production checklist
Before calling this mature, I want the project to prove:
- source provenance is immutable;
- profile mutations produce auditable receipts and tested rollback;
- bridged calls preserve DSH and host permission decisions;
- MCP cancellation reaches DSH and the underlying capability;
-
dsh__*names stay stable across reloads and collisions; - compatibility is tested against named DSH revisions;
- the npm instructions match an actually published artifact.
Until then, it is an architecture experiment with real code—not a polished package.
Source: https://github.com/bobleer/deepseek-harness-plugin-mcp
BitFun: https://github.com/GCWing/BitFun
If you use another MCP agent and have a specific DSH plugin in mind, open an issue with that exact pair. A concrete compatibility case is much more useful than “support all plugins.” If the direction is useful, a star tells us which side of the bridge to harden first.
Top comments (0)