Diversion for VS CodeSource-control integration for Diversion — registers Diversion as a first-class SCM provider in VS Code, and ships a standalone stdio MCP server (
This v0.8 release catches up with Diversion's mid-2026 feature drop, and gets ahead of it:
Read operations are sourced from the Diversion CoreAPI ( What you get
See the Language Model Tools section for the full tool list — every Diversion operation the extension performs internally is also a tool both the in-VS-Code and out-of-VS-Code AI clients can call. Requirements
Installing the VS Code extensionOption 1: VS Marketplace (recommended)Install directly from the Visual Studio Marketplace, or from the command line:
You can also search for Diversion in the VS Code Extensions view ( Option 2: install the latest
|
| Variable | Effect |
|---|---|
DIVERSION_DV_PATH |
Path to the dv binary (default: PATH lookup). |
DIVERSION_DAEMON_URL |
Local agent base URL (default: auto-discovered). |
DIVERSION_CORE_API_URL |
CoreAPI base URL (default https://api.diversion.dev/v0). |
DIVERSION_CORE_TOKEN |
CoreAPI access token, used instead of asking the local agent to mint one. Useful where the agent isn't running. Not refreshed — supply a live token. |
DIVERSION_MAX_PARALLEL |
Cap on concurrent dv processes (default 4). |
DIVERSION_MCP_READONLY |
1/true/yes registers only read tools. |
DIVERSION_LOG_LEVEL |
off | error | warn | info | debug. |
Normally none of these are needed: the server discovers repos through the local agent and gets its CoreAPI token from it.
The -y flag silently accepts npx's "install on first run" prompt — without it some MCP clients hang waiting on a TTY they never provide.
Alternatives without npm
If npx isn't an option (offline machine, locked-down corporate network, you'd rather pin to a specific download):
# Option A — install globally from npm
npm install -g @mtuska/diversion-mcp
# then in your MCP config: command = "diversion-mcp"
# Option B — grab the standalone bundle from the GitHub release
curl -L -o diversion-mcp.js \
https://github.com/mtuska/diversion-vscode/releases/latest/download/diversion-mcp.js
chmod +x diversion-mcp.js
# then: command = "node"; args = ["/absolute/path/to/diversion-mcp.js"]
# Option C — from a source checkout
git clone https://github.com/mtuska/diversion-vscode.git
cd diversion-vscode
npm install
npm run build
sudo npm link
# then: command = "diversion-mcp"
npm install -g and npm link both create a diversion-mcp.cmd shim on Windows automatically — no extra steps needed there.
Verifying
Standalone handshake — should print a JSON protocolVersion line on stdout:
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' | npx -y @mtuska/diversion-mcp
No env config required
Diversion has a centralised local agent that already knows every workspace on the machine. The MCP server pulls workspaces from the agent's registry at startup — you don't have to declare paths, point at config files, or symlink anything. If the agent is offline, the server falls back to the current working directory; if the model passes a repo hint to any tool, the server registers that path on the fly.
Optional escape-hatch env vars:
| Var | Default | Purpose |
|---|---|---|
DIVERSION_DV_PATH |
dv on $PATH |
Override the dv binary location |
DIVERSION_DAEMON_URL |
(port-file discovery) | Override agent URL, e.g. http://127.0.0.1:38825 |
DIVERSION_MAX_PARALLEL |
4 |
Concurrent dv processes cap |
DIVERSION_LOG_LEVEL |
info |
off / error / warn / info / debug (logged to stderr) |
Platform support
| Platform | dv binary | VS Code extension | diversion-mcp |
|---|---|---|---|
| Linux | dv |
Tested. Active development platform. | Tested. |
| macOS | dv |
Should work; same dv semantics as Linux. Untested. |
Should work; same code path as Linux. |
| Windows | dv.exe |
Should work; path handling is sep- and case-aware. Untested with a real Windows dv install. | npx @mtuska/diversion-mcp works in cmd / PowerShell / Git Bash. The bundle is plain Node CJS with a shebang; npm-install-g and npm-link auto-generate a diversion-mcp.cmd shim for direct invocations. The dv binary is auto-resolved as dv.exe. |
If you hit a platform-specific issue, file it with the contents of the Diversion output channel and we'll triage. The Diversion: Run Performance Trace command's output is also useful — it tells us whether the daemon and dv itself are responding the way we expect.
VS Code extension features
Source Control panel
- One Diversion provider per repo, keyed by the actual
.diversion/ancestor — opening a sub-directory still registers correctly. - Resource groups: Conflicts, Staged Changes, Changes, New. Conflicts (
*.dv-conflict.*sidecars) surface automatically. - Inline +/− buttons on every resource (stage / unstage), plus context-menu Stage / Unstage / Commit Selected / Discard. Multi-select works.
- Staging is persisted per-workspace via
workspaceState, so it survives reloads. - Commit picks the staged paths if any are staged, otherwise commits all (
dv commit <paths> -m/dv commit -a -m). - Generate Commit Message (sparkle button on the SCM input box) hands the current diff to your configured VS Code language model and drops the result into the commit message box.
- QuickDiff (gutter + side-by-side) via reverse-applied unified diff. Binary files skip the diff path and open directly.
Repo header (per-repo … menu)
- Branch pill (
$(git-branch) <name>) — click to switch branches. - Ellipsis button next to it opens a categorised quick-pick: Actions / Branch / Sync / Locks / View. Right-click on the repo row gets you the same menu.
- Sync verbs (no push/pull — Diversion auto-syncs commits): Update Workspace, Pause Sync, Resume Sync, Verify Repository.
History
- VS Code's built-in Source Control Graph populates with branches, commit timestamps, parents, and per-commit file lists. Clicking a file opens a real side-by-side diff for that commit (via a
dv-commit:content scheme). - View History webview as a textual fallback.
- Cherry-pick / Revert / Restore-to-commit commands.
Game-dev specific
- Hard locks (
dv lock): 🔒 explorer badges via FileDecorationProvider, Lock / Unlock / List Locks commands. Server-side gated to Studio / Enterprise tiers. - Sync conflict resolution for
*.dv-conflict.*sidecars (a Diversion concept distinct from merge conflicts). - Shelves tree view (
dv shelf): create / apply / delete / rename plus Shelve-and-switch-branch. - Inline blame (
dv annotate) —Diversion: Toggle Blame. Block-grouped GitLens-style.
Performance
- Batched per-commit prefetch when the SCM Graph expands a commit (one
dv diff --base <commit>call instead of N). - Persistent on-disk cache for commit content (50 MB, mtime LRU, segmented by dv version) — re-opening the same commit's diffs is ~1 ms after the first session.
Diversion: Run Performance Traceruns a known battery and writes per-step timings to the output channel, useful for triage.diversion.maxParallelProcessescaps concurrentdvinvocations (default 4). Bump it on fast machines to speed up SCM Graph prefetch.
Language Model Tools
Every Diversion operation in the extension is also exposed to AI models through two paths:
- Inside VS Code — 37 tools registered via
vscode.lm.registerTool. Copilot Chat (and any provider that uses VS Code's language-model API) can invoke them, and the#dvStatus-style chat references work for the read-side tools. - Outside VS Code — 39 tools through the
diversion-mcpstdio MCP server. The 2 extras over the VS Code side aredv_list_repos(inspect the MCP server's own registry) anddv_open_in_web(launchdv viewfrom a headless client).
The tools are otherwise identical; both share the same Repo facade, the same parsers, and the same dv-CLI runner under the hood. The table below lists tools by their MCP names with the #dv… reference name shown for the in-VS-Code equivalent.
Awareness tools (read-only)
| Tool | What it does |
|---|---|
dv_status / #dvStatus |
Branch, commit, sync state, working-tree changes |
dv_diff / #dvDiff |
Working-tree unified diff, optionally scoped to paths |
dv_diff_refs / #dvDiffRefs |
Diff between two refs (commit / branch / tag) |
dv_log / #dvLog |
Recent commits with since / until date filters |
dv_file_history / #dvFileHistory |
git log -- <path> equivalent for a single file or directory |
dv_overlapping_commits / #dvOverlap |
Recent commits that touch the same paths you have dirty — "what might conflict with my work" |
dv_show / #dvShow |
Full details for a single commit, including its file list |
dv_branches / #dvBranches |
Branch list with tip commits |
dv_list_tags / #dvListTags |
All tags (backed by dv tag --json for stable output) |
dv_list_cloud_repos / #dvListCloudRepos |
Repos the dv account has access to (cloned vs remote-only) |
dv_list_repos (MCP only) |
Repos this MCP server has registered — inspect the registry. In VS Code the SCM panel already shows the same info |
dv_shelves / #dvShelves |
List shelves |
dv_show_shelf / #dvShowShelf |
Inspect a single shelf's contents |
dv_locks / #dvLocks |
Active hard locks |
dv_annotate / #dvAnnotate |
Per-line blame for a file |
Action tools (write)
| Tool | What it does |
|---|---|
dv_commit / #dvCommit |
Commit working-tree changes, optionally scoped to paths |
dv_create_branch / #dvCreateBranch |
Create a branch (optionally switch to it) |
dv_delete_branch / #dvDeleteBranch |
Delete a branch |
dv_rename_branch / #dvRenameBranch |
Rename a branch |
dv_checkout / #dvCheckout |
Check out a ref with take/shelve/discard semantics |
dv_merge / #dvMerge |
Merge a ref into the current branch |
dv_cherry_pick / #dvCherryPick |
Cherry-pick a single commit |
dv_revert_commit / #dvRevertCommit |
Create a new commit that inverts a past commit |
dv_revert_to_commit / #dvRevertToCommit |
Restore the workspace to a past commit |
dv_restore_path / #dvRestorePath |
Restore one path from a ref |
dv_discard_path / #dvDiscardPath |
Discard changes to a single path |
dv_discard_all / #dvDiscardAll |
Discard all working-tree changes (optionally including new files) |
dv_create_tag / #dvCreateTag |
Tag a commit |
dv_create_shelf / #dvCreateShelf |
Shelve current changes |
dv_apply_shelf / #dvApplyShelf |
Apply a shelved changeset |
dv_delete_shelf / #dvDeleteShelf |
Delete a shelf |
dv_rename_shelf / #dvRenameShelf |
Rename a shelf |
dv_lock_path / #dvLockPath |
Acquire a hard lock (Studio / Enterprise) |
dv_unlock_path / #dvUnlockPath |
Release a hard lock |
dv_pause_sync / #dvPauseSync |
Pause background sync |
dv_resume_sync / #dvResumeSync |
Resume background sync |
dv_update_workspace / #dvUpdateWorkspace |
Force-pull base-branch updates |
dv_verify / #dvVerify |
Run dv's integrity verification |
dv_open_in_web (MCP only) |
Open the workspace in the Diversion web UI (dv view). The VS Code extension already has a Diversion: Open in Web UI palette command for this |
In multi-repo workspaces every tool accepts an optional repo argument (repo name or absolute path). With a single repo open it can be omitted.
Not implemented yet
- Selective sync editor (
dv preferences sync_paths_rules). - Workspace switcher (multiple workspaces of the same repo).
- Review requests —
dv reviewcan open one, but there's no endpoint to read review state back, so there's nothing to render. - Multi-lane DAG layout in the graph (currently linear-with-merge-markers).
- There is no Push or Pull — Diversion auto-syncs commits. This is by design, not an oversight.
Building
npm install
npm run build # one-shot bundle of extension + MCP server
npm run watch # esbuild watch mode for both
npm run typecheck # tsc --noEmit, strict
npm test # vitest unit tests (parsers + CLI runner)
npm run package # produce a .vsix via vsce — includes out/mcp.js
Press F5 in VS Code to launch the Extension Development Host. The Run Extension on SampleRepo launch configuration opens an example workspace at ~/Diversion/SampleRepo if you have one.
Testing the MCP server in a real workspace
# end-to-end roundtrip
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}'
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
sleep 1) | node out/mcp.js | jq -r 'select(.id==2) | .result.tools | length'
# → 39
Sanity-check daemon detection
node scripts/smoke-detect.mjs ~/Diversion/MyRepo
Settings
| Setting | Default | Description |
|---|---|---|
diversion.path |
"" |
Path to the dv binary. Empty uses the system PATH lookup. |
diversion.daemonUrl |
"" |
Override the daemon URL (e.g. http://127.0.0.1:38825). Empty discovers from ~/.diversion/.port. |
diversion.refresh.debounceMs |
150 |
Debounce window (ms) for filesystem-watcher-driven SCM refresh. Editor-originated events (save/create/delete/rename) bypass this and refresh immediately. |
diversion.maxParallelProcesses |
4 |
Cap on concurrent dv CLI processes (1–32). Higher = faster bulk operations, more CPU and daemon load. |
diversion.binaryExtensions |
[] |
Extra file extensions (with leading dot, e.g. ".uplugin") to treat as binary — they skip side-by-side diff and open directly. |
diversion.scm.showAllRepoChanges |
false |
When opening a sub-directory of a repo, the SCM panel scopes changes to that folder by default. Enable to see all changes in the repo. |
diversion.repositoryScanMaxDepth |
1 |
How many directory levels below each workspace folder to scan for nested .diversion repos. 0 disables nested scanning. Mirrors git.repositoryScanMaxDepth. |
diversion.log.level |
"info" |
Output channel verbosity (off/error/warn/info/debug). |
The MCP server doesn't read VS Code settings — it's a separate process. Use the env vars in the Installing the MCP server section above.
Architecture
┌──────────────────────────┐
│ src/diversion/ │
│ daemon.ts (AgentAPI) │
│ cli.ts (spawn dv) │
│ repo.ts (high-level) │
│ parsers/ (text → typed)│
└────────────┬─────────────┘
│
┌──────────────────────┼──────────────────────┐
│ │ │
┌───────▼───────┐ ┌───────▼────────┐ ┌────────▼────────┐
│ src/extension │ │ src/ai/tools.ts │ │ src/mcp/ │
│ (VS Code SCM) │ │ (vscode.lm) │ │ (stdio MCP) │
└───────────────┘ └─────────────────┘ └─────────────────┘
│ │
▼ ▼
Copilot Chat Claude Code / Codex /
Claude Desktop / Cursor /
anything MCP-aware
The extension and the MCP server share everything except their host-binding layer: the same dv-CLI runner, the same daemon HTTP client, the same parsers, the same Repo facade. The split is mechanical (vscode dependency vs not), so a tool added to one trivially mirrors to the other.
For the v0.1 design rationale, mapping of VS Code SCM concepts to dv commands, risks (CLI output drift, QuickDiff fragility), and the v0.2+ roadmap, see docs/PLAN.md.
Hard rules baked into the UX
- Never invent CLI flags. Every flag is verified against
dv help <cmd>. - Never assume git semantics. No push, no pull. (Conflict markers are the one borrowed idea — they're how VS Code's built-in per-block resolution UI is driven, not how Diversion stores conflicts.)
- Always parse
dvoutput through small, fixture-backed parsers — never a single mega-regex. - Never invent an auth flow. The CoreAPI bearer is minted by the local agent and kept in memory only — we never handle the user's credentials.
- Writes go through the
dvCLI so the local agent stays authoritative on sync state. The sole exception is merge-conflict resolution, which has no CLI equivalent. - Never assume
dvdetects a non-TTY. Pass the skip-flag on anything that prompts, or it hangs forever.
License
The Unlicense — public domain dedication. See LICENSE.