Skip to main content
Glama
mobabur94

hammerspoon-mcp

by mobabur94

hammerspoon-mcp

Give AI agents deep control over macOS — windows, audio, Bluetooth, Spaces, Focus mode, and 200+ OS APIs — through one MCP server.

macOS 13+ Node 22+ MIT License TypeScript

What is this?

An MCP server that bridges AI agents to Hammerspoon — the most powerful macOS automation tool available. Unlike screenshot-and-click tools, this gives agents programmatic OS-level access: manage windows by ID, switch audio devices by name, move apps between Spaces, toggle Focus mode, and subscribe to real-time OS events.

75 tools. 12 subscribable resources. Zero native dependencies.

Related MCP server: computer-use

Quick Start

# 1. Install Hammerspoon (if you haven't)
brew install --cask hammerspoon

# 2. Enable the IPC module (one-time setup)
#    Add this line to ~/.hammerspoon/init.lua:
#    require("hs.ipc")
#    Then reload your Hammerspoon config (Cmd+Alt+Ctrl+R or restart the app)

# 3. (Optional) Install the hs CLI symlink for convenience:
#    Run in Hammerspoon console: hs.ipc.cliInstall()
#    Or manually: ln -sf /Applications/Hammerspoon.app/Contents/Frameworks/hs/hs ~/.local/bin/hs

# 4. Run the MCP server
npx hammerspoon-mcp

Note: The server auto-discovers the hs binary — it checks ~/.local/bin/hs, /usr/local/bin/hs, /opt/homebrew/bin/hs, and the app bundle path. You don't need hs on your PATH if Hammerspoon is installed to /Applications.

Architecture

┌─────────────────────────────────────────────────────────┐
│  MCP Client (Claude, Cursor, MeshClaw, etc.)            │
└──────────────────────────┬──────────────────────────────┘
                           │ stdio (JSON-RPC)
┌──────────────────────────▼──────────────────────────────┐
│  hammerspoon-mcp (Node.js)                              │
│  ├─ tools → execSync("hs -c '...'")  (request/response)│
│  └─ watchers → named pipe reader     (push events)     │
└──────────────────────────┬──────────────────────────────┘
                           │ hs CLI / named pipe
┌──────────────────────────▼──────────────────────────────┐
│  Hammerspoon.app (Lua runtime + ObjC bridge)            │
│  200+ modules: window, screen, spaces, audio, wifi,     │
│  bluetooth, battery, USB, filesystem, accessibility...  │
└──────────────────────────┬──────────────────────────────┘
                           │
              macOS APIs (CoreGraphics, IOKit, etc.)

MCP Client Configuration

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "hammerspoon": {
      "command": "npx",
      "args": ["hammerspoon-mcp"]
    }
  }
}
claude mcp add hammerspoon -- npx hammerspoon-mcp

Add to .vscode/mcp.json:

{
  "servers": {
    "hammerspoon": {
      "command": "npx",
      "args": ["hammerspoon-mcp"]
    }
  }
}

Add to ~/.aws/amazonq/mcp.json:

{
  "mcpServers": {
    "hammerspoon": {
      "command": "npx",
      "args": ["hammerspoon-mcp"]
    }
  }
}

Tools

🪟 Window Management (7)

Tool

Description

hs_list_windows

All visible windows with app, title, frame, id

hs_focus_window

Bring window to front by id or title match

hs_move_window

Move/resize window by id

hs_window_layout

16 presets (halves, thirds, quarters, grid, cascade, center…) + custom fractional layouts

hs_save_layout

Snapshot all window positions as a named layout

hs_restore_layout

Restore a saved layout (matches by app + title)

hs_list_layouts

List saved layout names

🖥️ Spaces / Virtual Desktops (9)

Tool

Description

hs_spaces_list

All spaces per screen with active markers

hs_spaces_active

Currently focused space + screen

hs_spaces_goto

Switch by ID or index

hs_spaces_move_window

Move window to another space (optionally follow)

hs_spaces_add

Create a new space

hs_spaces_remove

Remove a space (safety checks)

hs_spaces_windows

Windows on a specific space

hs_spaces_window_spaces

Which space(s) a window is on

hs_spaces_mission_control

Toggle Mission Control / Exposé / Launchpad / Show Desktop

📱 Application Control (3)

Tool

Description

hs_list_apps

Running applications with bundle ID, PID, hidden state

hs_launch_app

Launch or activate an app by name

hs_kill_app

Quit an app

⌨️ Input (3)

Tool

Description

hs_click

Click at coordinates with button + modifier options

hs_type

Type text (Unicode, CJK, emoji)

hs_hotkey

Press key combo (e.g. "cmd+shift+4")

🖼️ Screen (3)

Tool

Description

hs_screenshot

Capture full screen or region (base64 PNG)

hs_screens

Display info (resolution, name, rotation)

hs_mouse_position

Current cursor coordinates

🔊 Audio Devices (6)

Tool

Description

hs_audio_devices

List all input/output with volume, mute, transport type

hs_audio_default

Get/set default devices (fuzzy name match)

hs_audio_volume

Volume on any specific device (0–100)

hs_audio_mute

Mute/unmute/toggle any device

hs_audio_datasources

List/switch data sources (speakers vs headphones)

hs_audio_watch

Watch for device changes

🔵 Bluetooth (5)

Tool

Description

hs_bluetooth_status

Power state and discoverability

hs_bluetooth_power

On / off / toggle

hs_bluetooth_devices

List paired or connected devices

hs_bluetooth_connect

Connect by name (fuzzy) or MAC address

hs_bluetooth_disconnect

Disconnect a device

Requires blueutil: brew install blueutil

🌙 Focus / Do Not Disturb (6)

Tool

Description

hs_focus_status

Check if DND/Focus is active + profile name

hs_focus_toggle

Toggle via Control Center (no setup needed)

hs_focus_shortcut

Enable/disable via macOS Shortcuts (most reliable)

hs_focus_install_shortcut

One-time setup guide

hs_focus_schedule

DND for N minutes with auto-disable

hs_focus_cancel_timer

Cancel scheduled disable

🔋 System State (6)

Tool

Description

hs_battery

Charge %, power source, time remaining

hs_wifi

Current SSID and interface details

hs_volume

System volume get/set

hs_dark_mode

Get/toggle dark mode

hs_notify

Post a macOS notification

hs_clipboard

Read/write system pasteboard

🔆 Display (1)

Tool

Description

hs_brightness

Get/set screen brightness (0–100)

⏱️ Timers (3)

Tool

Description

hs_timer_start

Named countdown with notification on fire

hs_timer_cancel

Cancel by name

hs_timer_list

List active timers

📁 Finder / Files (4)

Tool

Description

hs_finder_selection

Get currently selected Finder items

hs_finder_open

Open/reveal path in Finder

hs_trash

Move to Trash (reversible)

hs_quicklook

Quick Look preview

🛠️ Utilities (5)

Tool

Description

hs_system_info

CPU, memory, thermal state, uptime

hs_caffeinate

Prevent sleep for N minutes

hs_execute

Run shell command (user environment)

hs_open_url

Open URL in browser or specific app

hs_alert

HUD-style on-screen overlay message

👁️ Watchers — Live OS Event Streams (13)

Tool

Events

hs_watch_apps

App activated, launched, terminated, hidden

hs_watch_wifi

Network changes

hs_watch_usb

Device connect/disconnect

hs_watch_battery

Charge level, power source

hs_watch_screens

Display configuration

hs_watch_paths

Filesystem changes

hs_watch_sleep

Sleep/wake/lock/unlock

hs_watch_clipboard

Every pasteboard change

hs_watch_clipboard_history

Ring buffer with source app tracking

hs_get_clipboard_history

Read the full buffer

hs_watch_urls

Incoming hammerspoon://mcp/... URLs

hs_unwatch

Stop a watcher

hs_list_watchers

List active watchers

🧪 Escape Hatch (1)

Tool

Description

hs_eval

Execute arbitrary Lua in the Hammerspoon runtime

This gives access to all 200+ Hammerspoon modules not covered by dedicated tools — USB details, serial ports, network interfaces, Canvas drawing, menubar items, etc.

Resources (Subscriptions)

MCP clients can subscribe to resource URIs and receive push notifications when OS events fire:

URI

Triggers

watcher://apps

App lifecycle events

watcher://wifi

Network changes

watcher://usb

USB device events

watcher://battery

Battery/power changes

watcher://screens

Display reconfiguration

watcher://paths

Filesystem changes

watcher://sleep

Sleep/wake/lock events

watcher://clipboard

Pasteboard changes

watcher://clipboard_history

Clipboard ring buffer updates

watcher://urls

Incoming URL events

watcher://audio

Audio device changes

hammerspoon://system

System info snapshot

How event streaming works

Agent calls: hs_watch_wifi
  → Server injects Lua watcher into Hammerspoon runtime
  → macOS WiFi change fires
  → Watcher writes JSON to named pipe (/tmp/hs-mcp-events.pipe)
  → Node reader emits event
  → Server calls sendResourceUpdated("watcher://wifi")
  → Client reads resource → gets { ssid: "NewNetwork", ... }

Examples

"Tile my editor and terminal side by side"

hs_window_layout({ preset: "side-by-side" })

"Switch my audio to AirPods"

hs_audio_default({ output: "airpods" })
→ "set default output: AirPods Pro"

"Move Slack to Space 3"

hs_list_windows({ app: "Slack" })  → { id: 4523, ... }
hs_spaces_move_window({ windowId: 4523, spaceIndex: 3 })

"Start a 25-minute focus session"

hs_focus_schedule({ minutes: 25 })
hs_timer_start({ name: "pomodoro", minutes: 25, message: "Break time!" })

"Notify me when I switch away from my IDE"

hs_watch_apps()
→ Events stream to watcher://apps whenever focus changes

"Connect my headphones and set volume to 40%"

hs_bluetooth_connect({ device: "WH-1000XM5" })
hs_audio_volume({ device: "WH-1000XM5", volume: 40 })

Compared to Alternatives

Capability

hammerspoon-mcp

mac-use-mcp

macos-automator-mcp

Window management by ID

Virtual desktop (Spaces) control

Audio device switching

Bluetooth control

Focus / DND mode

Real-time OS event subscriptions

Clipboard history

Arbitrary OS scripting

✅ (Lua)

✅ (AppleScript)

Screenshot

Click / type / hotkeys

Accessibility tree queries

via hs_eval

Zero-install (no prerequisites)

Total tools

75

18

~10

Prerequisites

Requirement

Install

macOS 13+

Node.js 22+

brew install node

Hammerspoon

brew install --cask hammerspoon

hs.ipc module

Add require("hs.ipc") to ~/.hammerspoon/init.lua

blueutil (optional)

brew install blueutil (for Bluetooth tools)

The hs CLI symlink (hs.ipc.cliInstall()) is optional — the server auto-discovers the binary inside the Hammerspoon app bundle.

Verify setup

# If hs is on your PATH:
hs -c 'return "ok"'

# Or directly via the app bundle:
/Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c 'return "ok"'

# Should print: ok

If this works, npx hammerspoon-mcp will connect successfully.

Permissions

Permission

Required for

How to grant

Accessibility

Window, input, app control

System Settings → Privacy & Security → Accessibility → add your terminal

Screen Recording

hs_screenshot only

System Settings → Privacy & Security → Screen Recording

Project Structure

hammerspoon-mcp/
├── src/
│   ├── index.ts              MCP server entry point + resource registration
│   ├── bridge.ts             hs CLI bridge (auto-discovers binary, eval, evalJson)
│   ├── tools.ts              Core tools: window, app, input, screen, system, eval (23)
│   ├── watcher-tools.ts      Watcher management tools (13)
│   ├── watchers.ts           Named pipe event bridge
│   ├── spaces-tools.ts       Spaces / virtual desktop tools (9)
│   ├── audio-tools.ts        Audio device management (6)
│   ├── focus-tools.ts        DND / Focus mode (6)
│   ├── bluetooth-tools.ts    Bluetooth via blueutil (5)
│   └── extra-tools.ts        Brightness, timers, system info, Finder, utils (13)
├── package.json
├── tsconfig.json
├── LICENSE                   MIT
└── README.md

Development

git clone <repo>
cd hammerspoon-mcp
npm install
npm run dev     # Run with tsx (hot reload)
npm run build   # Compile to dist/
npm start       # Run compiled version

How It Works

  1. Startup — the bridge auto-discovers the hs binary (checks ~/.local/bin, /usr/local/bin, /opt/homebrew/bin, app bundle) and validates connectivity

  2. Tools execute synchronously via hs -c '<lua>' — typically 30–80ms per call. Stdout noise (-- Loading extension: ...) is stripped automatically

  3. Watchers inject Lua code that writes JSON lines to a FIFO pipe; a Node reader process emits them as MCP resource updates

  4. Resources buffer the last 50 events per watcher; clients read on-demand after receiving update notifications

  5. Graceful shutdown stops all watchers and cleans up the pipe on SIGINT/SIGTERM

Known Limitations

  • Node.js 22+ is specified in engines but the server builds and runs fine on Node 20 (tested)

  • hs_spaces_goto, addSpaceToScreen, removeSpace briefly flash Mission Control (macOS limitation — enable "Reduce motion" to minimize)

  • Bluetooth tools require blueutil (brew install blueutil)

  • Focus/DND reading uses heuristics (no public Apple API exists)

  • hs_screenshot returns base64 — large for full-screen captures

  • Saved layouts persist only in Hammerspoon's runtime (lost on HS reload)

  • Named pipe path is /tmp/hs-mcp-events.pipe — only one server instance at a time

License

MIT © 2026 Mohammed Babur

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    A
    maintenance
    A lightweight MCP server that bridges AI agents and macOS, enabling automation of file navigation, application control, UI interaction, browser automation, and system operations.
    145
    MIT
  • A
    license
    -
    quality
    C
    maintenance
    Standalone MCP server that gives AI agents full GUI control over macOS — screenshots, mouse, keyboard, apps, clipboard, and multi-display — with zero private dependencies.
    16
    MIT
  • A
    license
    -
    quality
    D
    maintenance
    MCP server that enables AI to fully control macOS — mouse, keyboard, terminal, screenshots, window management, UI element detection, and provides AI-optimized information reporting.
    32
    MIT

View all related MCP servers

Related MCP Connectors

  • Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.

  • User-owned memory for AI agents, Copilot, Claude, IDEs, CLIs, and chat apps over remote MCP.

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mobabur94/hammerspoon-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server