hammerspoon について
hammerspoon-mcp は、Hammerspoon を通じて macOS をプログラムから操作する MCP サーバーです。OS 自動化ツールに加え、イベント監視とサブスクライブ可能なリソースを提供します。
主な機能
- 01ウィンドウと仮想デスクトップの管理
- 02アプリ、入力、画面の制御
- 03オーディオと Bluetooth デバイスの切り替え
- 04集中モードとシステム設定の変更
- 05OS イベントの監視とリソース購読
- 06Hammerspoon 内での Lua 実行
活用シーン
- 01ウィンドウを整列し、Spaces 間でアプリを移動
- 02オーディオ出力の切り替えや Bluetooth デバイスの接続
- 03入力の自動化とシステム設定の調整
- 04アプリ、ネットワーク、バッテリー、クリップボードのイベントへの対応
MCP 対応
MCP クライアントに macOS 自動化ツールとサブスクライブ可能なリソースを公開します。サーバーは Hammerspoon と通信し、監視対象の OS イベントを配信します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
hammerspoon-mcp
1 つの MCP サーバーを通じて、AI エージェントが macOS を深く制御できるようにします。ウィンドウ、オーディオ、Bluetooth、Spaces、集中モード、200 以上の OS API に対応します。
これは何ですか?
MCP サーバーとして、AI エージェントと、利用可能な macOS 自動化ツールの中でも最も強力な Hammerspoon を連携させます。スクリーンショットを撮ってクリックするツールとは異なり、エージェントはプログラムから OS レベルでアクセスできます。ID でウィンドウを管理したり、名前でオーディオデバイスを切り替えたり、アプリを Spaces 間で移動したり、集中モードを切り替えたり、リアルタイムの OS イベントを購読したりできます。
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 種類のプリセット(半分、3 分割、4 分割、グリッド、カスケード、中央配置など)とカスタムの相対レイアウト |
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 | デバイスの変更を監視 |
🔵 Bluetooth(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 | クイックルックでプレビュー |
🛠️ ユーティリティ(5)
| ツール | 説明 |
|---|---|
hs_system_info | CPU、メモリ、熱状態、稼働時間 |
hs_caffeinate | N 分間スリープを防止 |
hs_execute | シェルコマンドを実行(ユーザー環境) |
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)の制御 | ✅ | ❌ | ❌ |
| オーディオデバイスの切り替え | ✅ | ❌ | ❌ |
| Bluetooth の制御 | ✅ | ❌ | ❌ |
| 集中モード/DND モード | ✅ | ❌ | ❌ |
| 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(Bluetooth ツール用) |
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~80ms かかります。標準出力のノイズ(-- Loading extension: ...)は自動的に除去されます - ウォッチャーは JSON 行を FIFO パイプに書き込む Lua コードを注入します。Node のリーダープロセスがそれらを MCP リソース更新として送信します
- リソースはウォッチャーごとに直近 50 件のイベントをバッファリングします。クライアントは更新通知を受け取った後、必要に応じて読み取ります
- 正常なシャットダウンでは、すべてのウォッチャーを停止し、SIGINT/SIGTERM 時にパイプをクリーンアップします
既知の制限事項
enginesでは Node.js 22+ が指定されていますが、サーバーは Node 20 でも問題なくビルドおよび実行できます(テスト済み)hs_spaces_goto、addSpaceToScreen、removeSpaceは Mission Control を一瞬表示します(macOS の制限です。「視差効果を減らす」を有効にすると最小限に抑えられます)- Bluetooth ツールには blueutil が必要です(
brew install blueutil) - 集中モード/DND の読み取りにはヒューリスティックを使用します(公開された Apple API が存在しません)
hs_screenshotは base64 を返すため、全画面キャプチャではサイズが大きくなります- 保存されたレイアウトは Hammerspoon の実行中のみ保持されます(HS の再読み込みで失われます)
- 名前付きパイプのパスは
/tmp/hs-mcp-events.pipeです。同時に実行できるサーバーインスタンスは 1 つだけです
License
MIT © 2026 Mohammed Babur
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。