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

  • jj version ≥ 0.2x (can be installed with brew 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