Skip to main content
Glama
hlsitechio

omarchy-mcp

by hlsitechio
README.md
# omarchy-mcp

![omarchy-mcp](assets/logo.jpeg)

Give any MCP-compatible LLM full control of an [Omarchy](https://omarchy.org)
Linux desktop.

`omarchy-mcp` turns AI coding agents into genuine desktop operators. Through
one MCP server, an agent can manage themes and appearance, launch apps, take
screenshots and recordings, control audio and networking, read system state,
drive Hyprland windows and tiling layouts, and orchestrate entire multi-agent
workspaces — 108 tools across 15 modules.

The project is built around one rule: **a desktop mutation is not successful
merely because a command ran.** Every action is confirmed against measured
desktop state — geometry, focus, service status — so agents can act
autonomously without silently failing.

## Status

| | Current state |
|---|---|
| MCP tools | 466 registered tools across 17 modules (110 hand-crafted + 356 generated from `omarchy commands`) |
| Live verification | 83 of 110 hand-crafted paths recorded with measured desktop evidence; generated 356 via catalog-validated `omarchy_exec` |
| Transport | Local stdio MCP server |
| Runtime | Node.js 20+ and TypeScript |
| Desktop | Omarchy with the Hyprland Lua configuration bridge |
| Tiling | Native `lua:omarchy-grid` grid/master layout |
| Safety | Destructive tools disabled by default; host-window self-guard |
| Verification | Unit tests, MCP smoke test, and live-desktop evidence ledger |

See [COMMANDS.md](COMMANDS.md) for tool-by-tool verification status and
[ROADMAP.md](ROADMAP.md) for planned milestones.

## Why this exists

Desktop-control tools often report that an action was dispatched without
checking whether it worked. That is particularly unreliable for tiling window
managers, where focus, floating rules, fullscreen state, workspace rules, and
the mouse can change the target.

This server adds the missing feedback loop:

- Window mutations report measured before/after state and a clear verdict.
- Explicit address and match selectors reduce focus-related mistakes.
- A PID-ancestry guard prevents the agent from closing its own host window.
- Destructive system operations require an explicit configuration opt-in.
- `health_check` diagnoses missing commands, layout installation, and desktop
  connectivity.
- `agent_grid` turns an entire multi-agent workspace request into one verified
  MCP operation.

## Quick start

### Requirements

- An installed Omarchy desktop
- Hyprland with Omarchy's Lua configuration bridge
- Node.js 20 or newer
- npm

Individual features may also use `wtype`, `nmcli`, `bluetoothctl`, `wpctl`,
`grim`, and `wl-copy`. `health_check` reports which optional commands are
available.

### Build

```bash
git clone https://github.com/hlsitechio/Omarchy-MCP.git
cd Omarchy-MCP
npm ci
npm run build
npm test
```

The MCP entry point is:

```text
node /absolute/path/to/Omarchy-MCP/build/index.js
```

### Install the native grid layout

The regular desktop tools can run without the custom layout, but deterministic
grid/master tiling and `agent_grid` require it.

```bash
install -Dm644 hypr/layouts.lua ~/.config/hypr/layouts.lua
```

Make sure the user Hyprland configuration loads it:

```lua
require("hypr.layouts")
```

Then reload and check the configuration:

```bash
hyprctl reload
hyprctl configerrors
```

Omarchy package files under `/usr/share/omarchy` should remain untouched; the
layout belongs in the user configuration under `~/.config/hypr`.

## Connect an MCP client

Any client that supports local stdio MCP servers can launch
`build/index.js`.

### OpenCode

Add this to `~/.config/opencode/opencode.json`, replacing the path with the
repository's absolute path:

```json
{
  "mcp": {
    "omarchy": {
      "type": "local",
      "command": [
        "node",
        "/absolute/path/to/Omarchy-MCP/build/index.js"
      ],
      "enabled": true
    }
  }
}
```

### Claude Desktop

```json
{
  "mcpServers": {
    "omarchy": {
      "command": "node",
      "args": ["/absolute/path/to/Omarchy-MCP/build/index.js"]
    }
  }
}
```

Restart or reconnect an existing MCP client after rebuilding so it reloads the
tool schema.

## First prompts to try

- “Check whether my Omarchy MCP is healthy.”
- “Show every window with its workspace and geometry.”
- “Open a 2x2 grid of OpenCode on the next empty workspace.”
- “Put Claude top-right and Codex bottom-right.”
- “Move Firefox to workspace 4 and confirm where it ended up.”
- “Snap this window to the top-left and tell me its final size.”
- “List nearby Wi-Fi networks, but do not connect to anything.”

## One-command coding-agent workspaces

`agent_grid` launches independent Omarchy TUI windows, applies the native grid
layout, assigns exact or sparse cells, and verifies each window's application
class, workspace, floating state, and observed geometry.

For four applications, ask for a **2x2** grid. A literal **4x4** grid contains
16 cells and launches 16 applications when fully populated.

### Homogeneous grid

Prompt:

> Open a 2x2 grid of OpenCode in this repository.

Equivalent arguments:

```json
{
  "agent": "opencode",
  "cols": 2,
  "rows": 2,
  "workspace": "next_empty",
  "cwd": "/path/to/project"
}
```

### Mixed sparse grid

Prompt:

> Open Claude in the top-right and Codex in the bottom-right.

Equivalent arguments:

```json
{
  "cols": 2,
  "rows": 2,
  "placements": [
    { "agent": "claude", "position": "top_right" },
    { "agent": "codex", "position": "bottom_right" }
  ]
}
```

Supported agents are OpenCode, Claude, Codex, Gemini, Copilot, Crush, Grok,
Oh My Pi (`omp`), and Pi. Use `dry_run: true` to validate a complete plan
without opening windows.

Named corner assignments and explicit row/column assignments persist when the
user changes workspaces. Existing tiled windows are counted before launch, and
the request is rejected if it would exceed the grid capacity.

## Tool groups

| Domain | Tools | Examples |
|---|---:|---|
| Window and layout control | 24 | focus, type, keys, snap, resize, close, workspaces, grid/master |
| Desktop essentials | 11 | launch, screenshots, reminders, audio, brightness, system status |
| Shell and local UI | 13 | notifications, DND, OSD, bar state/configuration, plugin inspection |
| Local plugin lifecycle | 4 | bounded detail, enable, disable, and packaged local clone workflows |
| Device and audio controls | 7 | audio inventory/defaults, media source, keyboard and input devices |
| Local launchers | 3 | Files/About, validated config files, and allow-listed terminal tools |
| Network and power | 11 | Wi-Fi, Bluetooth, battery, power profiles |
| Theme and appearance | 11 | themes, local backgrounds, thumbnail cache, fonts |
| Capture and local media | 7 | recording, OCR/QR selectors, transcoding, ASCII conversion |
| Local system state | 6 | versions, resources, monitor state, toggles, hardware readiness |
| Gated system operations | 5 | shutdown, packages, update, configuration refresh |
| Defaults and display | 3 | application defaults and coordinated text sizing |
| Health and discovery | 2 | readiness diagnostics, installed command search |
| Coding-agent orchestration | 1 | homogeneous and mixed agent grids |

The complete list and its live-test status are maintained in
[COMMANDS.md](COMMANDS.md).

## Safety model

### No shell interpolation

Commands are executed with argument arrays through Node's `execFile` or
`spawn`; user input is not concatenated into shell commands.

### Destructive operations are opt-in

Shutdown, reboot, package installation, system updates, and configuration
refreshes are disabled by default. Enable them with:

```bash
mkdir -p ~/.config/omarchy-mcp
printf '%s\n' '{"enableDangerous": true}' > ~/.config/omarchy-mcp/config.json
```

Or set the process-level override:

```bash
OMARCHY_MCP_ENABLE_DANGEROUS=1 node build/index.js
```

Use this setting only for a client and session you trust.

### Host-window protection

Window-closing and other high-risk operations resolve the MCP host process's
PID ancestry and refuse to target its own terminal window. Explicit window
addresses are preferred for mutations because Hyprland focus can follow the
mouse.

### Verified outcomes

Mutating window tools return statuses such as `confirmed`,
`split_confirmed`, `opened_but_not_split`, or `not_detected`, together with
the measured state and a recovery hint where appropriate.

## Architecture

```text
MCP client
    │  JSON-RPC over stdio
    ▼
MCP tool + Zod input validation
    │
    ├── Omarchy CLI ───────────── themes, capture, power, applications
    ├── Hyprland Lua dispatcher ─ windows, workspaces, native layout
    └── System CLIs ───────────── nmcli, bluetoothctl, wpctl, upower
    │
    ▼
State reread + geometry/verdict engine
    │
    ▼
Structured MCP result with STATUS, evidence, and HINT
```

Source layout:

```text
src/index.ts              server and tool registration
src/exec.ts               shell-free process execution
src/hypr.ts               desktop introspection and verification helpers
src/result.ts             consistent MCP success/error results
src/config.ts             safety configuration
src/tools/                 tool domains
hypr/layouts.lua          native deterministic grid/master layout
test/                      automated and manual live tests
```

Hyprland window dispatches use the Omarchy Lua API, for example:

```lua
hl.dsp.window.resize({ window = "address:0x...", x = 900, y = 700, relative = false })
```

The native layout supports `grid` and `master` modes plus runtime messages for
forced dimensions, ordering, swaps, sparse cells, and per-workspace state.

## Development and verification

```bash
npm run build      # TypeScript compilation
npm test           # compilation + deterministic planner tests
npm run smoke      # live local MCP/Omarchy smoke test
```

The smoke test is intentionally desktop-aware. It checks tool registration,
the health report, read-only Omarchy/Hyprland access, the destructive-operation
gate, and an `agent_grid` dry run. Visual mutations are verified manually on a
real Omarchy session and recorded in [COMMANDS.md](COMMANDS.md).

For a live agent-grid exercise:

```bash
node test/live-agent-grid.mjs
```

This command opens real windows and changes the active workspace; it is not
part of `npm test`.

## Troubleshooting

### The new tool does not appear

Run `npm run build`, then restart or reconnect the MCP client. MCP clients
normally cache the tool list for the life of the server process.

### `health_check` says the grid layout is not fully installed

Confirm that `~/.config/hypr/layouts.lua` exists, that the user Hyprland config
contains `require("hypr.layouts")`, and that `hyprctl configerrors` is empty.

### A window command selected the wrong target

Call `window_list`, then retry with the returned address instead of relying on
the focused window. This avoids `input:follow_mouse` focus changes.

### A dangerous tool says it is disabled

That is the safe default. Enable it explicitly only after reviewing the
[safety model](#safety-model).

### A layout command reports a Hyprland warning

Some compositor no-ops are expected—for example, swapping a fullscreen window
or swapping toward an empty cell. The MCP result distinguishes these warnings
from confirmed mutations.

## Contributing

Contributions are welcome across implementation, live verification,
documentation, testing, accessibility, and release engineering. The repository
provides structured issue forms for bugs, tool proposals, and verification
reports, plus a pull-request checklist aligned with the project safety model.

Start with [CONTRIBUTING.md](CONTRIBUTING.md), then choose a contribution lane
from [ROADMAP.md](ROADMAP.md). Broad or high-risk changes should begin with an
issue so scope, evidence, and recovery behavior can be agreed before coding.

## Project documents

- [COMMANDS.md](COMMANDS.md) — implementation and live-verification ledger
- [ROADMAP.md](ROADMAP.md) — milestones, priorities, and release gates
- [CONTRIBUTING.md](CONTRIBUTING.md) — contribution and testing workflow
- [GOVERNANCE.md](GOVERNANCE.md) — roles, decisions, reviews, and releases
- [SECURITY.md](SECURITY.md) — private reporting and security boundaries
- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) — community participation standards
- [AGENTS.md](AGENTS.md) — technical context for coding agents working on the repository

## License

[MIT](LICENSE)

TDQS

B3.4/5.0

Scored across 108 tools

Disambiguation4/5

Most tools have clearly distinct purposes with detailed descriptions, but the sheer number creates some overlaps such as window_snap vs self_window_snap and layout_swap_windows vs window_swap. While these are functionally different, an agent may struggle to pick the right one in ambiguous situations.

Naming Consistency4/5

The majority of tools follow a consistent verb_noun pattern (e.g., wifi_toggle, theme_set, window_close). Minor deviations exist, such as noun-based names like system_info and omarchy_version_info, but the style remains predictable and clear throughout the set.

Tool Count1/5

With 108 tools, this server vastly exceeds any reasonable tool count for an MCP server. Even for a broad desktop environment, the number is overwhelming and will likely lead to tool-selection errors and increased latency. The scope is far beyond the typical 3-15 tools that are considered well-scoped.

Completeness4/5

The tool set covers an impressive range of desktop operations: themes, backgrounds, windows, audio, wifi, bluetooth, notifications, plugins, and more. There are minor gaps like explicit workspace creation, but hypr_dispatch offers flexibility. Overall, the surface is quite complete for the domain, with only a few missing lifecycle operations.

Maintenance

ActivityMaintained
ResponsivenessResponsive