mcp server
aegis-desktop
Extensible desktop-control MCP server for Linux-first agentic automation, with pluggable backends for windows, input, screenshots, OCR, app launching, and policy-aware computer interaction.
Set up
Runs on your computer. Pick your agent and operating system.
Before you start
- Node.js 20 or newer
{
"mcpServers": {
"aegis-desktop": {
"command": "npx",
"args": [
"-y",
"@mtstoica/aegis-desktop"
]
}
}
}same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12
Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs
README
synced Oct 23, 2026aegis-desktop
Extensible desktop-control MCP server for Linux-first agentic automation, with pluggable backends for windows, input, screenshots, OCR, app launching, and policy-aware computer interaction.
What It Is
aegis-desktop is a production-oriented Model Context Protocol server for structured desktop control on Linux systems. It is designed for agentic computer use where an LLM or automation agent needs to inspect desktop state, focus and manage windows, take screenshots, perform keyboard and mouse input, read or write the clipboard, and launch applications through explicit tools instead of opaque shell scripts.
The first implementation is intentionally Linux/X11-first. It uses mature command-line utilities such as wmctrl, xdotool, maim, import, gnome-screenshot, xclip, and tesseract where available, while exposing capability state and degrading honestly when a dependency is missing.
Why It Exists
Desktop automation often starts as brittle shell glue. That does not scale well for long-lived agent workflows because:
- state is hard to inspect before acting
- failures are poorly structured
- safety controls are bolted on late
- Linux/X11 and Wayland differences get hidden instead of modeled
- higher-level operations become difficult to reason about
aegis-desktop provides a clean foundation for a serious AEGIS desktop-control stack by separating transport, tools, policy, backend selection, and command execution.
Feature Overview
- stdio MCP server using the official MCP TypeScript SDK
- Linux Mint / Ubuntu-like focus with honest X11-first support
- real session-aware backend selection for X11 and Wayland surfaces
- modular backend interfaces for windows, screenshots, input, OCR, launching, clipboard, monitors, and accessibility
- explicit tool schemas with Zod validation
- structured tool errors and capability reporting
- policy layer with safe mode, launch allowlists, tool disable flags, screenshot throttling, env restrictions, and coordinate checks
- monitor enumeration and monitor-relative coordinate routing
- screenshot metadata extraction with explicit deterministic-region backend semantics
- optional accessibility-tree snapshot and semantic target search when AT-SPI support exists
- stateful low-level input primitives:
key_down,key_up,mouse_down,mouse_up,mouse_move - first-class low-level orchestration tool:
perform_input_sequence - artifact management for screenshots and inspection output
- strict TypeScript, ESLint, Prettier, tests, and smoke script
Architecture Overview
The server is split into distinct layers:
- transport layer: MCP server setup and stdio transport
- tool registration layer: tool catalog assembly and request handling
- backend abstraction layer: window, screenshot, input, OCR, launch, and clipboard interfaces
- policy layer: runtime checks and configurable restrictions
- utility layer: logging, command execution, path handling, matching
- config layer: defaults, env/config-file parsing, typed validation
- input sequence layer: validation, normalization, planning, and execution for complex low-level input actions
Relevant paths:
src/index.tssrc/server/src/backends/src/policy/src/config/src/tools/src/input-sequence/
See architecture.md for a deeper walkthrough.
Supported Environments
Current target:
- Linux Mint
- Ubuntu
- Debian-like desktop systems
- X11 desktop sessions
Current partial or unsupported areas:
- Wayland input and window control are still partial and backend-dependent
- active-window semantics on Wayland remain limited
- semantic target execution is not implemented yet; current support is inspection/search only
Backend Strategy
The implementation is intentionally pluggable. The v1 default backend strategy is:
- window management:
wmctrlplusxdotoolandxwininfoon X11; explicit unsupported backend on Wayland - input automation:
xdotoolon X11; partialydotoolsurface on Wayland - screenshots on X11:
maim, thenimport, thengnome-screenshot - screenshots on Wayland:
grim, thengnome-screenshot - monitor enumeration:
xrandron X11 andwlr-randron supported Wayland stacks - OCR:
tesseractwhen enabled and installed, otherwise graceful degradation - clipboard:
wl-copy/wl-pasteon Wayland when available, thenxclip, thenxsel - accessibility: Python
pyatspisnapshot/search when available - app launching:
spawnandxdg-open
Future Wayland and accessibility-driven backends can be added behind the same interfaces without rewriting tool handlers.
See backends.md.
Dependencies And Optional Binaries
Required runtime:
- Node.js 20+
Strongly recommended Linux binaries:
wmctrlxdotoolxwininfoxrandrmaimorimagemagick(import) orgnome-screenshotxcliporxselxdg-open
Optional:
tesseractgrimwlr-randrwl-copyandwl-pasteydotool- Python 3 with
pyatspi
Example install on Ubuntu-like systems:
sudo apt update
sudo apt install -y wmctrl xdotool x11-utils x11-xserver-utils maim imagemagick gnome-screenshot xclip xsel xdg-utils tesseract-ocr grim wl-clipboard python3
Installation
git clone <your-repo-url> aegis-desktop
cd aegis-desktop
npm install
Local Development
npm run dev
Validation loop:
npm run lint
npm run typecheck
npm test
npm run build
Build
npm run build
Run
Development:
npm run dev
Built server:
npm run build
npm start
Lightweight smoke check:
npm run smoke
Tool Catalog
System and diagnostics:
get_system_infolist_capabilitieshealth_checklist_monitors
Windows:
list_windowsget_active_windowfocus_windowmove_windowresize_windowset_window_boundsclose_windowwait_for_windowmove_window_to_primary_monitor
Screen and artifacts:
take_screenshotwindow_screenshotinspect_screenfind_text_on_screenartifact_list
Input:
key_downkey_upmouse_downmouse_upmouse_movemouse_clickmouse_dragtype_textpress_keysscroll_mouseget_pointer_positionperform_input_sequence
Apps and clipboard:
launch_appopen_urlread_clipboardwrite_clipboard
Accessibility and semantics:
get_accessibility_treefind_semantic_targets
See tools.md for schemas, behavior, and examples.
Stateful Input Model
aegis-desktop does not treat input as purely stateless. The input backend exposes low-level primitives that support multi-step interactions:
key_downkey_upmouse_downmouse_upmouse_move
High-level tools such as mouse_drag and press_keys build on those primitives. For more complex interactions, use perform_input_sequence.
Pointer and screenshot tools also support monitor-relative targeting through monitorId, relativeX, and relativeY where coordinates make sense.
perform_input_sequence
This tool validates and executes an ordered sequence of low-level steps as one logical action. It supports:
- modifier-hold plus drag
- multi-step drag operations
- keyboard plus mouse combinations
- scroll sequences
- dry-run validation
- cleanup of held keys/buttons after a mid-sequence failure
Example shift-drag:
{
"steps": [
{ "type": "key_down", "key": "Shift_L" },
{ "type": "mouse_down", "button": "left", "x": 100, "y": 100 },
{ "type": "mouse_move", "x": 300, "y": 300, "duration_ms": 200 },
{ "type": "mouse_up", "button": "left" },
{ "type": "key_up", "key": "Shift_L" }
]
}
Example hold-w while moving the mouse:
{
"steps": [
{ "type": "key_down", "key": "w" },
{ "type": "mouse_move", "x": 800, "y": 450, "duration_ms": 100 },
{ "type": "mouse_move", "x": 900, "y": 450, "duration_ms": 100 },
{ "type": "key_up", "key": "w" }
]
}
Safe dry run:
{
"dry_run": true,
"steps": [
{ "type": "key_down", "key": "Control_L" },
{ "type": "key_down", "key": "c" },
{ "type": "key_up", "key": "c" },
{ "type": "key_up", "key": "Control_L" }
]
}
Configuration Reference
Configuration sources:
- environment variables
- optional JSON config file via
AEGIS_CONFIG_PATH - sensible defaults
Important options:
AEGIS_ARTIFACT_DIRAEGIS_OCR_ENABLEDAEGIS_OCR_COMMANDAEGIS_COMMAND_TIMEOUT_MSAEGIS_SCREENSHOT_BACKENDAEGIS_INPUT_BACKENDAEGIS_SAFE_MODEAEGIS_ALLOWED_LAUNCH_COMMANDSAEGIS_LOG_LEVELAEGIS_MAX_SCREENSHOTS_PER_MINUTEAEGIS_MAX_INPUT_SEQUENCE_STEPS
See configuration.md for the full reference.
Safe Mode And Policy
The policy layer is intentionally explicit. Current controls include:
- launch command allowlist
- env allowlist for launched processes
- tool-level disable flags
- screenshot rate limiting
- coordinate validation
- input-sensitive safe mode
- command timeouts
When AEGIS_SAFE_MODE=true, risky operations such as app launching, typing, mouse clicks, drags, and window mutations are blocked.
Codex MCP Config Example
Example local stdio configuration for Codex:
{
"mcpServers": {
"aegis-desktop": {
"command": "node",
"args": ["/absolute/path/to/aegis-desktop/dist/src/index.js"],
"env": {
"AEGIS_ARTIFACT_DIR": "/absolute/path/to/aegis-desktop/artifacts",
"AEGIS_SAFE_MODE": "false",
"AEGIS_OCR_ENABLED": "true",
"XDG_SESSION_TYPE": "x11"
}
}
}
}
There is also a reusable example at codex-stdio.json.
Troubleshooting
- If
list_capabilitiesreports missing backends, install the corresponding Linux binaries. - If running under Wayland, expect partial or unavailable support for window management and synthetic input.
- If screenshots fail on X11, try setting
AEGIS_SCREENSHOT_BACKEND=maimorimport. - If screenshots fail on Wayland, install
grim;gnome-screenshothas limited deterministic region behavior. - If OCR is empty, verify
tesseractis installed andAEGIS_OCR_ENABLED=true. - If semantic tools return no nodes, verify
python3andpyatspiare available on the desktop session. - If launch requests are denied, check
AEGIS_ALLOWED_LAUNCH_COMMANDS. - If stateful input sequences are rejected, inspect validation errors and coordinate clamping warnings.
Security Notes
- The server never logs to stdout; stdout is reserved for MCP transport.
- App launching is policy-gated.
- Environment variables passed to launched apps are allowlisted.
- Screenshot generation is throttled.
- Input tooling validates coordinates and step structure.
- Unsupported features are reported honestly instead of silently faked.
This is still a powerful desktop-control surface. Run it only in environments you trust and configure policy conservatively for unattended usage.
Extensibility Guide
To add a new backend or tool:
- Add or extend an interface in
src/backends/types.ts. - Implement the backend in a dedicated backend module.
- Expose capability detection in
src/backends/detect.ts. - Add policy checks if the new action is sensitive.
- Register the tool in
src/server/registerTools.ts. - Document the behavior and add tests.
The goal is to keep tools thin and backends swappable.
Roadmap
- Wayland-aware input and window backends beyond the current partial surface
- accessibility-tree action execution and richer semantic targeting
- richer OCR engines and language packs
- multi-monitor routing is now present; next step is per-monitor policy and focus control
- semantic UI targeting that can drive actions, not just inspection
- recording and replay
- policy plugins and richer approval models
See roadmap.md.