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.jsonas an opt-in switch. - Tool naming format is
mcp__<serverName>__<toolName>. - Supports
stdiotransport, with support forcommand,args,env, andcwd. - Supports
streamable-httptransport, with support forurlandheaders. - Uses the
mcpServersJSON 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
toolCallTimeoutMsis60000,idleTimeoutMsis300000; settingidleTimeoutMsto0means never disconnect. - When conflicting with an upper preset/host connection for the same
serverName, it skips the upper layer by default; settingoverride: trueforces 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 ofmcpServers, used as the tool namespace; must match[A-Za-z0-9_-]{1,32}.command: Launch command forstdiotransport.args: Arguments forstdiotransport.env: Extra environment variables forstdiotransport.cwd: Subprocess working directory forstdiotransport; relative paths are resolved relative to the project root.url: MCP server URL forstreamable-httptransport.headers: Extra headers forstreamable-httptransport.toolCallTimeoutMs: Timeout for a single call, default60000.idleTimeoutMs: Disconnect time when idle, default300000; set to0to never disconnect.override: Whether to force using the project connection when the upper layer already provides the sameserverName, defaultfalse.transport: Usually no need to write manually; inferred asstdioifcommandexists, inferred asstreamable-httpifurlexists. 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
mcpServersconfiguration shape already existing in Claude Code, Cursor, and VS Code. - Need both
stdioandstreamable-httptypes 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
MITlicense before installing. - The plugin will read project configuration and may launch
commandor connect tourl; it runs under the currentdshprocess permissions. ${NAME}inenvandheadersexpands from the host process environment; do not write sensitive information to locations you cannot control the exposure scope.- Both
commandandurlmust be present (one of them), otherwise the transport cannot be inferred. serverNamemust 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