agent/desktop_
A desktop client for every LLM, built for agents. Plan mode, MCP, git panel, scheduler, voice, Jupyter — on your filesystem, or headless in a Docker sandbox.
the app / a real desktop window, not a terminal
features / what's in the box
claude agent sdk, wired to your filesystem
Built on the Claude Agent SDK. Plan mode renders proposed plans as markdown and requires explicit approval — rejection passes feedback back as context. AI settings cascade from Global → Folder → Conversation. Native SDK session resume sends only the last message, falls back on corruption.
git panel
Interactive Git visualizer in the right sidebar. Auto-refreshes after any Bash tool result that touches the repo. Hardened runGit spawn wrapper with timeout and env sanitization.
scheduled tasks
Recurring agent runs on a cron interval, linkable to a specific conversation. Prompts tokenize {name} and {name:arg} variables — built-ins plus custom .ts resolvers with hot-reload. AI has its own MCP bridge to create, list, and cancel tasks.
viewers · jupyter · openscad · monaco
Open anything and the app knows what to do. .ipynb renders with a live kernel and inline cell editing (Colab-style). OpenSCAD files render as a 3D preview via Three.js with STL export. Monaco, HTML sandbox, Markdown, Mermaid, SVG, base64 images — all native.
knowledge base
Attach files and folders as context, per conversation. Read-only or read-write collection modes. 500KB cumulative size guard. @mention autocomplete with VS Code-style fuzzy matching.
mcp · stdio / http / sse
Model Context Protocol, first-class. Connect stdio, HTTP, or SSE servers. Enable per conversation. Granular Setting Sources — user / project / local. Scheduler ships as a built-in MCP server.
themes + font scale
Dark/light built-in + full CSS custom property editor. Import custom themes from ~/.agent-desktop/themes/. Folder heatmap auto-colors by conversation count. Per-folder color tinting via HSV picker. Font scale presets (80/100/125/150%) — everything including Monaco scales via rem.
message queue & fork
Queue messages while the AI is streaming — auto-send on response end, with drag-reorder, inline edit, delete. Right-click any message → Fork from here to branch the conversation. Slash commands: /compact, /clear. Multi-select with Ctrl/Shift-click.
quick chat · voice
Global overlay, one keybind from anywhere. Text or voice. Voice goes through local whisper.cpp — audio never leaves the machine. System volume auto-ducks during recording. Optional headless notifications-only mode.
text-to-speech
Responses read aloud via Piper (HTTP), edge-tts (CLI), or spd-say. Modes: full · summary · auto · off. Configurable summary model (Haiku / Sonnet / Opus). Per-stream audio ducking, per-conversation TTS settings via AI cascade.
four surfaces, one agent
desktop GUI
Electron 33 + React 18 + Zustand + Tailwind. Sidebar with folders, drag & drop, heatmap, multi-select. Plan approval, live tool timeline, git panel, TTS. System tray with theme-aware icons. Auto-update via electron-updater.
quick chat
Global overlay, one keybind away from anywhere. Text or voice — voice goes through local whisper.cpp, audio never leaves the machine. Resume-last-conversation or start fresh. Headless notifications-only mode available.
headless web server
Runs on any Node 18+ machine — no Electron needed. HTTPS with auto-generated self-signed certs (or plain HTTP if OpenSSL is missing). Raspberry Pi, WSL, any headless box. Short URLs for LAN.
discord bot
Forwards messages to any conversation. Slash commands: /set-conversation, /get-messages, /compact, /clear, more. Autocomplete for conversations and folders, user whitelist, auto-start on launch. Long responses auto-split across messages.
settings cascade / global → folder → conversation
the persona one system prompt, cascaded
Configure your agent's personality however you want — one editable system prompt. It inherits down the cascade, so you can change it on a single folder and that folder speaks differently.
You are terse. No filler, no "certainly", no "I'd be happy to". Never use "really", "just", "very", "basically". If a paragraph can be a sentence, it is. If the answer is "no", say "no" and stop.
bring your own frontend / the GUI is optional
The whole app is a headless daemon with a GUI bolted on — and you can unbolt it.
The shipped desktop window, the web view, the Discord bot — they are all clients of the same local server. Swap any of them. Write your own in whatever language you like. The core keeps your conversations, folders, macros, scheduler, permissions, and agent state.
- Typed REST + websockets — openapi spec included
- Plugin API — add a tool in ~40 lines of JS
- Theme tokens exported — match the official UI
- Same daemon, any client — desktop, neovim, a rotary phone
// your own UI. 18 lines. no SDK. const ad = new WebSocket("ws://localhost:3484/v1/stream"); ad.onopen = () => ad.send(JSON.stringify({ type: "message", folder: "/cad", // persona + model inherit text: "render that bracket again with a 4mm fillet", tools: ["scad.preview", "fs.write"] })); ad.onmessage = (e) => { const m = JSON.parse(e.data); if (m.type === "token") print(m.delta); if (m.type === "tool") renderCard(m); if (m.type === "done") finalize(m.cost); };
extend it, actually
hooks.json //intercept
Hooks fire at defined points of the Claude Agent SDK loop. UserPromptSubmit hook output is rendered as a markdown system-message block and persists across sessions. Per-backend hook isolation.
scheduler //cron
Cron-scheduled prompts with a real variable resolver. Variables resolve in parallel, per-variable timeout, passthrough-on-error. Tasks can target a specific conversation. The AI can create, list, and cancel schedules through a built-in MCP bridge.
two runners, one agent
The agent backend is swappable. Default to the official Claude Agent SDK, or switch to the experimental PI Coding Agent backend — per conversation, per folder, or globally.
A runner is the piece that drives the agent loop — it owns the tool calls, the context window, and the conversation with Claude. Agent-desktop ships with two backends. Same files, same hooks, same scheduler, same MCP servers — only the loop driving them changes.
claude login, or paste an ANTHROPIC_API_KEY with an optional custom base URL. This is the default runner — the app is designed around it.
claude login · or ANTHROPIC_API_KEYmcp servers / any tool, any protocol
themes / real CSS files, real editor
A theme is a CSS file with --color-* tokens.
The app ships with dark and light. Drop any additional .css into ~/.agent-desktop/themes/ — the app picks it up without a restart.
- CSS custom property editor — tweak tokens live from Settings, save as a new theme
- Auto day/night — switch between two configured themes at sunrise/sunset
- Folder heatmap + per-folder tinting — via
color-mix()on the active theme - Font scale — 80% / 100% / 125% / 150% via
--font-scale, Monaco included - Ask Claude to write one — give a vibe, get a CSS file
/* Agent Desktop — Default Dark Theme */ :root { --color-bg: #1a1a2e; --color-surface: #16213e; --color-deep: #0f3460; --color-primary: #e94560; --color-accent: #533483; --color-text: #eaeaea; --color-text-muted: #a0a0a0; --color-success: #00d26a; --color-warning: #ffc107; --color-error: #ff4757; --color-tool: #00bcd4; /* optional overrides */ --font-family: "JetBrains Mono", monospace; --font-scale: 1; }
~/.agent-desktop/themes/