Run Claude Code in Docker with full feature parity.
Sandboxed sessions with clipboard, browser control, MCP servers, parallel sessions, and sound notifications — all bridged seamlessly to your Mac.
Quick Start • Usage • Configuration • How It Works • Changelog
Running Claude Code with full access to your Mac is risky. Claude's auto mode guards it with a permission classifier — a soft boundary that costs a model call per risky action. clauded gives you a hard one: a Docker sandbox. Skip permission prompts safely and cheaply, while clipboard, sound, Claude in Chrome, git, and MCP servers all bridge to your Mac.
- Parallel sessions — run as many as you want across projects at once
- Resume by name or ID —
clauded -r my-sessionpicks up where you left off - Claude in Chrome — drive your Mac's Chrome from the container, built in, no setup
- Mac bridges —
/copyand copy-on-select, clicked links, and sound notifications all reach your Mac - Voice input — Claude Code's voice mode works in the container; your Mac's mic is bridged in on-demand and gated by a per-session approval prompt
- MCP servers — stdio and HTTP MCPs work inside Docker; Chromium bundled for Puppeteer/Playwright
- Auto host networking — when enabled in Docker Desktop, container ports are reachable on your Mac without
--port - Works behind VPNs — auto-detects broken IPv6 and pins Anthropic endpoints to IPv4 so sessions keep connecting
- Versioning — auto-updates Claude Code on startup; pin an exact version with
--versionor freeze updates with--no-update - Git and SSH — SSH keys mounted, GitHub auth forwarded via
GH_TOKEN - Configurable — project directory, extra mounts, SSH/git overrides in
~/.clauded/config
- macOS (Apple Silicon or Intel)
- Docker Desktop (must be running)
- Xcode Command Line Tools — provides
git,curl, andpython3(xcode-select --install) - A Claude account (Pro, Max, Teams, or Enterprise)
sox— only for voice input (brew install sox)
curl -fsSL https://raw.githubusercontent.com/nj-io/clauded/main/install.sh | bashThis clones the repo, builds the Docker image, symlinks clauded and play-sound to your PATH, and starts the clipboard/sound host services.
Manual installation
git clone https://github.com/nj-io/clauded.git ~/.clauded
cd ~/.clauded && ./clauded build
sudo ln -sf ~/.clauded/clauded /usr/local/bin/clauded
sudo ln -sf ~/.clauded/play-sound /usr/local/bin/play-soundOn first run, clauded will:
- Build the Docker image with Chromium, Node.js, Python, and Claude Code
- Start the clipboard and sound servers on your Mac
- Migrate
~/.claude.jsoninto~/.claude/(one-time symlink for Docker compatibility) - Open a login URL in your browser — authenticate with your Claude account
Optional: auto-start host services on login so they're always ready:
clauded sounds install
clauded clipboard installclauded # Start in current directory
clauded ~/dev/my-project # Start in a specific directory
clauded -r <id-or-name> # Resume a session
clauded --continue # Resume last session
clauded --fork-session <id-or-name> # Resume a copy, leaving the original untouched
clauded --worktree # Start in a git worktree
clauded --worktree my-feature # Named worktree
clauded --no-update # Start without checking for updates
clauded --version 2.1.150 # Pin to a specific Claude Code versionClaude in Chrome works out of the box. Install the Claude in Chrome extension and Claude can navigate, click, screenshot, and read the console in your Mac's Chrome from inside the container — no flag or setup required. The mcp__claude-in-chrome__* tools are available automatically.
Claude Code's voice mode works inside the container. A container-local PulseAudio exposes a source that Claude Code records from, and your Mac's microphone is streamed into it while you're recording. It's on by default and needs sox on your Mac (brew install sox).
The first time each session records, macOS asks you to approve microphone access for it — denied by default. After you approve, it won't ask again for that session for about an hour (set MIC_CONSENT="always" in ~/.clauded/config to be asked before every recording). macOS shows its microphone indicator whenever a capture is running, each capture is logged to ~/.clauded/mic.log, and access requires the per-machine token in ~/.clauded/bridge-token that clauded gives its containers.
Turn it off with VOICE="false" in ~/.clauded/config, or --no-voice for one session. Manage the host bridge with clauded voice start|stop|status.
clauded --port 4000 # Expose port 4000 to Mac
clauded --port 4000-4010 # Expose port range
clauded --ro ~/specs # Mount extra directory read-only
clauded --mount ~/data:/data # Mount extra directory read-writeclauded --agent my-agent "prompt" # Run a Claude agent
clauded run "prompt" # Non-interactive queryclauded list # See running sessions
clauded stop # Stop most recent session
clauded stop-all # Stop all sessions
clauded shell # Bash into most recent sessionclauded sounds start|stop|restart|status|install|uninstall # Sound notifications (port 21563)
clauded clipboard start|stop|restart|status|install|uninstall # Clipboard bridge (port 21564)clauded build # Build/rebuild (auto-detects updates)
clauded firewall # Lock down outbound network access
clauded setup # Full setup wizardUser settings live in ~/.clauded/config (auto-created on first run):
# Project directory mounted into containers
DEV_DIR="$HOME/dev"
# Extra directories to mount read-write (space-separated)
EXTRA_MOUNTS="$HOME/.my-tool $HOME/.local/share/my-mcp"
# Custom SSH config for Docker (leave empty to use ~/.ssh/config)
SSH_CONFIG="$SCRIPT_DIR/ssh-config-docker"
# Custom gitconfig for Docker (leave empty to use ~/.gitconfig)
GITCONFIG="$SCRIPT_DIR/gitconfig-docker"
# Skip the auto-update check on startup (same as --no-update)
# SKIP_UPDATE="true"
# Pin Claude Code to a specific version (same as --version)
# CLAUDE_PIN_VERSION="2.1.150"
# Force Anthropic endpoints to IPv4 under host networking (auto | true | false)
# FORCE_IPV4="auto"All SSH keys from ~/.ssh/ are mounted read-only. If your ~/.ssh/config or ~/.gitconfig have Mac-specific entries (Keychain credential helpers, etc.), create Docker-specific overrides:
cp ssh-config-docker.example ssh-config-docker # Edit with your key
cp gitconfig-docker.example gitconfig-docker # Edit with your emailMCP servers configured in ~/.claude.json work automatically if their dependencies are available in the container. The image includes:
| Dependency | For |
|---|---|
| Chromium (headless) | Puppeteer and Playwright MCPs |
| Node.js 22 + npm | JavaScript-based MCPs |
| Python 3 | Python-based MCPs |
HTTP/SSE MCPs (Asana, GitHub, Linear, Slack, Supabase, etc.) work out of the box.
Claude in Chrome is built in and needs no bridge — just install the extension (see Chrome Browser Control).
To mount additional MCP source directories, add them to EXTRA_MOUNTS in your config.
clauded runs Claude Code inside Docker while bridging Mac features via lightweight HTTP servers on the host:
Sessions share ~/.claude/ via bind mount. Each container gets isolated /tmp. The persistent Docker home at ~/.clauded/home survives container restarts.
Multiple sessions run simultaneously with isolated containers but shared project files and Claude settings:
# Terminal 1 # Terminal 2 # Terminal 3
clauded ~/dev/backend clauded ~/dev/frontend clauded -r my-sessionA memory warning appears when total container usage exceeds 3GB.
Optionally restrict outbound traffic to only essential services:
clauded firewallWhitelisted: Anthropic API, GitHub, npm, PyPI, Claude-in-Chrome relay.
Some VPNs advertise IPv6 but can't route it. With host networking enabled, that breaks the container's connection to Anthropic — you'd see 401 Invalid authentication credentials or a certificate error.
clauded handles this automatically: it checks whether Anthropic is reachable over IPv6 and pins the endpoints to IPv4 only if it isn't.
To override the auto-detection:
clauded --force-ipv4 # always pin to IPv4
clauded --no-force-ipv4 # never pinOr set it permanently in ~/.clauded/config:
FORCE_IPV4="auto" # auto (default) | true (always pin) | false (never)Found a bug or have a feature request? Open an issue.
Pull requests welcome. For larger changes, open an issue first to discuss.

