Introduction

In DSH, MCP servers are typically configured at the host or preset layer, suitable for general capabilities. However, if you only want a specific project’s session to see that project’s MCP tools—such as a project-specific GitHub server or a local API—without affecting other projects, you can place the configuration in the project root directory.

Below is an introduction to dsh-project-mcp-bridge. Upon discovering .dsh/mcp.json in the project root directory, it registers the MCP tools declared within it for that project’s sessions.

What is This

dsh-project-mcp-bridge is maintained by KYinCode and is a DeepSeek Harness client bridge plugin.

Its main function is to consume MCP servers: it reads the servers declared in .dsh/mcp.json and registers the tools provided by these servers in DSH sessions. It is not an MCP server, nor is it an official DeepSeek package.

When there is no .dsh/mcp.json in the project root directory, the project’s sessions are unaffected. Once the file exists, the corresponding project session automatically gains the declared MCP tools.

The license is MIT.

Core Features

The core capabilities of dsh-project-mcp-bridge are as follows:

  • Uses the existence of .dsh/mcp.json as an opt-in switch.
  • Tool naming format is mcp__<serverName>__<toolName>.
  • Supports stdio transport, with support for command, args, env, and cwd.
  • Supports streamable-http transport, with support for url and headers.
  • Uses the mcpServers JSON shape, consistent with Claude Code, Cursor, and VS Code.
  • After saving .dsh/mcp.json, running project sessions will re-resolve the configuration and fully rebuild the project MCP surface.
  • Connections are isolated by agent/session and are not pooled; lazy connect on the first tool call.
  • Supports per-call timeout and idle timeout; default toolCallTimeoutMs is 60000, idleTimeoutMs is 300000; setting idleTimeoutMs to 0 means never disconnect.
  • When conflicting with an upper preset/host connection for the same serverName, it skips the upper layer by default; setting override: true forces the use of the project connection, while the upper connection remains.

Installation and Usage

Normal Installation

For normal use, install to the web profile using the DSH CLI:

dsh plugin --profile web add dsh-project-mcp-bridge

Restart dsh web once after installation:

dsh web

This step ensures bundle layers are composed at startup. Afterwards, modifying .dsh/mcp.json supports hot reloading; you do not need to restart dsh web for every configuration change.

Hot Install for Dev Path

If you want to iterate on the plugin itself locally and have changes take effect without a restart, you can install via the user patch row method. Do not use dsh plugin add for this path, otherwise, an extra line will be added outside the bundle registration.

First, switch to the profile directory:

cd ~/.dsh/profiles/web

Install the package to the profile’s node_modules:

pnpm add dsh-project-mcp-bridge

Then append to ~/.dsh/profiles/web/cordis.patch.yml:

- insert:
    - id: dsh-project-mcp-bridge
      name: 'dsh-project-mcp-bridge'

The name here is the package name, not a file:// path. This path is suitable for local development iteration; for daily use, prefer the bundle installation method above.

Typical Usage

Declare a stdio MCP Server

Declare a GitHub server in MyProject/.dsh/mcp.json:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}

After saving, sessions under MyProject can call:

mcp__github__create_issue

Placeholders like ${NAME} in env and headers will be expanded from the host process environment.

Declare a streamable-http MCP Server

If the MCP server exposes an HTTP endpoint, you can configure url and headers:

{
  "mcpServers": {
    "local-api": {
      "url": "http://localhost:3000/mcp",
      "headers": {
        "Authorization": "Bearer ${MCP_TOKEN}"
      },
      "override": true
    }
  }
}

In this example, override is set to true. If the upper preset/host already provides a local-api with the same name, the plugin will force the use of the connection from the project; the upper connection remains, and project tools win in terms of visibility for tools with the same name.

Common Configuration Fields

Configuration field names are consistent with dsh-mcp-client:

  • serverName: Required, the JSON key of mcpServers, used as the tool namespace; must match [A-Za-z0-9_-]{1,32}.
  • command: Launch command for stdio transport.
  • args: Arguments for stdio transport.
  • env: Extra environment variables for stdio transport.
  • cwd: Subprocess working directory for stdio transport; relative paths are resolved relative to the project root.
  • url: MCP server URL for streamable-http transport.
  • headers: Extra headers for streamable-http transport.
  • toolCallTimeoutMs: Timeout for a single call, default 60000.
  • idleTimeoutMs: Disconnect time when idle, default 300000; set to 0 to never disconnect.
  • override: Whether to force using the project connection when the upper layer already provides the same serverName, default false.
  • transport: Usually no need to write manually; inferred as stdio if command exists, inferred as streamable-http if url exists. One must be present.

Conflicts and Hot Reload

Conflicts with Upper Layer MCP

Tools are registered to the agent scope layer, and the visibility priority is:

project > preset > host

When the preset/host layer already provides an MCP row with the same serverName, the default behavior is to skip this server in the project configuration to ensure the project session can still start.

If you indeed want the project connection to override the upper layer’s same-name server, you can set:

"override": true

Note that override does not close the upper connection. The project connection is added on top of the upper connection, and the upper connection remains; tools with the same name are shadowed by the project registration item in the agent layer, and the model actually calls the project connection. The tool name itself does not carry a source marker.

Different serverName or different tool names can coexist.

If duplicate serverName appears between the host row and preset row in the official dsh-mcp-client, it will fail to mount, requiring a unique serverName to be chosen. dsh-project-mcp-bridge defaults to skip when there is a conflict at the project layer rather than failing the entire mount.

Hot Reload

After saving .dsh/mcp.json, the running sessions of that project will re-parse the configuration and fully rebuild the project MCP surface:

  • Add server: Perform schema sync, register new tools.
  • Delete server: Unregister tools and close corresponding connections.
  • Modify server: Full rebuild, unregister old tools, close connections, re-read, re-register.
  • Delete config file: Uninstall all MCP tools for that project.

Configuration file polling is about 500ms with a 300ms debounce. No need to open a new session after saving.

Suitable Scenarios and Notes

Suitable for the following scenarios:

  • Want to declare MCP servers per project instead of putting them all at the host or preset layer.
  • Want to reuse the mcpServers configuration shape already existing in Claude Code, Cursor, and VS Code.
  • Need both stdio and streamable-http types of MCP servers.
  • Isolate MCP tools by project in the DSH web profile.
  • Iterate on the plugin locally and want to use the user patch row hot install path.

Suggestions before use:

  • It is not an official DeepSeek package; check source code, dependencies, and the MIT license before installing.
  • The plugin will read project configuration and may launch command or connect to url; it runs under the current dsh process permissions.
  • ${NAME} in env and headers expands from the host process environment; do not write sensitive information to locations you cannot control the exposure scope.
  • Both command and url must be present (one of them), otherwise the transport cannot be inferred.
  • serverName must satisfy [A-Za-z0-9_-]{1,32}.

Resources

  • GitHub: https://github.com/KYinCode/dsh-project-mcp-bridge
  • Directory Page: https://www.skillhub.cn/plugins/KYinCode/dsh-project-mcp-bridge