Install
$ agentstack add mcp-jkhas8-linux-coworker-ui ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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 Used
- ✓ Environment & secrets No
- ✓ 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
linux-coworker-ui
[](../../actions/workflows/ci.yml) [](LICENSE) [](#)
A Linux desktop GUI for the Claude Code agent — a Linux counterpart to Anthropic's macOS/Windows-only Claude Cowork.
The app wraps claude (Claude Code CLI) as the agent loop and adds a Linux desktop control layer (screenshot, click, type, launch apps) via a bundled MCP server.
┌─────────────────────────────────────────────────────────┐
│ Tauri shell ◀──── stream-json ────▶ claude (CLI) │
│ (Rust + Solid) │ │
│ ▼ │
│ mcp-linux-control │
│ (screenshot, xdotool, │
│ wmctrl, launch) │
└─────────────────────────────────────────────────────────┘
Prerequisites
System packages (Ubuntu 24.04 / Debian):
sudo apt install -y \
libwebkit2gtk-4.1-dev \
librsvg2-dev \
libdbus-1-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
libsoup-3.0-dev \
pkg-config \
build-essential \
xdotool \
wmctrl \
maim
Toolchain:
- Rust >= 1.93
- Node >= 20 (or Bun)
claudeCLI on$PATH(Claude Code 2.x)
Build
# 1. Build the MCP server
cargo build -p mcp-linux-control
# 2. Install frontend deps
bun install
# 3. Run the app (dev mode)
bun run tauri dev
Set MCP_LINUX_CONTROL_BIN=/path/to/mcp-linux-control if the auto-locator can't find the binary (default is target/debug/mcp-linux-control relative to the app binary).
Layout
linux-coworker-ui/
├── Cargo.toml workspace root
├── package.json frontend (Vite + Solid + TS)
├── src/ Solid frontend
│ ├── App.tsx chat UI shell
│ ├── stream.ts parse stream-json -> display blocks
│ └── types.ts
├── src-tauri/ Tauri app
│ ├── Cargo.toml
│ └── src/
│ ├── lib.rs `run()` + Tauri commands
│ ├── agent.rs spawn/supervise `claude` subprocess
│ └── mcp_config.rs write `.mcp.json` for `--mcp-config`
└── crates/
└── mcp-linux-control/ MCP server: screenshot/xdotool/wmctrl
└── src/main.rs
How it works
- The Tauri backend spawns `claude --print --input-format stream-json
--output-format stream-json --mcp-config .json --permission-mode bypassPermissions`.
- Each user message is written to claude's stdin as one NDJSON line of the
form {"type":"user","message":{...}}.
- claude streams NDJSON events back on stdout (assistant turns, tool calls,
tool results). The backend forwards every line to the frontend via the claude://event Tauri event.
- The frontend parses each event into display blocks (text bubble, tool-call
card, tool-result card) and renders them.
- When claude calls one of our MCP tools (e.g.
mcp__linux_control__screenshot),
the Claude Code CLI launches the mcp-linux-control binary as a stdio subprocess and routes the call there.
MVP tools exposed by mcp-linux-control
| Tool | Backed by | Notes | |----------------|---------------------|------------------------------------------------| | screenshot | maim / scrot | Returns base64 PNG image content to the model. | | xdo_click | xdotool click | Optional x/y, optional double. | | xdo_move | xdotool mousemove | | | xdo_type | xdotool type | Configurable per-char delay. | | xdo_key | xdotool key | Accepts chords like ctrl+s. | | launch_app | spawn() | Detached, returns immediately. | | list_windows | wmctrl -l | | | focus_window | wmctrl -a | Substring match on title. |
File operations (Read/Write/Edit), shell (Bash), search (Grep/Glob) come for free from Claude Code's built-in tools.
Known limitations / next steps
- Permission flow is YOLO right now. Backend defaults to
--permission-mode bypassPermissions. The "approve destructive only" UX needs a --permission-prompt-tool exposed by our MCP server that blocks on a Tauri-side approval dialog. See agent.rs -> permission_mode.
- X11 only. Screenshots, xdotool, and wmctrl rely on X11. Wayland support
would swap in grim/slurp/ydotool and a portal-based screenshot path.
- No session persistence. Conversations are in-memory and reset on app
close. Add --resume plumbing.
- No streaming partials. We render finalized assistant messages only.
Toggle --include-partial-messages and handle stream_event in src/stream.ts to get token-level streaming.
Contributing
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for architecture, protocols, how to add a new MCP tool, the permission model roadmap, and the testing plan.
License
MIT.
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: jkhas8
- Source: jkhas8/linux-coworker-ui
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.