# hammerspoon-mcp [Health: Active]

**Category:** 🖥️ OS Automation  
**Repository:** https://github.com/vukvukovich/hammerspoon-mcp  
**GitHub Stars:** 1  
**npm Downloads (last month):** 204  
**Views:** 2  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/hammerspoon-mcp

## Description
Control macOS through Hammerspoon: windows, apps, and API search. Injection-safe by design.

## Tools
Capabilities this server exposes over MCP:

- **hs_health** — Verify that Hammerspoon is running and reachable, and report its version. Call this first when any other tool fails, because it distinguishes a setup problem from a tool problem.
- **hs_api_search** — Search Hammerspoon's own API documentation for functions, methods, constants, and modules. Returns exact signatures. Use this before writing Lua so calls are correct the first time, rather than discovering a wrong name from a runtime error.
- **hs_list_windows** — List every visible window with its id, owning application, title, frame, and screen. Window ids are what hs_focus_window and hs_move_window operate on, so call this first.
- **hs_focus_window** — Bring a window to the front, selected by id (exact) or by a substring of its title. The matched window is returned so you can confirm the right one was chosen.
- **hs_move_window** — Set the position and/or size of a window by id, in screen pixels. Omitted fields keep their current value. The returned frame is read back after the move settles, so it is the real placement; adjusted=true means macOS or the app put the window somewhere other than requested. Use hs_screens to learn the available coordinate space.
- **hs_window_layout** — Snap a window to a named position such as left-half or quarter-top-left, computed from the screen size so no pixel arithmetic is needed. Defaults to the focused window. Positions respect the menu bar and Dock.
- **hs_list_apps** — List running applications with pid, bundle identifier, window count, and which one is frontmost.
- **hs_launch_app** — Launch an application by name, or focus it if it is already running. Use the name as it appears in Finder, for example "Safari".
- **hs_focus_app** — Bring an already-running application to the front. Unlike hs_launch_app this never starts anything, so it fails if the application is not running.
- **hs_screens** — List connected screens with their coordinate frames. frame excludes the menu bar and Dock, fullFrame includes them. Use these bounds when computing arguments for hs_move_window.
- **hs_list_spaces** — List macOS Spaces across all screens with their id, type, and which one is current. User desktops also carry a 1-based position, which is the number people mean by "desktop 2" and what the Ctrl+N shortcuts match. Fullscreen app spaces have no position.
- **hs_goto_space** — Switch to another macOS desktop, either by its id from hs_list_spaces or by its 1-based position. The result reports where the switch actually landed: arrived=false with landedOn set means the system did not end up on the requested desktop, which can happen when macOS auto-rearranges Spaces mid-switch. Verified, not assumed.
- **hs_audio_devices** — List audio output and input devices, showing which is currently the default plus its volume and mute state. Call this before hs_audio_set_device to learn the exact device names.
- **hs_audio_set_device** — Make an audio device the system default, for example switching output to headphones or a display. Matches the name exactly first, then falls back to a case-insensitive substring, and lists the available devices when nothing matches.
- **hs_audio_volume** — Read or change the volume and mute state of the default audio device. Called with no arguments it only reports the current state, so it is safe to use as a query.
- **hs_brightness** — Read or change the built-in display brightness, 0 to 100. Called with no arguments it only reports. Most external displays do not support software brightness control and will report an error.
- **hs_media_control** — Send a system media key: play or pause, next track, previous track. Works with whichever application currently owns media playback (Music, Spotify, a browser tab), the same as pressing the key on the keyboard.
- **hs_machine_status** — One call for the state of the machine: host name and OS version, idle time, battery level and charging state, display brightness and screen count, current wifi network, and default audio device with its volume. Fields are null where the hardware does not provide them.
- **hs_peripherals** — List USB devices, cameras (including whether one is currently in use), and mounted volumes with free space. Answers questions like whether an external drive is mounted or whether the webcam is active.
- **hs_wifi** — Report the wifi radio state, the current network, and scan for available ones. radio="off" means no scan was attempted. scanned=false with the radio on means the scan was blocked or failed, in which case the current network is still reported.
- **hs_notification** — Post a real macOS notification. Delivery cannot be verified from here: an active Focus mode silently suppresses or files the banner, so posted=true means handed to Notification Center, not necessarily seen. Use this when the user should see something after stepping away. For a transient on-screen message that ignores Focus modes and leaves no trace, use hs_notify instead.
- **hs_keep_awake** — Stop the Mac from sleeping, or let it sleep again. Called with no arguments it reports the current state. Useful before a long build or download.
- **hs_lock_screen** — Lock the Mac immediately, as if you pressed the lock shortcut. Applications keep running and nothing is closed, so this is safe to do at any time.
- **hs_list_shortcuts** — List the user's macOS Shortcuts by name. These are automations the user wrote themselves, so they are often the best way to do something specific to this machine.
- **hs_run_shortcut** — Run one of the user's macOS Shortcuts by name. Input cannot be passed; a shortcut that needs input will run without it. The shortcut runs in the background, so this reports that it started rather than what it produced; a shortcut that fails after starting logs to the console, visible via hs_console_tail. Call hs_list_shortcuts first to get exact names.
- **hs_ui_inspect** — Read an application's accessibility tree: the buttons, menus, fields, and their labels, with the actions each supports. This is how you find out what is clickable in an app and what it is called. Returns structure and labels only, never the contents of text fields or documents. Each node carries a path you can pass to hs_ui_press.
- **hs_open_url** — Open a URL in the default handler for its scheme, or in a specific application by bundle id (for example com.google.Chrome or com.apple.Safari). The result names the application that actually received the URL. Errors when nothing handles the scheme or macOS refuses. Use hs_list_apps to find bundle ids.
- **hs_default_browser** — Report which application handles http, https, and mailto links, and optionally change the http and https handler. Called with no arguments it only reports. Changing it may make macOS ask the user to confirm.
- **hs_music_status** — Report the current track, artist, album, position, and playback state for Spotify and the Music app. A player that is not running is reported as such rather than being launched, so this is safe to call as a plain query.
- **hs_music_control** — Play, pause, or skip in Spotify or the Music app specifically. Use this instead of hs_media_control when more than one player could respond to a media key. The reported state is read back after the action settles, so it reflects what the player is now doing. Errors rather than launching the app if it is not already running.
- **hs_speak** — Say something out loud through the Mac speech synthesiser. Returns as soon as speech starts rather than waiting for it to finish. Calling again interrupts whatever is currently being spoken.
- **hs_list_voices** — List the installed speech synthesiser voices with name, language, gender where the system reports it, and the full identifier. Names repeat across languages (fourteen Eddys), so pass the identifier to hs_speak when the name alone is ambiguous.
- **hs_network** — Report the primary network interface, its IP addresses and router, the current wifi network, and optionally whether a given host is reachable. Reachability is a routing check, not a ping, so it answers instantly and does not prove the host is up.
- **hs_caps_lock** — Read or change the caps lock state, including its keyboard light. Called with no arguments it only reports.
- **hs_settings** — Store small values that survive Hammerspoon restarts, for remembering things between sessions. Keys are namespaced so this can never read or overwrite the user's own Hammerspoon settings. Values must be JSON-compatible.
- **hs_console_tail** — Return the most recent lines from the Hammerspoon console. This is where Lua errors and print output from the user configuration appear, so it is the first place to look when a config change misbehaves.
- **hs_notify** — Display a transient alert on screen through Hammerspoon. Useful for telling the user something without stealing focus.
- **hs_reload_config** — Reload ~/.hammerspoon/init.lua. Use after editing the user configuration. The reload is scheduled a moment ahead so this call can return first, and it resets all in-memory state held by the configuration. Speech started by hs_speak is stopped first; a speech callback landing after the reload would crash Hammerspoon.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "hammerspoon-mcp": {
    "command": "npx",
    "args": ["-y","@vukvukovich/hammerspoon-mcp"],
    "env": {
      "HS_MCP_TOOLS": ""
    }
  }
}
```

**Requires environment variables:** `HS_MCP_TOOLS` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation

## What hammerspoon-mcp MCP server does

The hammerspoon-mcp MCP server exposes macOS automation through Hammerspoon as MCP tools. It can inspect running applications and windows, focus or launch apps, move and resize windows, apply named layouts, and report connected screens. It also provides controls for Spaces, display brightness, audio devices, volume, mute, and system media keys.

For Hammerspoon development, the server can search the bundled API reference, read recent console output, reload `~/.hammerspoon/init.lua`, and display a temporary notification. A health check reports the resolved `hs` executable, whether Hammerspoon responds, and its version.

## How it works

MCP requests are translated into Lua programs executed by the running Hammerspoon process. Communication uses the Hammerspoon command-line interface and its `hs.ipc` module. The server communicates through a persistent Unix socket when available and can fall back to launching `hs` with an argument array; it does not use a shell to parse commands.

Tool arguments are validated, encoded as JSON, and then base64-encoded before being passed to a fixed Lua prelude. The Lua bodies are static rather than assembled from interpolated user input. This design keeps ordinary tool calls separate from the Lua source they execute.

The default tool tier is intended for reading, inspecting, arranging, and other controlled actions. `hs_eval`, `hs_applescript`, and `hs_ui_press` are disabled unless `HS_MCP_TOOLS=all` is configured. The UI tool requires an expected label or role from inspection and rejects the action if the element has changed.

## Setup and configuration

The hammerspoon-mcp MCP server requires macOS, Node.js 24 or newer, and an installed, running Hammerspoon application. Add `require("hs.ipc")` to `~/.hammerspoon/init.lua`, reload the Hammerspoon configuration, and verify the bridge with `hs -c "return 1 + 1"`. A result of `2` confirms that the command-line bridge is responding.

Install the server for a client that accepts an MCP server command with `npx -y @vukvukovich/hammerspoon-mcp`. For Claude Code, the documented command is `claude mcp add hammerspoon -- npx -y @vukvukovich/hammerspoon-mcp`. The optional `HS_MCP_TOOLS=all` environment variable enables the three gated tools.

## Tools and capabilities

Available capabilities include:

- Check bridge health, search Hammerspoon API documentation, tail the console, reload configuration, and show notifications.
- List, focus, move, resize, and arrange windows using IDs, title matches, pixel coordinates, or named layout presets.
- List, launch, and focus applications, including bundle IDs, PIDs, and window counts.
- Inspect screens, Spaces, machine status, audio devices, and current display state.
- Switch Spaces, change audio input or output devices, set volume or mute, adjust built-in display brightness, and control media playback.
- With the optional tool tier, evaluate Lua, run AppleScript against supported macOS applications, and press inspected UI elements.

Tool names and argument shapes may change because the project is pre-1.0.

_Full upstream README: https://allmcps.com/mcp/hammerspoon-mcp/readme_

