Hammerspoon

io.github.mobabur94由 GitHub 账号 mobabur94 发布v0.1.0更新于 Oct 25, 2026

macOS automation via Hammerspoon — 75 tools for windows, Spaces, audio, Bluetooth, and more

已验证STDIO仅桌面效率与工作流开发者工具

概览

AI 生成的概览

一个本地 MCP 服务器,通过 Hammerspoon 让 AI 助手以编程方式控制 macOS:窗口、空间、音频、蓝牙、专注模式和系统状态。

可以做什么
列出、聚焦、移动和调整窗口,应用或保存布局预设,并管理空间与虚拟桌面,包括 Mission Control 切换和跨空间移动窗口。启动、激活和退出应用,并模拟点击、输入文字和快捷键。截取屏幕、读取显示器和光标信息、调节亮度。列出并切换音频设备、音量和静音,控制蓝牙开关、配对与连接。读取和更改电池、Wi-Fi、音量、深色模式、剪贴板、通知、计时器和防休眠等系统状态。监听应用、Wi-Fi、USB、电池、屏幕、文件、睡眠、剪贴板和 URL 等实时系统事件,并可执行 shell 命令、打开 URL 或运行 Lua
适用场景
适合希望助手直接操作 Mac 而不是靠截图和点击的场景:排列窗口、切换音频或蓝牙设备、在空间之间移动应用、开启专注时段,或对系统事件作出反应。适合已在使用或愿意安装 Hammerspoon 的 macOS 用户。
运行要求
macOS 13 或更高版本、Node.js(标注 22+,据称 20 也可运行),以及已安装 Hammerspoon 并在其 init.lua 中启用 hs.ipc 模块。蓝牙工具还需要 blueutil。窗口、输入和应用控制需要辅助功能权限;截图需要屏幕录制权限。无需 API 密钥或账户。
安装前请注意
它赋予对机器的广泛控制:执行任意 shell 命令、运行任意 Lua、模拟输入、退出应用、将文件移到废纸篓以及更改系统设置。剪贴板监听可能捕获敏感的剪贴板内容,截图也可能包含私密屏幕内容。请谨慎授予辅助功能和屏幕录制权限,并留意让助手执行的操作。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Hammerspoon,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

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.

Quick Start

bash
# 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 servernpx 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

Claude Desktop

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

json
{  "mcpServers": {    "hammerspoon": {      "command": "npx",      "args": ["hammerspoon-mcp"]    }  }}
Claude Code
bash
claude mcp add hammerspoon -- npx hammerspoon-mcp
Cursor / VS Code / Copilot

Add to .vscode/mcp.json:

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

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

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

Tools

🪟 Window Management (7)

ToolDescription
hs_list_windowsAll visible windows with app, title, frame, id
hs_focus_windowBring window to front by id or title match
hs_move_windowMove/resize window by id
hs_window_layout16 presets (halves, thirds, quarters, grid, cascade, center…) + custom fractional layouts
hs_save_layoutSnapshot all window positions as a named layout
hs_restore_layoutRestore a saved layout (matches by app + title)
hs_list_layoutsList saved layout names

🖥️ Spaces / Virtual Desktops (9)

ToolDescription
hs_spaces_listAll spaces per screen with active markers
hs_spaces_activeCurrently focused space + screen
hs_spaces_gotoSwitch by ID or index
hs_spaces_move_windowMove window to another space (optionally follow)
hs_spaces_addCreate a new space
hs_spaces_removeRemove a space (safety checks)
hs_spaces_windowsWindows on a specific space
hs_spaces_window_spacesWhich space(s) a window is on
hs_spaces_mission_controlToggle Mission Control / Exposé / Launchpad / Show Desktop

📱 Application Control (3)

ToolDescription
hs_list_appsRunning applications with bundle ID, PID, hidden state
hs_launch_appLaunch or activate an app by name
hs_kill_appQuit an app

⌨️ Input (3)

ToolDescription
hs_clickClick at coordinates with button + modifier options
hs_typeType text (Unicode, CJK, emoji)
hs_hotkeyPress key combo (e.g. "cmd+shift+4")

🖼️ Screen (3)

ToolDescription
hs_screenshotCapture full screen or region (base64 PNG)
hs_screensDisplay info (resolution, name, rotation)
hs_mouse_positionCurrent cursor coordinates

🔊 Audio Devices (6)

ToolDescription
hs_audio_devicesList all input/output with volume, mute, transport type
hs_audio_defaultGet/set default devices (fuzzy name match)
hs_audio_volumeVolume on any specific device (0–100)
hs_audio_muteMute/unmute/toggle any device
hs_audio_datasourcesList/switch data sources (speakers vs headphones)
hs_audio_watchWatch for device changes

🔵 Bluetooth (5)

ToolDescription
hs_bluetooth_statusPower state and discoverability
hs_bluetooth_powerOn / off / toggle
hs_bluetooth_devicesList paired or connected devices
hs_bluetooth_connectConnect by name (fuzzy) or MAC address
hs_bluetooth_disconnectDisconnect a device

Requires blueutil: brew install blueutil

🌙 Focus / Do Not Disturb (6)

ToolDescription
hs_focus_statusCheck if DND/Focus is active + profile name
hs_focus_toggleToggle via Control Center (no setup needed)
hs_focus_shortcutEnable/disable via macOS Shortcuts (most reliable)
hs_focus_install_shortcutOne-time setup guide
hs_focus_scheduleDND for N minutes with auto-disable
hs_focus_cancel_timerCancel scheduled disable

🔋 System State (6)

ToolDescription
hs_batteryCharge %, power source, time remaining
hs_wifiCurrent SSID and interface details
hs_volumeSystem volume get/set
hs_dark_modeGet/toggle dark mode
hs_notifyPost a macOS notification
hs_clipboardRead/write system pasteboard

🔆 Display (1)

ToolDescription
hs_brightnessGet/set screen brightness (0–100)

⏱️ Timers (3)

ToolDescription
hs_timer_startNamed countdown with notification on fire
hs_timer_cancelCancel by name
hs_timer_listList active timers

📁 Finder / Files (4)

ToolDescription
hs_finder_selectionGet currently selected Finder items
hs_finder_openOpen/reveal path in Finder
hs_trashMove to Trash (reversible)
hs_quicklookQuick Look preview

🛠️ Utilities (5)

ToolDescription
hs_system_infoCPU, memory, thermal state, uptime
hs_caffeinatePrevent sleep for N minutes
hs_executeRun shell command (user environment)
hs_open_urlOpen URL in browser or specific app
hs_alertHUD-style on-screen overlay message

👁️ Watchers — Live OS Event Streams (13)

ToolEvents
hs_watch_appsApp activated, launched, terminated, hidden
hs_watch_wifiNetwork changes
hs_watch_usbDevice connect/disconnect
hs_watch_batteryCharge level, power source
hs_watch_screensDisplay configuration
hs_watch_pathsFilesystem changes
hs_watch_sleepSleep/wake/lock/unlock
hs_watch_clipboardEvery pasteboard change
hs_watch_clipboard_historyRing buffer with source app tracking
hs_get_clipboard_historyRead the full buffer
hs_watch_urlsIncoming hammerspoon://mcp/... URLs
hs_unwatchStop a watcher
hs_list_watchersList active watchers

🧪 Escape Hatch (1)

ToolDescription
hs_evalExecute 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:

URITriggers
watcher://appsApp lifecycle events
watcher://wifiNetwork changes
watcher://usbUSB device events
watcher://batteryBattery/power changes
watcher://screensDisplay reconfiguration
watcher://pathsFilesystem changes
watcher://sleepSleep/wake/lock events
watcher://clipboardPasteboard changes
watcher://clipboard_historyClipboard ring buffer updates
watcher://urlsIncoming URL events
watcher://audioAudio device changes
hammerspoon://systemSystem 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

Capabilityhammerspoon-mcpmac-use-mcpmacos-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 queriesvia hs_eval✅❌
Zero-install (no prerequisites)❌✅✅
Total tools7518~10

Prerequisites

RequirementInstall
macOS 13+—
Node.js 22+brew install node
Hammerspoonbrew install --cask hammerspoon
hs.ipc moduleAdd 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

bash
# 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

PermissionRequired forHow to grant
AccessibilityWindow, input, app controlSystem Settings → Privacy & Security → Accessibility → add your terminal
Screen Recordinghs_screenshot onlySystem 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

bash
git clone <repo>cd hammerspoon-mcpnpm installnpm 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

来源:README.md,提交 388b47d

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.1.0最新Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分