Commands
Global flags
These flags apply to all md commands:
| Flag | Description |
|---|---|
--runtime <runtime> | Select container runtime: docker or podman (default: auto-detect) |
--control-master | Enable SSH ControlMaster connection multiplexing (disabled on Windows) |
-v, --verbose | Verbose output |
Container lifecycle
| Command | Description |
|---|---|
md start | Create and start a container for the current branch; SSH in automatically |
md start -display | Start with X11/VNC desktop environment |
md start -tailscale | Start with Tailscale networking |
md start -usb | Start with USB device passthrough (for ADB, Linux only) |
md start -no-ssh | Start container without opening an SSH session |
md run <cmd> | Start a temporary container, run a command, then clean up |
md fork | Snapshot a running container and create a new one on fresh branches |
md list | List all md containers |
md list --json | List containers as JSON |
md list --stats | Include resource usage stats (CPU, memory, disk, network) |
md sudo-password | Print the container's random sudo password |
md stop | Stop the container (preserves filesystem for later revival) |
md start (on stopped container) | Revive a stopped container (re-queries SSH port, restores SSH config) |
md purge | Stop and permanently remove the container |
Start flags
| Flag | Description |
|---|---|
-b, -branch <name> | Branch to use (default: current branch) |
-r, -repo <path> | Path to git repository (default: current directory) |
--image <ref> | Full base Docker image (e.g. ghcr.io/caic-xyz/md-user:2026-05-09) |
--tag <tag> | Tag for the default base image (ghcr.io/caic-xyz/md-user:<tag>) |
--display, -d | Enable X11/VNC virtual desktop (port 5901) |
--tailscale | Enable Tailscale networking |
--usb | Pass through USB devices (/dev/bus/usb, Linux only) |
--github | Inject GITHUB_TOKEN into the container |
--no-ssh | Don't SSH into the container after starting |
--cpus <n> | Max CPU cores (default: NumCPU - 2, minimum 2; 0 = no limit) |
--label key=value, -l | Add Docker container label (repeatable) |
--extra-repo path[:branch], -e | Map an additional git repository (repeatable) |
--docker-flag "arg1 arg2" | Extra flags passed verbatim to docker run (shell-quoted, repeatable) |
--sudo | Enable root access with a random password; grants SYS_ADMIN and /dev/fuse |
-q, --quiet | Suppress informational output |
--control-master | Enable SSH ControlMaster connection multiplexing |
Access
| Command | Description |
|---|---|
ssh md-<repo>-<branch> | SSH into the container directly |
md vnc | Open VNC connection to the container desktop |
Syncing
| Command | Description |
|---|---|
md diff | Show changes vs. base branch (git diff base). Extra args forwarded to git, e.g. md diff --stat |
md diff --all | Show diffs for all repos in the container |
md pull | Pull changes from container and integrate into local branch |
md pull --all | Pull changes for all repos |
md fetch | Fetch changes from container without integrating (updates remote-tracking ref) |
md push | Force-push local state into the container; creates a backup branch inside |
Fork
md fork snapshots a running container's entire filesystem (installed packages, build artifacts, agent state) and creates a new container where each repo is checked out on a fresh branch.
# Fork the current container
md fork
# Fork a specific container by name
md fork -source md-myrepo-main
# Fork with extra repos and VNC
md fork -e ../other-project -displayFork flags mirror md start plus:
| Flag | Description |
|---|---|
-s, --source <name> | Source container name (default: auto-detect from repo) |
--sudo | Enable root access with a random password; grants SYS_ADMIN and /dev/fuse |
-q, --quiet | Suppress informational output |
Each repo (source and extra) gets a unique destination branch derived from its source branch (e.g. main → main-0, then main-1, etc.).
Run
md run <cmd> starts a temporary container, runs a command, and cleans up everything:
md run -- npm test
md run -- cargo check
md run --image ghcr.io/caic-xyz/md-user:2025-05-09 -- npm ciSupports: --image, --tag, --repo, --branch, --github, --cpus, --docker-flag, and all cache flags.
Workflows
Multi-repo containers
Map multiple repositories into a single container with --extra-repo:
# Start with main project + dependency
md start -r ~/src/backend -e ~/src/shared-lib
# Specify branches explicitly
md start -b feature-x -e ~/src/shared-lib:feature-xAll repos are cloned into ~/src/<name> inside the container. The first repo is primary; extras are pushed alongside it. md diff, md pull, and md push operate on the repo matching your current directory. Use --all to operate on all repos:
md diff --all # show diffs for every repo
md pull --all # pull changes from every repoFork workflow
Fork a running agent's container to try a different approach without losing progress:
# Agent is working in md-myrepo-feature-x
# You want to try a different approach:
md fork # creates md-myrepo-feature-x-0
ssh md-myrepo-feature-x-0
# Work on the fork. If it works out:
md pull # pull changes back from the fork
md purge # clean up the fork
# If the original approach was better:
md purge md-myrepo-feature-x-0 # discard the forkThe fork preserves the entire filesystem (installed packages, build artifacts, agent history) so you don't lose context. Each repo gets a unique divergent branch.
CI / one-shot runs
md run starts a container, runs a command, and cleans up. Ideal for CI:
# Run tests in a clean environment
md run -- npm test
md run -- cargo test
md run -- go test ./...
# Run a linter on a specific branch without checking out
md run -b feature-x -- golangci-lint run ./...
# Custom image + specific version
md run --image ghcr.io/caic-xyz/md-user:2026-05-09 -- npm ci && npm test
# Pass through GitHub token for private repos
md run --github -- npm installAI commit messages
md pull can generate commit messages using an LLM. It analyzes the diff and recent commit history to produce a conventional commit message.
Setup
Set the provider and model via environment variables; the full list of acceptable ASK_PROVIDER values is from genai:
export ASK_PROVIDER=deepseek
export ASK_MODEL=deepseek-v4-flsahIf not set, md auto-discovers available providers on your system. It prefers CLI-based providers in this order: pi, codex, opencode, claudecode, then any others alphabetically. The model defaults to a cheap/fast option.
For large diffs, md uses a progressive reduction pipeline to fit within the LLM's context window. See Design for details.
Build
md build-image
Builds the md-root-local and md-user-local Docker images from the embedded source. Use this when:
- You're contributing changes to the container Dockerfiles or setup scripts
- You want to test a change to the container's preinstalled tools
- You want fully local images without pulling from
ghcr.io
md build-imageThe first build takes several minutes (two full Docker builds: root image, then user image on top). Subsequent builds are faster thanks to layer caching.
A GITHUB_TOKEN is recommended to avoid rate limits when installing tools like Neovim and rust-analyzer:
export GITHUB_TOKEN=ghp_...
md build-imageOnce built, use the local images:
md start -image md-user-localmd prune
Removes unused md-specialized-* and md-fork-* images no longer referenced by any container. Also cleans the Docker build cache.
Cache flags
| Flag | Description |
|---|---|
--no-cache <name> | Exclude a specific default cache (repeatable) |
--no-caches | Disable all default caches |
--cache <name> | Add a well-known cache (use with --no-caches) or custom host:container[:ro] |
Caches are baked into the image at build time. Only caches whose host directories exist are included; missing directories are silently skipped. The image rebuilds only when the active cache set changes.
Well-known caches
| Cache name | Host path | Description |
|---|---|---|
bun | ~/.bun/install/cache | Bun package manager |
cargo | ~/.cargo/registry, ~/.cargo/git | Rust cargo registry and git checkouts |
go-mod | ~/go/pkg/mod | Go module cache |
gradle | ~/.gradle/caches, ~/.gradle/wrapper/dists | Gradle caches and wrapper |
maven | ~/.m2/repository | Maven repository |
npm | ~/.npm | npm cache |
pip | ~/.cache/pip | Python pip cache |
pnpm | ~/.local/share/pnpm/store | pnpm store |
uv | ~/.cache/uv | UV Python package manager |
android-keys | ~/.android (shallow) | Android debug keystore and ADB keys |
Remote GUI (VNC)
Enable at startup, then open:
md start -display
md vncThe DISPLAY environment variable is automatically set in SSH sessions, so X11 apps launched from SSH appear on the VNC desktop.
Recommended VNC clients:
- Windows: RealVNC Viewer, TightVNC, UltraVNC
- macOS: Built-in VNC or RealVNC Viewer
- Linux:
tigervnc-viewer,vinagre, orvncviewer