Skip to main content

MCP

The same loopback server speaks the Model Context Protocol at /mcp (streamable HTTP, via the official MCP Rust SDK) — so Claude Code, Claude Desktop, or any MCP client can drive Vindue as a tool.

Register​

Claude Code:

claude mcp add --transport http vindue http://127.0.0.1:47725/mcp

Claude Desktop / Cursor / other clients: add an HTTP MCP server pointing at http://127.0.0.1:47725/mcp (Settings → MCP servers; the URL is copyable from Vindue's Settings → API section).

Then just ask: "Put Safari on the left half of my right monitor."

Tools​

Settings + tiling; no UI control by design. The catalog below is generated from the compiled Rust code — descriptions and parameter schemas exactly as tools/list serves them to clients — and pinned by a CI drift gate, so it cannot go stale.

ToolWhat it doesParameters
delete_shortcutRemove a shortcut binding by its KeyboardEvent.code. Reports whether it existed.
  • key string, required — KeyboardEvent.code of the key, e.g. "Digit1".
get_configThe full config: grid (rows, cols, windowGap, screenMargins), keybindings (openPanel hotkey; "" = none), shortcuts (assignment + keys), api (port, enabled).none
get_stateEverything about Vindue right now: Accessibility trust, the current target window (frontmost), all monitors with canonical labels, and the full config (grid, keybindings, shortcuts, api). Call this first.none
list_appsRunning apps that own windows: pid and name — pass either to tile_window's app parameter.none
list_monitorsAll connected displays: canonical label (use these strings to target monitors — twins get positional suffixes like "(left)"/"(right)"), position, size, work area, and scale factor.none
list_shortcutsThe shortcuts config: assignment mode (pinned binds new shortcuts to the monitor they are created on; relative follows the panel's monitor) plus every key → { monitor, selection } binding.none
set_gridUpdate the grid: rows/cols (1-12), windowGap and screenMargins (px 0-300). Only the fields passed change. Stored shortcuts that no longer fit are rescaled proportionally, and open panel/Settings views refresh.
  • cols integernull, optional — Grid columns, 1-12. Omit to leave unchanged.
  • rows integernull, optional — Grid rows, 1-12. Omit to leave unchanged.
  • screenMargins any, optional — Margins inset from the screen edges, px 0-300.
  • windowGap any, optional — Gap between tiled windows, px 0-300.
set_hotkeySet or clear the global hotkey that opens the Vindue panel (e.g. "CommandOrControl+Alt+S"; "" = none). Registration fails if macOS or another app owns the combo — the error will say so.
  • keys string, required — Accelerator string like "CommandOrControl+Alt+S", or "" to remove the global open-panel hotkey.
set_marginsSet screen margins (px 0-300) inset from each edge of every display's work area.
  • bottom integer, required — Margin inset from the bottom of the work area, px 0-300.
  • left integer, required — Margin inset from the left of the work area, px 0-300.
  • right integer, required — Margin inset from the right of the work area, px 0-300.
  • top integer, required — Margin inset from the top of the work area, px 0-300.
set_shortcutCreate or update a keyboard shortcut that tiles the frontmost window into the given grid cells. Pass a monitor label from list_monitors (or index) to pin it to a display; omit monitor for a relative shortcut.
  • key string, required — KeyboardEvent.code of the key, e.g. "Digit1", "KeyT", "Backquote".
  • monitor stringnull, optional — Monitor label from list_monitors or index to pin this shortcut to a display. Omit for a relative shortcut that follows whichever monitor the panel is on.
  • selection any, required — Grid cells (inclusive) the shortcut tiles into.
set_shortcut_assignmentSet whether new shortcuts are "pinned" to the monitor they are created on or "relative" (following the panel's monitor).
  • assignment string, required — "pinned" (new shortcuts bind to the monitor they are created on) or "relative" (shortcuts follow the panel's monitor).
tile_windowMove and resize a window to a grid region. Presets: full, left_half, right_half, top_half, bottom_half, top_left, top_right, bottom_left, bottom_right — or pass explicit inclusive cells. Targets the frontmost window by default; pass an app name or pid for another app. The monitor defaults to the one holding the target window.
  • app any, optional — App to tile — pid or name. Defaults to the frontmost window.
  • cells any, optional — Explicit grid cells — use instead of preset.
  • monitor stringnull, optional — Monitor to tile on: canonical label from list_monitors (e.g. "DELL U2720Q (left)"), a monitor index, or "current". Defaults to the display holding the target window.
  • preset stringnull, optional — Named region: full, left_half, right_half, top_half, bottom_half, top_left, top_right, bottom_left, bottom_right.

Design notes​

  • One implementation, two protocols — every tool delegates to the exact same handler functions as the REST API
  • Self-describing — the server advertises usage instructions in its initialize response, so clients learn the workflow (check get_state, use canonical labels, cells are inclusive) without docs
  • Same guard as REST — rmcp enforces its own loopback Host allowlist on every request; browsers can't reach it

Requirements​

  • Vindue running with api.enabled (the default)
  • The Accessibility grant for tile_window to move windows (read-only tools work without it)

Walkthrough: Tile windows with Claude.