Install
$ agentstack add mcp-liruns-marudesk ✓ 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 Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ 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
Mission control for AI development — where the agent proves it fixed your running app, not just your source. A desktop app built around a Task graph: each node is an intent you hand the agent, and a real browser, code editor, terminal, and Source Control are transient instruments the task summons on demand. A task isn't done because the agent says so — it's done when the live app proves its acceptance criteria over the Chrome DevTools Protocol.
> Screenshots are regenerated from the live app with npm run screens (in marudesk/, output under marudesk/.screens/); some images below predate the Mission Control redesign and are being refreshed.
Maru is a desktop application (Electron) for building and debugging web software. Unlike source-only AI coding tools, it embeds a real Chromium browser and speaks the Chrome DevTools Protocol (CDP) in-process, so the agent can read the live DOM, console, and network of the app you are running and act on that runtime evidence — for example, turning a console error into a source fix and confirming the fix by reloading the page.
Mission Control is the only home. Instead of juggling tabs and panes, you work a Task graph: each node is an intent the agent works on. Selecting a task opens its own dock — a per-task chat plus the task inspector — so you talk to the task, not a global bot. When a task needs a tool, it summons a transient instrument (browser, Monaco editor, terminal, Source Control, Settings) into the full area, then dismisses it with "← Graph". A ⌘K command palette is the universal entry point for opening instruments and running actions; a slim Flight bar shows the goal and running/passed/failed counts; the Evidence strip turns acceptance criteria into real pass/fail verdicts proven via CDP (0/2 → 2/2), and a Flight Log keeps the cross-task transcript.
> Status: in active development — built as a daily driver and portfolio project. See [Project status](#project-status).
Download
Grab the installer for your platform from the latest release →.
| Platform | Installer | Notes | |---|---|---| | Windows | marudesk-Setup-0.2.0.exe | Installs and auto-updates in place. | | macOS · Apple Silicon | marudesk-0.2.0-arm64.dmg | Unsigned — on first launch, right-click → Open to pass Gatekeeper. | | macOS · Intel | marudesk-0.2.0.dmg | Unsigned — on first launch, right-click → Open. | | Linux | .AppImage · .deb | chmod +x the AppImage and run it, or sudo dpkg -i the .deb. |
Prefer to build from source? See [Getting started](#getting-started).
The idea
Most AI coding assistants only see your source files. Maru co-locates the surfaces a developer actually moves between — browser, DevTools, editor, terminal, and the agent — inside one process, and connects the seams between them:
- A console error in the embedded DevTools carries a one-click Fix this: the agent maps the stack frame back to your source file, edits it, reloads the page, and verifies the error is gone (
get_console_errors → edit → reload_and_verify). - The agent can click, type, and scroll the live page, read network requests, and evaluate expressions — the same things you would do by hand in DevTools.
- Because the agent shares the workspace, terminals, and the open instruments through an in-process context server, it works from what is actually on screen instead of guessing.
Screenshots
The per-task chat — model bar, reasoning-effort dial, and the agent composer, each task owning its own conversation in the dock.
A task summons an instrument into the full area — a real browser, editor, terminal, or Source Control — with "← Graph" to return home.
Features
Agentic AI chat
- Many providers, one app. Anthropic, OpenAI, Google (Gemini), xAI (Grok), Ollama (local), and any custom OpenAI-compatible endpoint (OpenRouter, LM Studio, vLLM, and similar).
- Bring your own subscription. Connect by API key, or sign in with an OAuth subscription. Claude (Pro/Max) and xAI work today; ChatGPT and Gemini subscription backends are experimental.
- Provider fallback chain. When the active model is rate-limited or errors (429 / 5xx), the agent automatically retries on the next connected model you have ranked, instead of failing the turn.
- Streaming, reasoning, and control. Live token streaming, collapsible reasoning blocks, a per-provider reasoning-effort dial, and approval modes (plan / read-only / ask / auto).
- Composer that keeps up. Slash commands (
/init,/review,/diff,/context,/compact,/copy, …),@-mention workspace files, paste or drop images for vision models, recall past prompts with the arrow keys, and queue a message while a turn is still running. - Plan mode. Have the agent research read-only and propose a step-by-step plan before you let it edit.
- Compaction and verify.
/compactsummarizes a long conversation to reclaim context; an optional post-edit verify command (e.g.npm run typecheck) runs after the agent edits and folds the PASS/FAIL back into the chat. - Approvals that remember. Approve a gated tool once, or "Allow always" to stop re-prompting for it for the rest of the conversation.
- Sessions and memory. Resume past conversations from a history rail; keep durable cross-session notes.
- Chat from the terminal. An OpenCode-style CLI (
npm run chatinmarudesk/) drives the same agent over a zero-config loopback bridge — a bordered header card, a full-width status bar (state · workspace · mode on the left, model · context · tokens on the right), streamed markdown and reasoning, a slash menu, model/session pickers,/agentsand/skillscatalogs, inline approvals, Esc to interrupt. In the app it opens as an "AI Chat (CLI)" instrument from the ⌘K palette, and the app installs amarudeskcommand on PATH so any terminal can open it while the app runs (Settings → Terminal shows/repairs it). - Agent roles + skills. Delegated subtasks run as named roles: built-in agents (
explore,researcher,reviewer,planner,general) plus your own, defined as markdown files under.marudesk/agents/(project) or the app'sagents/folder (user) — frontmatter picks the model (fast/smarttier or a concreteprovider/model) and a tool subset, the body is the role's instructions. The subagent's model resolves automatically against the providers you actually connected, and fails over mid-run on rate limits the same way the main loop does. Reusable instruction skills (SKILL.mdplaybooks) load on demand via theskilltool.
Runtime-aware tools (the differentiator)
- Read console errors with source mapping back to workspace files.
- Query the DOM, read network requests and response bodies, evaluate JavaScript.
- Drive the live page: click, fill, press keys, scroll.
- A reload-and-verify loop that checks whether a change actually removed the error.
- See the page: a
screenshottool hands the live viewport to vision-capable models, so the agent can verify a change looks right, not just that the error is gone;get_web_vitalsgrounds performance claims in LCP/CLS/INP/TTFB. - An exception trap (
arm_exception_capture→ reproduce →read_exception_capture) that snapshots call frames and local variable values at the moment an uncaught exception fires. - Full-stack triage:
triage_network_failurecorrelates a failed request with backend dev-server output across multi-root (FE+BE) workspaces. - One-click Fix this on console errors — and on terminal errors: build/test failures detected in integrated terminal scrollback get a badge and the same one-click handoff to the agent.
A real browser, not a preview
The browser is a full-area instrument a task summons — a real Chromium WebContentsView, not a screenshot preview — with favicons, history, bookmarks (star toggle + panel), address-bar suggestions (bookmarks and frecency-ranked history with a search-the-web row), downloads, find-in-page, zoom, configurable search engines, crash recovery, and per-site partitioning. Because it is a live page, the runtime-aware tools above act on exactly what is on screen.
Custom DevTools (CDP)
A React-built DevTools dock with Console, Network, Elements, Application, and Rendering panels plus a REPL — dockable or popped out into its own window. Network requests open into full detail tabs (Headers / Payload / Response / Timing / Initiator) with parsed payloads and phase timing bars; WebSocket/SSE connections get a live Frames viewer; the Application panel can edit local/session storage and delete cookies; Elements adds a Computed pane with the box-model diagram. Chromium's own DevTools remain available as an escape hatch.
Editor, terminal, explorer
A Monaco code editor with TypeScript/JavaScript IntelliSense (completions, hover, go-to-definition across open files), format on save, a git diff gutter, and inline current-line blame; a real shell terminal (node-pty) with find, copy/paste, and error detection with one-click Fix this; a file explorer; and workspace-scoped file tools the agent can use — guarded by configurable never-edit globs. The Source Control panel covers stage/commit/branch/sync plus stashes (push/apply/pop/drop) and merge-conflict resolution (per-file accept ours/theirs, operation banner with Continue/Abort, and accept-current/incoming/both codelenses on conflict markers in the editor). Workspace content search (Ctrl/Cmd+Shift+F, ripgrep with a Node fallback) adds case/word/regex toggles, include/exclude glob filters, highlighted match previews, and click-to-jump to the exact line and column.
Context MCP and external MCP
A built-in, in-process MCP server exposes tabs, the active page, terminals, editor buffers (including unsaved edits), the explorer tree, sessions, and memory to the agent. External MCP servers can also be connected — local over stdio or remote over HTTP (Streamable HTTP, with an SSE fallback) — configured Claude-Desktop-style in mcp-servers.json. Each external tool is routed through the same approval / read-only mediation as the built-in ones; a server can be marked trust, hidden per tool with disabledTools, auto-approved per tool with autoApproveTools, or forced back to per-call confirmation with confirmTools. Config reads report diagnostics and fail closed on malformed config, and external tool names/metadata/schema are scrubbed and bounded before model exposure. Manage them in Settings → MCP Servers.
Plugins
Extend the agent with your own JavaScript. A plugin is a folder with a manifest.json and an index.js exporting activate(ctx); it can contribute agent tools and slash commands. Plugins run in an isolated worker (Electron utilityProcess with the Node Permission Model + a module sandbox), never in the main process, and reach the filesystem/network only through a capability-gated bridge the user approves per plugin (fs:read, fs:write, net). Contributed tools flow through the same approval / read-only mediation as the built-in ones, and a plugin's file writes show up in the chat diff/revert history. Manage them in Settings → Plugins; see [marudesk/docs/plugin-runtime-design.md](marudesk/docs/plugin-runtime-design.md). Plugin folders are scanned from /plugins/ (user) and /.marudesk/plugins/ (project); a runnable example lives in [marudesk/examples/plugins/hello-world](marudesk/examples/plugins/hello-world).
Writing a plugin
A plugin is a folder with a manifest.json (id, entry, declared permissions) and an index.js exporting activate(ctx), where ctx is the capability bridge — registerTool / registerSlashCommand plus permission-gated fs, http, exec, setStatus, and log. The author guide documents the full ctx surface, the permission model, and how to install from the Plugins panel: [marudesk/examples/plugins/README.md](marudesk/examples/plugins/README.md). For editor autocomplete and typecheck, annotate your module with the author types in [marudesk/shared/plugin.ts](marudesk/shared/plugin.ts) (PluginModule, PluginContext); start from the [hello-world](marudesk/examples/plugins/hello-world) example.
Repository layout
Maru lives in a single active package, marudesk/; a former Capacitor mobile client is archived.
| Path | Role | |---|---| | marudesk/ | Electron desktop app — browser stage, DevTools, agent loop, editor/terminal, workspace integration, packaging. Owns the model/tool/workspace loop. | | mobile/ (archived) | Capacitor thin client — removed from the active workspace; preserved on the archive/mobile branch and archive/mobile-v0.8.0 tag. | | reference/ (not built) | Read-only vendored source snapshots kept for design/feature reference only (e.g. reference/pane/). Outside every build/lint/test. See [reference/README.md](reference/README.md) and [reference/pane-porting-map.md](reference/pane-porting-map.md). |
Inside marudesk/:
electron/— main process:browser/*(tabs, navigation, downloads, CDP runtime capture),agent/*(session loop, tools, MCP, context sources, provider auth), plus settings, secrets, and the loopback CLI bridge (cli-bridge/).src/— React renderer, organized into feature slices (features/browser,devtools,editor,agent,settings,terminal, and others).shared/— transport-safe typed contracts used across main, renderer, and tests.e2e/— Playwright end-to-end tests.docs/— design and architecture notes.DESIGN.md— design-system rules.
Tech stack
- Electron 42 (Chromium 148), React 19, TypeScript (strict project builds)
- Vite 8 build, Zustand state, Tailwind design tokens
- Monaco editor, xterm.js + node-pty terminal
- Vercel AI SDK (
@ai-sdk/*) for model integration, Model Context Protocol SDK for tools - Playwright for Electron/runtime end-to-end tests
Getting started
Prerequisites: Node.js 20 or newer and npm. There is no root package; install per package.
# Desktop app
cd marudesk
npm install
npm run dev # starts the Vite renderer + Electron shell
Configure a provider
Open Settings → AI Providers and either paste an API key or sign in with a subscription (OAuth). Then choose a model from the command-palette model picker. To enable automatic failover, turn on Settings → Agent → Model fallback and rank your models.
Build a desktop package
cd marudesk
npm run build # type-check + bundle
npm run package:win # or: npm run package:mac / npm run package:linux
Cut a release (CI)
Releases are built and published by the Release GitHub Actions workflow (.github/workflows/release.yml). Pushing a v* tag builds marudesk on native runners — macOS arm64 and x64 cross-built on Apple Silicon (macos-14), Windows x64 (windows-latest), and Linux x64 (ubuntu-latest) — and uploads the installers (dmg for macOS, NSIS exe for Windows, AppImage + deb for Linux) to the GitHub release that matches marudesk/package.json version:
# bump marudesk/package.json version first, commit, then:
git tag v0.2.0
git push origin v0.2.0
A manual workflow_dispatch run builds the same matrix without publishing, so yo
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Liruns
- Source: Liruns/marudesk
- 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.