DeepSeek Harness (DSH) follows the philosophy that “everything is a plugin.” In agent development, handling version control is often constrained by git semantics. This plugin exposes the local jj CLI as mcp__jj__* tools through a zero-dependency MCP stdio server, enabling the model to perform version control operations in jj repositories using jj semantics.
Prerequisites¶
jjversion ≥ 0.2x (can be installed withbrew install jujutsu, or refer to the official documentation).- Node.js ≥ 18 (the server uses only the standard library and has no additional dependencies).
Installation and Enablement¶
Add the bundle via the official directory:
dsh plugin --profile web add github:LosEcher/dsh-jj#main
For local development or when modifying the source code:
dsh plugin --profile web add link:/path/to/dsh-jj
After installing a new bundle, restart dsh web (HMR usually does not cover configuration changes):
~/.dsh/scripts/dsh-web-restart.sh
Configuration Notes¶
The bundle patch uses command: jj-mcp (the package’s bin entry). If the PATH of the dsh process does not include the node_modules/.bin directory (common in launchd-managed scenarios), MCP service startup will fail. In that case, override it with an absolute path in the user patch layer:
- id: mcp-jj
config:
serverName: jj
transport: stdio
command: node
args: ['/absolute/path/to/dsh-jj/server.mjs']
env:
JJ_MCP_BIN: '/path/to/jj'
failOnStartupError: false
toolCallTimeoutMs: 120000
Core Features¶
The plugin encapsulates common jj operations as mcp__jj__* tools. All tools support an optional repo parameter.
| Tool | Description |
|---|---|
jj_status |
Get a summary of the current change and workspace modifications |
jj_log |
View the change graph (alternative to git log) |
jj_diff |
View the diff of a specified change |
jj_describe |
Set or update a change description |
jj_new |
Start a new empty change |
jj_commit |
Seal the current change and start a new change |
jj_edit |
Switch to an existing change and continue editing |
jj_abandon |
Discard a change (can be undone) |
jj_undo |
Undo the previous jj operation |
jj_rebase |
Move a change to a new parent |
jj_fetch |
Fetch remote branches into bookmarks |
jj_push |
Push a bookmark to a remote |
jj_bookmark |
Manage bookmarks (similar to git branches) |
jj_run |
Generic pass-through (security restrictions apply) |
Security Design:
* All tools invoke jj using spawn with array arguments, without shell involvement, making them immune to argument injection.
* The jj_run tool filters out the --config / --config-toml / --config-file arguments to prevent arbitrary command execution through configuration items.
* jj itself supports jj undo / jj op restore, and the risk of destructive operations is relatively low.
Environment Variables¶
| Variable | Default | Description |
|---|---|---|
JJ_MCP_BIN |
/opt/homebrew/bin/jj or jj |
Path to the jj binary; configure manually if automatic detection fails |
JJ_MCP_TIMEOUT_MS |
60000 |
Timeout for a single call |
JJ_MCP_DEFAULT_REPO |
Empty | Default repository directory |
JJ_MCP_LOG |
1 |
0 can disable the stderr startup banner |
Standalone Usage¶
This server is a standard MCP stdio server and can also be used directly with Claude Code or Codex:
npx -y jj-mcp
Summary¶
This plugin is suitable for scenarios where version control is needed in DeepSeek Harness using Jujutsu. It maps jj’s native semantics to MCP tools, avoiding the model forcing jj operations into a git mindset. After installation, restart dsh web. If the runtime environment is special (such as launchd), pay attention to PATH configuration.
- Directory page: https://www.skillhub.cn/plugins/LosEcher/dsh-jj
- GitHub repository: https://github.com/LosEcher/dsh-jj