关于 hammerspoon
hammerspoon-mcp 是面向 AI Agent 的 MCP 服务,通过 Hammerspoon 提供 macOS 程序化控制。它将系统自动化工具与事件监视器、可订阅资源结合起来。
主要功能
- 01管理窗口和虚拟桌面
- 02控制应用、输入和屏幕
- 03切换音频与蓝牙设备
- 04调整专注模式和系统设置
- 05监视系统事件并订阅资源
- 06在 Hammerspoon 中运行 Lua
适用场景
- 01排列窗口并在 Spaces 间移动应用
- 02切换音频输出或连接蓝牙设备
- 03自动化输入并调整系统设置
- 04响应应用、网络、电池或剪贴板事件
MCP 相关
向 MCP 客户端提供 macOS 自动化工具和可订阅资源。服务端与 Hammerspoon 通信,并推送监视到的系统事件。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
hammerspoon-mcp
通过一个 MCP 服务,让 AI Agent 深度控制 macOS——窗口、音频、蓝牙、Spaces、专注模式以及 200 多个操作系统 API。
这是什么?
一个将 AI Agent 接入 Hammerspoon 的 MCP 服务——Hammerspoon 是目前功能最强大的 macOS 自动化工具。与截屏并点击的工具不同,它能让 Agent 以编程方式访问操作系统级功能:按 ID 管理窗口、按名称切换音频设备、在 Spaces 之间移动应用、切换专注模式,以及订阅实时操作系统事件。
75 个工具。12 个可订阅资源。零原生依赖。
快速开始
# 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
注意: 服务会自动查找
hs二进制文件——检查~/.local/bin/hs、/usr/local/bin/hs、/opt/homebrew/bin/hs和应用包路径。如果 Hammerspoon 安装在/Applications,则无需将hs添加到 PATH。
架构
┌─────────────────────────────────────────────────────────┐
│ 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 客户端配置
Claude Desktop
添加到 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"hammerspoon": {
"command": "npx",
"args": ["hammerspoon-mcp"]
}
}
}
Claude Code
claude mcp add hammerspoon -- npx hammerspoon-mcp
Cursor / VS Code / Copilot
添加到 .vscode/mcp.json:
{
"servers": {
"hammerspoon": {
"command": "npx",
"args": ["hammerspoon-mcp"]
}
}
}
Kiro
添加到 ~/.aws/amazonq/mcp.json:
{
"mcpServers": {
"hammerspoon": {
"command": "npx",
"args": ["hammerspoon-mcp"]
}
}
}
工具
🪟 窗口管理(7)
| 工具 | 描述 |
|---|---|
hs_list_windows | 列出所有可见窗口及其应用、标题、框架和 ID |
hs_focus_window | 按 ID 或标题匹配,将窗口置于最前 |
hs_move_window | 按 ID 移动或调整窗口大小 |
hs_window_layout | 16 种预设布局(左右半屏、三等分、四等分、网格、层叠、居中……)+ 自定义比例布局 |
hs_save_layout | 将所有窗口位置快照保存为命名布局 |
hs_restore_layout | 恢复已保存的布局(按应用 + 标题匹配) |
hs_list_layouts | 列出已保存的布局名称 |
🖥️ Spaces / 虚拟桌面(9)
| 工具 | 描述 |
|---|---|
hs_spaces_list | 列出各屏幕上的所有空间,并标记当前活动空间 |
hs_spaces_active | 当前聚焦的空间和屏幕 |
hs_spaces_goto | 按 ID 或索引切换 |
hs_spaces_move_window | 将窗口移至其他空间(可选择跟随切换) |
hs_spaces_add | 创建新空间 |
hs_spaces_remove | 移除空间(带安全检查) |
hs_spaces_windows | 指定空间上的窗口 |
hs_spaces_window_spaces | 窗口所在的空间 |
hs_spaces_mission_control | 切换 Mission Control / Exposé / Launchpad / 显示桌面 |
📱 应用控制(3)
| 工具 | 描述 |
|---|---|
hs_list_apps | 列出正在运行的应用及其捆绑包 ID、PID 和隐藏状态 |
hs_launch_app | 按名称启动或激活应用 |
hs_kill_app | 退出应用 |
⌨️ 输入(3)
| 工具 | 描述 |
|---|---|
hs_click | 在指定坐标点击,并可设置鼠标按键和修饰键 |
hs_type | 输入文本(Unicode、CJK、表情符号) |
hs_hotkey | 按下组合键(例如 "cmd+shift+4") |
🖼️ 屏幕(3)
| 工具 | 描述 |
|---|---|
hs_screenshot | 截取全屏或指定区域(base64 PNG) |
hs_screens | 显示屏幕信息(分辨率、名称、旋转方向) |
hs_mouse_position | 当前光标坐标 |
🔊 音频设备(6)
| 工具 | 描述 |
|---|---|
hs_audio_devices | 列出所有输入/输出设备及其音量、静音状态和传输类型 |
hs_audio_default | 获取/设置默认设备(模糊名称匹配) |
hs_audio_volume | 设置任意指定设备的音量(0–100) |
hs_audio_mute | 将任意设备静音/取消静音/切换静音状态 |
hs_audio_datasources | 列出/切换数据源(扬声器与耳机) |
hs_audio_watch | 监视设备变化 |
🔵 蓝牙(5)
| 工具 | 描述 |
|---|---|
hs_bluetooth_status | 电源状态和可被发现状态 |
hs_bluetooth_power | 开启/关闭/切换 |
hs_bluetooth_devices | 列出已配对或已连接的设备 |
hs_bluetooth_connect | 按名称(模糊匹配)或 MAC 地址连接 |
hs_bluetooth_disconnect | 断开设备连接 |
需要 blueutil:
brew install blueutil
🌙 专注模式/勿扰模式(6)
| 工具 | 描述 |
|---|---|
hs_focus_status | 检查勿扰模式/专注模式是否已启用,并显示配置文件名称 |
hs_focus_toggle | 通过控制中心切换(无需设置) |
hs_focus_shortcut | 通过 macOS 快捷指令启用/停用(最可靠) |
hs_focus_install_shortcut | 一次性设置指南 |
hs_focus_schedule | 设置 N 分钟的勿扰模式,到时自动停用 |
hs_focus_cancel_timer | 取消定时停用 |
🔋 系统状态(6)
| 工具 | 描述 |
|---|---|
hs_battery | 充电百分比、电源来源、剩余时间 |
hs_wifi | 当前 SSID 和接口详情 |
hs_volume | 获取/设置系统音量 |
hs_dark_mode | 获取/切换深色模式 |
hs_notify | 发布 macOS 通知 |
hs_clipboard | 读取/写入系统剪贴板 |
🔆 显示器(1)
| 工具 | 描述 |
|---|---|
hs_brightness | 获取/设置屏幕亮度(0–100) |
⏱️ 计时器(3)
| 工具 | 描述 |
|---|---|
hs_timer_start | 启动命名倒计时,结束时发送通知 |
hs_timer_cancel | 按名称取消 |
hs_timer_list | 列出活动计时器 |
📁 Finder/文件(4)
| 工具 | 描述 |
|---|---|
hs_finder_selection | 获取当前选中的 Finder 项目 |
hs_finder_open | 在 Finder 中打开/显示路径 |
hs_trash | 移到废纸篓(可撤销) |
hs_quicklook | Quick Look 预览 |
🛠️ 实用工具(5)
| 工具 | 描述 |
|---|---|
hs_system_info | CPU、内存、温度状态、运行时间 |
hs_caffeinate | 在 N 分钟内防止进入睡眠 |
hs_execute | 运行 shell 命令(用户环境) |
hs_open_url | 在浏览器或指定应用中打开 URL |
hs_alert | HUD 风格的屏幕叠加消息 |
👁️ 监视器 — 实时 OS 事件流(13)
| 工具 | 事件 |
|---|---|
hs_watch_apps | 应用已激活、已启动、已终止、已隐藏 |
hs_watch_wifi | 网络变化 |
hs_watch_usb | 设备连接/断开 |
hs_watch_battery | 充电电量、电源来源 |
hs_watch_screens | 显示器配置 |
hs_watch_paths | 文件系统变化 |
hs_watch_sleep | 睡眠/唤醒/锁定/解锁 |
hs_watch_clipboard | 每次剪贴板变化 |
hs_watch_clipboard_history | 环形缓冲区,并跟踪来源应用 |
hs_get_clipboard_history | 读取完整缓冲区 |
hs_watch_urls | 收到的 hammerspoon://mcp/... URL |
hs_unwatch | 停止监视器 |
hs_list_watchers | 列出活动监视器 |
🧪 逃生口(1)
| 工具 | 描述 |
|---|---|
hs_eval | 在 Hammerspoon 运行时中执行任意 Lua 代码 |
这可以访问专用工具未涵盖的 200 多个 Hammerspoon 模块,例如 USB 详情、串行端口、网络接口、Canvas 绘图、菜单栏项目等。
资源(订阅)
MCP 客户端可以订阅资源 URI,并在 OS 事件触发时接收推送通知:
| URI | 触发条件 |
|---|---|
watcher://apps | 应用生命周期事件 |
watcher://wifi | 网络变化 |
watcher://usb | USB 设备事件 |
watcher://battery | 电池/电源变化 |
watcher://screens | 显示器重新配置 |
watcher://paths | 文件系统变化 |
watcher://sleep | 睡眠/唤醒/锁定事件 |
watcher://clipboard | 剪贴板变化 |
watcher://clipboard_history | 剪贴板环形缓冲区更新 |
watcher://urls | 收到 URL 事件 |
watcher://audio | 音频设备变化 |
hammerspoon://system | 系统信息快照 |
事件流的工作方式
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", ... }
示例
“将我的编辑器和终端并排平铺”
hs_window_layout({ preset: "side-by-side" })
“将我的音频切换到 AirPods”
hs_audio_default({ output: "airpods" })
→ "set default output: AirPods Pro"
“将 Slack 移到 Space 3”
hs_list_windows({ app: "Slack" }) → { id: 4523, ... }
hs_spaces_move_window({ windowId: 4523, spaceIndex: 3 })
“开始一段 25 分钟的专注时段”
hs_focus_schedule({ minutes: 25 })
hs_timer_start({ name: "pomodoro", minutes: 25, message: "Break time!" })
“当我切换离开 IDE 时通知我”
hs_watch_apps()
→ Events stream to watcher://apps whenever focus changes
“连接我的耳机并将音量设为 40%”
hs_bluetooth_connect({ device: "WH-1000XM5" })
hs_audio_volume({ device: "WH-1000XM5", volume: 40 })
与替代方案的比较
| 功能 | hammerspoon-mcp | mac-use-mcp | macos-automator-mcp |
|---|---|---|---|
| 按 ID 管理窗口 | ✅ | ❌ | ❌ |
| 虚拟桌面(Spaces)控制 | ✅ | ❌ | ❌ |
| 音频设备切换 | ✅ | ❌ | ❌ |
| 蓝牙控制 | ✅ | ❌ | ❌ |
| 专注/勿扰模式 | ✅ | ❌ | ❌ |
| 实时 OS 事件订阅 | ✅ | ❌ | ❌ |
| 剪贴板历史记录 | ✅ | ✅ | ❌ |
| 任意 OS 脚本编写 | ✅ (Lua) | ❌ | ✅ (AppleScript) |
| 截屏 | ✅ | ✅ | ❌ |
| 点击/输入/快捷键 | ✅ | ✅ | ❌ |
| 辅助功能树查询 | 通过 hs_eval | ✅ | ❌ |
| 零安装(无需前置条件) | ❌ | ✅ | ✅ |
| 工具总数 | 75 | 18 | ~10 |
前置条件
| 要求 | 安装 |
|---|---|
| macOS 13+ | — |
| Node.js 22+ | brew install node |
| Hammerspoon | brew install --cask hammerspoon |
hs.ipc 模块 | 在 ~/.hammerspoon/init.lua 中添加 require("hs.ipc") |
| blueutil(可选) | brew install blueutil(用于蓝牙工具) |
hsCLI 符号链接(hs.ipc.cliInstall())为可选项——服务会自动在 Hammerspoon 应用程序包中发现该二进制文件。
验证设置
# 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
如果此命令可以正常运行,npx hammerspoon-mcp 就能成功连接。
权限
| 权限 | 用途 | 授予方式 |
|---|---|---|
| 辅助功能 | 窗口、输入、应用控制 | 系统设置 → 隐私与安全性 → 辅助功能 → 添加你的终端 |
| 屏幕录制 | 仅用于 hs_screenshot | 系统设置 → 隐私与安全性 → 屏幕录制 |
项目结构
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
开发
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
工作原理
- 启动 — 桥接程序会自动发现
hs二进制文件(检查~/.local/bin、/usr/local/bin、/opt/homebrew/bin和应用程序包),并验证连接 - 工具通过
hs -c '<lua>'同步执行——每次调用通常耗时 30–80 毫秒。标准输出中的噪声(-- Loading extension: ...)会自动剥离 - 监视器注入 Lua 代码,将 JSON 行写入 FIFO 管道;Node 读取器进程会将其作为 MCP 资源更新发出
- 资源会为每个监视器缓冲最近的 50 条事件;客户端收到更新通知后按需读取
- 正常关闭会停止所有监视器,并在收到 SIGINT/SIGTERM 时清理管道
已知限制
engines中指定了 Node.js 22+,但服务在 Node 20 上也能正常构建和运行(已测试)hs_spaces_goto、addSpaceToScreen、removeSpace会短暂闪现 Mission Control(macOS 的限制——启用“减少动态效果”可尽量减轻)- 蓝牙工具需要 blueutil(
brew install blueutil) - 专注/勿扰状态的读取使用启发式方法(Apple 没有提供公开 API)
hs_screenshot会返回 base64 数据——全屏截图的数据量较大- 保存的布局仅在 Hammerspoon 运行时中保留(重新加载 HS 后会丢失)
- 命名管道路径为
/tmp/hs-mcp-events.pipe——同一时间只能运行一个服务实例
License
MIT © 2026 Mohammed Babur
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。