← Discover MCPs and Agents
t
MCPAI & MLGitHub

termusher

TermUsher — macOS menu bar app that seats your terminal windows in a tidy grid. Built for developers running multiple AI-CLI sessions (Claude Code, Codex, Cursor) at once. Tile, zoom, drag-to-reorder, auto-return on idle.

Links

README

From the repo.

TermUsher

TermUsher — macOS terminal window manager

Test

A macOS menu bar app that seats your terminal windows in a tidy grid. Built for developers who keep many AI-CLI sessions open at once — Claude Code, Codex, Cursor, Aider, plain shells, you name it. When you're juggling a dozen terminals chasing different agents and tasks, TermUsher tiles them so you can see them all, then quietly steps aside.

Click a tile to zoom it for typing — others tuck into a sidebar strip. Drag a terminal's title bar to reorder. ⌘⌥G or hover the top edge of the screen returns to the even grid. The app can also auto-return after you press Enter and go idle (perfect for chat-style LLM workflows). Stop tiling and TermUsher restores each window to where it was before.

Built for the AI-CLI workflow. If your day involves ten Claude Code sessions, three Codex tabs, and a Cursor in the corner, this is for you.

Tech stack: Swift Package Manager · AppKit · ApplicationServices (Accessibility API) · ServiceManagement (Launch at Login) · XCTest · GitHub Actions CI on macos-14 · swift build --arch arm64 --arch x86_64 (universal binary).

Current version: 0.5.0 — see CHANGELOG.md for release notes and docs/ARCHITECTURE.md for module layout.

Build

./build-app.sh

Produces TermUsher.app in the project root.

swift test

Runs pure unit tests (layout math + settings; no Accessibility grant required).

Install

cp -R TermUsher.app /Applications/
open /Applications/TermUsher.app

On first launch macOS will prompt for Accessibility permission. Grant it in System Settings → Privacy & Security → Accessibility, then re-launch.

For stable Accessibility grants across rebuilds (recommended for local development):

./scripts/setup-codesigning.sh
# follow the printed sudo trust step once
./build-app.sh

Auto-launch on login

Click the menu bar icon → Launch at Login. (Uses SMAppService — requires the app to be installed in /Applications.)

Use

Click the grid icon in the menu bar:

  • Tile Terminal Windows — lay out every standard Terminal window in an even grid (one grid per display, based on where each window currently sits).
  • Click any tile → it zooms. Four zoom styles in the Zoom Style submenu:
    • Side Strip — focused fills 78% on the left, others stack on the right.
    • Full Screen — focused fills the screen entirely.
    • Full Column — focused expands vertically only (1/N width × full screen height).
    • Disabled — clicking does nothing; the static grid stays put.
  • ⌘⌥T — toggle tiling from anywhere.
  • ⌘⌥G — return to the even grid (works from any app; doesn't conflict with vim/REPL Esc behavior in Terminal).
  • ⌘⌥⇧T — Stop tiling and leave windows where they are (no restore).
  • Return to Grid / Refresh Window List — re-tile or re-detect windows (auto-detects most cases).
  • Exclude Focused Window — drop the currently-focused tile from tiling and restore its original position. Useful for log tails or monitoring panes that shouldn't move. Re-tile (stop + start) to bring it back.
  • Stop Tiling — submenu with two choices: Restore Originals (snap each window back to its position at the moment tiling started) or Leave Where They Are (just stop managing in place).

Keybindings

ShortcutAction
⌘⌥TToggle tiling (start, or Stop & Restore)
⌘⌥GReturn to the even grid (cancels a zoom)
⌘⌥⇧TStop & Leave (windows stay where they are)

Hotkeys are global — they fire from any app. They use charactersIgnoringModifiers so they map to the physical keys on Dvorak / AZERTY / QWERTZ as well as US-QWERTY.

Auto Return to Grid

Three triggers can return a zoomed window to the grid without you reaching for a hotkey, all toggleable in the Auto Return to Grid submenu:

  • After N min idle — no input on screen for the configured interval (default 5 minutes) → grid.
  • On hover at top edge — move mouse to the very top of the screen for 0.3s → grid.
  • After ⏎ + Ns idle — press Return while Terminal.app is frontmost, then no further keystrokes for the configured interval (default 3 seconds) → grid. Best for Claude-CLI / chat-style usage. Enter in other apps is ignored.

All three are off by default. Enable any combination. Monitors are only installed for triggers you turn on.

Override durations (optional)

# Idle threshold (seconds)
defaults write com.youngharold.termusher TermUsher.autoReturnIdleSeconds -float 300

# Post-Return idle (seconds)
defaults write com.youngharold.termusher TermUsher.autoReturnAfterSendSeconds -float 3

Menu labels update to match the configured values.

Drag to reorder

While tiled, drag a Terminal window's title bar to move it. On release, TermUsher snaps it into the closest grid slot and swaps with whatever was there. Order persists for the session — restarting tiling resets to the original order. Windows dragged to another display re-tile on that display on the next Return to Grid.

Notes

  • New Terminal windows are auto-detected and added to the grid (~150ms after they appear).
  • Closed windows are dropped automatically; if only one Terminal window remains, tiling stops and that window is restored.
  • Windows on multiple displays tile within their own display (no cross-display merging). Unreadable-grid checks are per display.
  • Display plug/unplug or resolution changes while tiling re-index and re-tile automatically.
  • "Restore Originals" snaps each window back to the position it had at the moment tiling started — not to a pre-Terminal factory default.
  • Grid cells are pixel-snapped so odd display widths don't leave 1pt gaps between tiles.

Repository layout

Sources/TermUsher/          Menu bar app (AppDelegate, main)
Sources/TermUsherCore/      Layout, settings, WindowManager
Tests/TermUsherCoreTests/   XCTest suite
docs/ARCHITECTURE.md        Module responsibilities & data flow
CHANGELOG.md                Release history
build-app.sh                Universal .app bundle + codesign
scripts/                    Codesigning setup, diagram generators

Troubleshooting

  • Menu bar icon is there but tiling does nothing. Accessibility permission isn't granted to this exact build. Open System Settings → Privacy & Security → Accessibility — if TermUsher isn't listed, drag the app in; if it's listed but off, toggle it on. The hotkey monitor retries every ~1.5s, so you don't need to relaunch the app afterwards. Prefer the stable signing identity (see Install) so grants stick across rebuilds.
  • ⌘⌥T does nothing. Same as above — global key monitoring is gated by Accessibility.
  • Tile button shows "Too many Terminal windows". Cells would be smaller than 320×200 pt on that display. Move some windows to another display, or close a few.
  • Auto-return after Enter fires when I'm in another app. Fixed in 0.5.0 — only Terminal frontmost counts. Update if you're on an older build.
  • One Terminal window stays tiled fullscreen after closing siblings. This shouldn't happen — the app stops and restores when the count drops below 2. If it does, click Stop & Restore Originals in the menu.

Known limitations

  • Terminal.app only. iTerm2, Ghostty, Alacritty, and Warp use different AX subroles or aren't standard windows; they aren't detected.
  • Single-instance. Launching a second copy will alert and quit.
  • Ad-hoc signed (unless you run setup-codesigning.sh). Distributing the prebuilt .app outside this Mac will trip Gatekeeper. Build from source with ./build-app.sh instead.
  • Exclude is one-way for the session. Bring a window back by stopping and starting tiling (or opening a new window and refreshing).

Requirements

  • macOS 13+
  • Swift 5.9+
  • Apple Silicon or Intel (the build script produces a universal binary when both arch flags are used)

License

MIT

Collected info

  • 1 stars
  • 1 forks
  • Language: Swift
  • Source updated: 7/16/2026

Config for your environment

Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.

Tool

OS

Config file: ~/.cursor/mcp.json

{
  "mcpServers": {
    "mcp-server": {
      "url": "{MCP_ENDPOINT_URL}"
    }
  }
}

Paste into mcpServers in the config file. Restart Cursor after saving.

If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.