AgentStack
MCP verified MIT Self-run

Sync Worktrees

mcp-yordan-kanchelov-sync-worktrees · by yordan-kanchelov

Auto-sync Git worktrees with remote branches. Includes an MCP server so Claude Code, Cursor & other AI agents can inspect and manage worktrees.

No reviews yet
0 installs
10 views
0.0% view→install

Install

$ agentstack add mcp-yordan-kanchelov-sync-worktrees

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Sync Worktrees? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

sync-worktrees

> Keep every branch and every repo you work on checked out as predictable directories — no stashing, no re-cloning, no re-orienting your AI assistant.

Contents: [Why](#why-sync-worktrees) · [How it works](#how-it-works) · [Quick start](#quick-start) · [MCP server](#mcp-server) · [Interactive TUI](#interactive-tui) · [CLI options](#cli-options)

Why sync-worktrees

If you've ever:

  • Stashed half-finished work just to check out another branch
  • Lost minutes hunting for where you cloned a sibling repo
  • Switched branches in five repos because one feature spans them all
  • Re-explained to an AI assistant which directory holds which branch

…sync-worktrees fixes that. It keeps the entire branch and repo layout you work in materialized on disk — one directory per branch, automatically kept in sync with the remote. Switching branches becomes cd. Searching across repos becomes grep -r. AI agents see the same shape you do, so "look in the other repo" actually works.

It's also a clean answer to dev-environment bootstrapping. One config file describes every repo, branch, and folder layout your team works in. Hand it to a new hire (or a fresh laptop) and sync-worktrees lays down the whole workspace in a single command — no day-one cloning checklist, no "where do I put this repo?" Slack threads.

Runs as a one-shot, a background daemon, or an interactive TUI — and ships an MCP server so AI assistants can list, create, and inspect worktrees themselves.

How it works

The default — worktree mode — gives every remote branch its own directory while sharing one Git database underneath:

  1. First run clones the repo once as a bare repository (just the Git data, no working files).
  2. Each sync:
  • Creates a directory for every remote branch (main, develop, feature/*).
  • Fetches latest changes (no merge — your local work stays untouched).
  • Removes directories for branches deleted upstream (preserves dirty trees and unpushed commits).

The bare repository is not an extra object store layered on top — it is the single Git database every worktree attaches to natively, so branches share history for free (no --reference, no alternates). The bare layout exists only so that no branch is a privileged "main" checkout: every branch, the default included, is a peer directory.

Smallest config that produces this:

// sync-worktrees.config.js
// @ts-check

/** @satisfies {import("sync-worktrees").SyncWorktreesConfig} */
const config = {
  repositories: [
    {
      name: "my-repo",
      repoUrl: "https://github.com/user/my-repo.git",
      worktreeDir: "./worktrees/my-repo",
    },
  ],
};

export default config;

Run sync-worktrees from the directory holding the config and you get:

.
├── sync-worktrees.config.js
├── .bare/
│   └── my-repo/             # Bare repository (shared Git objects)
└── worktrees/my-repo/
    ├── main/                # Worktree for main branch
    ├── feature-1/           # Worktree for feature-1 branch
    └── feature-2/           # Worktree for feature-2 branch

Clone mode (mode: "clone") is a first-class alternative: a plain git clone of one branch into worktreeDir, no bare repo, no per-branch subfolders. Reach for it when you want a repo to live at a fixed path — a dependency sibling, a single-branch dev clone, or any case where one checkout is enough. See [Clone mode](#clone-mode).

Features

  • Filtering & lifecycle — branch name globs, age filtering, sparse checkout, automatic divergence detection with .diverged/ preservation, retry with exponential backoff.
  • Interactive TUI — Ink-based UI with wizards for opening worktrees, creating branches, and inspecting status; diverged-directory management; live log streaming; multi-repo filtering.

Installation

npm install -g sync-worktrees

Quick start

sync-worktrees always runs against a config file. Create one once, then run the tool.

cd ~/projects/my-sync-dir
sync-worktrees init      # interactive wizard → writes sync-worktrees.config.js
sync-worktrees           # auto-loads the config in the current directory and starts syncing

By default, bare sync-worktrees launches the [interactive TUI](#interactive-tui) and keeps syncing on the cron schedule from your config. Press q to quit. For a one-shot run (CI, scripts, ad-hoc), add --runOnce.

To manage multiple repositories, edit the generated config file and add entries under repositories. See [Configuration](#configuration).

If the config lives outside the current directory, pass it explicitly:

sync-worktrees --config /path/to/sync-worktrees.config.js
sync-worktrees --config /path/to/sync-worktrees.config.js --runOnce
sync-worktrees list --config ./config.js --filter "frontend-*"

MCP server

sync-worktrees ships a Model Context Protocol server so AI assistants (Claude Desktop, Claude Code, Cursor, Windsurf, etc.) can inspect and operate your workspace directly. Installing the package exposes a second binary, sync-worktrees-mcp, that speaks MCP over stdio.

In a single call, an AI assistant can discover every repo and worktree you have configured — so an agent working in frontend/ can grep across backend/ and shared/ without you reorienting it. That call is detect_context with includeAllWorktrees: true; the response also includes a per-capability { available, reason } block telling the agent which operations are reachable from its current vantage point, so there's no guessing whether sync will work. See [Available tools](#available-tools) for the full surface.

Getting started

Install the sync-worktrees MCP server with your client.

Standard config works in most tools:

{
  "mcpServers": {
    "sync-worktrees": {
      "command": "npx",
      "args": ["-y", "-p", "sync-worktrees", "sync-worktrees-mcp"],
      "env": {
        "SYNC_WORKTREES_CONFIG": "/absolute/path/to/sync-worktrees.config.js"
      }
    }
  }
}

If installed globally, replace command with sync-worktrees-mcp and drop args. SYNC_WORKTREES_CONFIG is optional — without it the server runs in auto-detect mode: when the client's CWD sits inside a worktree managed by sync-worktrees, the server locates the bare repo, enumerates sibling worktrees, and enables per-worktree operations. sync and initialize require a loaded config (or call load_config at runtime).

Claude Code

Use the Claude Code CLI:

claude mcp add sync-worktrees -- npx -y -p sync-worktrees sync-worktrees-mcp

To pass a config path, append -e SYNC_WORKTREES_CONFIG=/absolute/path/to/sync-worktrees.config.js to the command.

Claude Desktop

Edit claude_desktop_config.json and paste the standard config above into the mcpServers block. Default locations:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Restart Claude Desktop after editing.

Cursor

Edit ~/.cursor/mcp.json (global) or .cursor/mcp.json (per-project). Paste the standard config above.

Or open Cursor SettingsMCPAdd new MCP Server, pick command type, and enter npx -y -p sync-worktrees sync-worktrees-mcp.

Windsurf

Follow the Windsurf MCP documentation and use the standard config above.

VS Code

Use the VS Code CLI:

code --add-mcp '{"name":"sync-worktrees","command":"npx","args":["-y","-p","sync-worktrees","sync-worktrees-mcp"]}'

Or follow the VS Code MCP install guide and use the standard config above.

Codex

Use the Codex CLI:

codex mcp add sync-worktrees -- npx -y -p sync-worktrees sync-worktrees-mcp

Or edit ~/.codex/config.toml:

[mcp_servers.sync-worktrees]
command = "npx"
args = ["-y", "-p", "sync-worktrees", "sync-worktrees-mcp"]

Gemini CLI

Follow the Gemini CLI MCP install guide and use the standard config above.

Cline

Edit cline_mcp_settings.json (see Configuring MCP Servers) and add:

{
  "mcpServers": {
    "sync-worktrees": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "-p", "sync-worktrees", "sync-worktrees-mcp"],
      "disabled": false
    }
  }
}

opencode

Edit ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "sync-worktrees": {
      "type": "local",
      "command": ["npx", "-y", "-p", "sync-worktrees", "sync-worktrees-mcp"],
      "enabled": true
    }
  }
}

Warp

Open SettingsAIManage MCP Servers+ Add (see Warp MCP docs) and paste the standard config above. Alternatively, run /add-mcp in the prompt.

Available tools

| Tool | Purpose | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | detect_context | Inspect a path, resolve the bare repo, enumerate sibling worktrees, report config-driven sibling repositories and capabilities. Pass includeAllWorktrees: true to include every configured repo's worktrees keyed by repo name. | | list_worktrees | List worktrees with status label (clean/dirty/stale/current), divergence, safeToRemove, last sync. Without repoName and with a loaded config, results are grouped across all configured repos. | | get_worktree_status | Detailed status for one worktree (dirty files, unpushed commits, stashes, operation in progress). | | create_worktree | Create a worktree for a branch; optionally create the branch from baseBranch. Newly created branches are pushed to origin unless push=false. | | update_worktree | Fast-forward one worktree to match upstream. | | sync | Full sync cycle (fetch, create, prune, update). Requires config. Streams progress notifications. | | initialize | Clone the bare repo and create the main worktree. Requires config. Streams progress. | | load_config | Load or reload a config file at runtime. | | set_current_repository | Select the active repo when multiple are configured. |

All tools that target a single repo accept an optional repoName. When omitted, they use the current repository — set by auto-detect, the first entry in the config, or set_current_repository.

Safety

  • The MCP surface exposes no removal or trash operations — an agent cannot delete a worktree or touch the trash through it. Removal happens via sync's own safety-gated pruning or manual git commands.
  • create_worktree rejects sanitized-path collisions (e.g. feature/foo vs feature-foo both resolving to feature-foo/) before touching disk.
  • Branches created by sync-worktrees use --no-track first, then publish with git push -u origin , so they do not inherit origin/main as their upstream.
  • Path-targeted tools verify the supplied path is a registered worktree of the selected repository.

Interactive TUI

Running sync-worktrees without runOnce drops you into an interactive terminal UI with live log streaming, manual sync triggers, and wizards for the common operations.

Keybindings

| Key | Action | | ----------- | ---------------------------------------------- | | s | Manually trigger sync for all repositories | | c | Create a new branch (wizard) | | o | Open a worktree in terminal or editor (wizard) | | w | View worktree status across repos | | r | Reload configuration and re-sync | | ? / h | Toggle help screen | | q / Esc | Gracefully quit | | j / | Scroll log down one line | | k / | Scroll log up one line | | gg | Jump to top of log | | G | Jump to bottom (re-enables auto-scroll) |

Wizards

  • Open wizard (o) — select a worktree across all configured repos with live filtering (just type to narrow the list). Press Tab to flip between Terminal mode (launches a new terminal window attached to a tmux session in the worktree) and Editor mode (launches $EDITOR / $VISUAL, falling back to code). Re-opening the same worktree attaches to the existing tmux session instead of creating a duplicate.
  • Branch creation wizard (c) — pick a repo, pick a base branch from a live-filtered list, type the new branch name. Names are validated against Git's rules; if the desired name already exists, a numeric suffix (-2, -3, …) is suggested automatically.
  • Worktree status view (w) — flat list of every worktree across every configured repo, each tagged with status flags:

| Flag | Meaning | | ---- | -------------------------------------------------------------- | | | Clean | | M | Modified / uncommitted changes | | | Unpushed commits | | | Commits absent from every remote but fully pushed before the remote branch was deleted (likely squash-merged) | | S | Stashed changes | | | Operation in progress (merge/rebase/cherry-pick/revert/bisect) | | | Modified submodules | | | Upstream branch is gone |

Press Enter on an entry to expand file/commit/stash counts. The view also surfaces .diverged/ directories preserved from past force-pushes; press d (with y/n confirmation) to delete one after reviewing.

Terminal mode environment variables

| Variable | Purpose | Default behavior

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.