by johnzfitch
Run Claude Desktop’s Cowork mode natively on Linux — no macOS or VM required
# Add to your Claude Code skills
git clone https://github.com/johnzfitch/claude-cowork-linuxGuides for using ai agents skills like claude-cowork-linux.
Quick Start · How It Works · Manual Setup · Troubleshooting
Claude Cowork is a special Claude Desktop build that works inside a folder you point it at—it reads, writes, and organizes files there while it runs a plan. Cowork is currently a macOS-only preview backed by a sandboxed Linux VM; this repo reverse-engineers and stubs the macOS-native pieces so Cowork can run directly on Linux (x86_64)—no VM and no macOS required. The stub translates VM paths to host paths so Cowork points at the right files on Linux.
How it works:
| Step | Description |
|:-----|:------------|
|
Stubbing | Replace macOS-only native modules (@ant/claude-swift, @ant/claude-native) with JavaScript |
|
Direct Execution | Run the Claude Code binary directly (no VM needed—we're already on Linux!) |
|
Path Translation | Convert VM paths to host paths transparently |
|
Platform Spoofing | Send macOS headers so the server enables the feature |
$WAYLAND_DISPLAY / $XDG_SESSION_TYPE (Ozone backend).| Distro | Desktop | Status | Notes |
|:-------|:--------|:-------|:------|
| Arch Linux | Hyprland (Wayland) | Tested | Primary dev environment |
| Arch Linux | KDE Plasma (Wayland) | Expected | KDE Wallet exposed via SecretService D-Bus |
| Arch Linux | GNOME (Wayland) | Expected | Global shortcuts require manual DE config (GNOME lacks portal support) |
| Ubuntu 22.04+ | GNOME / X11 | Expected | gnome-keyring provides SecretService |
| Fedora 39+ | GNOME / KDE | Expected | May need p7zip-plugins for DMG extraction |
| Debian 12+ | Any | Expected | p7zip-full in apt |
| NixOS | Any | Untested | Electron + bwrap sandboxing may need extra config |
| openSUSE | Any | Tested | Uses 7zip package (not p7zip); nodejs-default for Node.js |
Known caveats:
GlobalShortcuts portal (GNOME) won't have global hotkey support -- set a custom shortcut in your DE settings instead.gnome-keyring or another SecretService provider isn't running, the launcher falls back to --password-store=basic (credentials stored on disk, not in a keyring)./sessions root symlink requires sudo once during install. If your distro restricts root symlinks differently, point it manually: sudo ln -s "$HOME/.config/Claude/local-agent-mode-sessions/sessions" /sessions.Run ./install.sh --doctor (or claude-desktop --doctor) after install to validate your environment.
npm install -g @electron/asar)7zip instead)enable-cowork.py patching — the installer uses Node.js to download DMGs)--password-store=basic.git clone https://github.com/johnzfitch/claude-cowork-linux.git
cd claude-cowork-linux
./install.sh # auto-downloads the latest DMG via Node.js
claude-desktop
yay -S claude-cowork-linux # auto-downloads the latest DMG
bash <(curl -fsSL https://raw.githubusercontent.com/johnzfitch/claude-cowork-linux/master/install.sh)
The installer automatically downloads the latest Claude Desktop DMG using Node.js (scripts/fetch-dmg.js). You can also provide a DMG manually:
./install.sh ~/Downloads/Claude-*.dmg
# or
CLAUDE_DMG=~/Downloads/Claude-1.1.4010.dmg ./install.sh
[!IMPORTANT] This repo does not include Anthropic's proprietary code. The installer downloads it directly from Anthropic's CDN.
┌─────────────────────────────────────────────────────────────────┐
│ Claude Desktop (Electron) │
├─────────────────────────────────────────────────────────────────┤
│ @ant/claude-swift (STUBBED) │
│ ├── vm.setEventCallbacks() → Register process event handlers │
│ ├── vm.startVM() → No-op (we're already on Linux) │
│ ├── vm.spawn() → Delegates to session orchestrator │
│ ├── vm.kill() → Kills spawned processes │
│ └── vm.writeStdin() → Writes to process stdin │
├─────────────────────────────────────────────────────────────────┤
│ @ant/claude-native (STUBBED) │
│ ├── AuthRequest → Opens system browser (xdg-open) │
│ └── Platform helpers → Minimal compatibility shims │
├─────────────────────────────────────────────────────────────────┤
│ stubs/cowork/ — Orchestration Layer (15 modules) │
│ ├── session_orchestrator.js → Coordinates spawn lifecycle │
│ ├── asar_adapter.js → Asar IPC API compatibility │
│ ├── process_manager.js → Process lifecycle & I/O │
│ ├── resume_coordinator.js → Session resume logic │
│ ├── sessions_api.js → Session CRUD operations │
│ ├── session_store.js → In-memory session state │
│ ├── transcript_store.js → Transcript persistence │
│ ├── file_registry.js → Working directory tracking │
│ ├── file_watch_manager.js → File change detection │
│ ├── stream_protocol.js → JSON-RPC stream parsing │
│ ├── credential_classifier.js → Token leak prevention │
│ ├── eipc_channel.js → EIPC message protocol │
│ ├── ipc_tap.js → IPC channel discovery │
│ ├── dirs.js → XDG directory resolution │
│ └── file_identity.js → Path normalization │
├─────────────────────────────────────────────────────────────────┤
│ Claude Code Binary │
│ └── Resolved from ~/.local/bin, mise/asdf shims, PATH, etc. │
│ (launch.sh replaces macOS Mach-O binary with Linux symlink)│
└─────────────────────────────────────────────────────────────────┘
The stub translates VM paths to host paths:
| VM Path | Host Path |
|:--------|:----------|
| /usr/local/bin/claude or claude | Resolved via ~/.local/bin/claude, ~/.config/Claude/claude-code-vm/{version}/claude, or PATH |
| /sessions/... | ~/.config/Claude/local-agent-mode-sessions/sessions/... |
When you select a folder in Cowork, the stub creates symlinks to make it accessible at the expected VM path:
~/.config/Claude/local-agent-mode-sessions/sessions/<session-name>/mnt/
├── <folder> → /home/user/path/to/selected/folder (symlink)
├── .claude → ~/.config/Claude/local-agent-mode-sessions/.../session/.claude (symlink)
├── .skills → ~/.config/Claude/local-agent-mode-sessions/skills-plugin/... (symlink)
└── uploads/ (directory for file uploads)
The additionalMounts parameter from Claude Desktop provides the mapping between mount names and host paths.
[!NOTE] The Claude Code binary expects
/sessionsto exist.install.shcreates/sessionsas a symlink into~/.config/Claude/local-agent-mode-sessions/sessions(requiressudoonce) so you don't need a world-writable root directory.
The app sends these headers to Anthropic's servers:
'Anthropic-Client-OS-Platform': 'darwin'
'Anthropic-Client-OS-Version': '14.0'
This makes the server think we're on macOS 14 (Sonoma), enabling Cowork features.
The platform-gate function (minified name changes per build — xPt() in v1.1.3963, wj() in older builds) checks if Cowork is supported. enable-cowork.py finds it automatically and replaces it to unconditionally return `
No comments yet. Be the first to share your thoughts!