hammerspoon-mcp について
hammerspoon-mcp は、MCP クライアントから Hammerspoon を操作する macOS 自動化サーバーです。ウィンドウやアプリ、システム機能を Agent から扱えます。Lua のツール本体は固定され、引数を別途渡す設計で、安全なツールだけが既定で有効です。
主な機能
- 01ウィンドウの一覧・フォーカス・配置
- 02アプリの起動と切り替え
- 03Hammerspoon API ドキュメントの検索
- 04コンソール確認と設定の再読み込み
- 05システム機能の確認と操作
- 06任意の Lua 実行は既定で無効
活用シーン
- 01デスクトップのウィンドウ配置
- 02Hammerspoon API の用法確認
- 03設定再読み込み後のエラー調査
- 04オーディオデバイスやデスクトップの切り替え
MCP 対応
stdio 経由で MCP クライアントに型付きツールを提供し、呼び出しを Hammerspoon の操作に変換します。任意の Lua 実行などの制限付きツールは、HS_MCP_TOOLS=all の設定時にのみ登録されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @vukvukovich/hammerspoon-mcpHS_MCP_TOOLSWhich tools to expose. "safe" (default) exposes inspection, window management, and system tools only. "all" additionally exposes hs_eval, hs_applescript, and hs_ui_press, which run arbitrary Lua and AppleScript and press UI elements - anything the user can do.HS_MCP_TRANSPORTHow Lua reaches Hammerspoon. "socket" (default) keeps one persistent Unix domain socket, self-installed on first call, with automatic fallback to spawning; "spawn" runs one hs process per call.HS_MCP_HS_PATHExplicit path to the Hammerspoon hs command line tool. Only needed when Hammerspoon is installed somewhere unusual.HS_MCP_DOCS_PATHExplicit path to Hammerspoon's bundled docs.json, used by hs_api_search.HS_MCP_LOG_LEVELLog verbosity on stderr: debug, info (default), warn, or error.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
38掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
これは何か
Hammerspoon は、Lua でスクリプトを記述する macOS 自動化アプリです。hs.ipc モジュールを通じてコマンドラインインターフェースを公開しているため、hs -c "<lua>" を実行すると、起動中の Hammerspoon プロセス内で Lua が実行されます。
このプロジェクトは、その CLI の前段で動作する MCP(Model Context Protocol)サーバーです。エージェントに、型付きツール(ウィンドウの一覧表示、ウィンドウの移動、アプリへのフォーカス、Hammerspoon API ドキュメントの検索、コンソールログの末尾取得、設定の再読み込み)を提供し、各ツール呼び出しを Hammerspoon が実行する Lua プログラムに変換します。
stdio 経由で MCP を使用するため、Claude Code、Claude Desktop、または独自の MCP クライアントから利用できます。
プロジェクトの状況
npm で v0.4.x として公開されています。安全なティアのツールが 38 個あり、さらに HS_MCP_TOOLS=all で有効になるツールが 3 個あります。まだ 1.0 より前のため、マイナーバージョン間でツール名や引数の形式が変更される場合があります。
このプロジェクトの特徴
1. 構造上、インジェクションを防止
「Lua を代わりに実行する」ブリッジのリスクの大半は、Lua を組み立てる段階で生じます。一般的な方法では、引数をソース文字列に埋め込み、危険な文字をエスケープします。エスケープは規律が求められる作業ですが、規律が守られないこともあります。
このサーバーは、値を埋め込みません。各ツールの Lua 本体は、TypeScript ソース内の静的な定数です。引数は別々に渡します。
- 検証済みの引数オブジェクトを JSON エンコードします。
- その JSON を base64 エンコードします。
- base64 テキストを、固定されたプリアンブル行に一度だけ埋め込みます。
local ARGS = hs.json.decode(hs.base64.decode("<base64>"))
その後、ツール本体は ARGS.title、ARGS.windowId などを読み取ります。
base64 の文字集合は A-Z、a-z、0-9、+、/、= です。引用符、バックスラッシュ、改行、角括弧、ハイフンは含まれません。そのため、ペイロードが Lua 文字列を閉じたり、エスケープシーケンスを開始したり、長い括弧を開いたり、コメントを開始したりすることはできません。誰かが正しくエスケープするのを忘れないからではなく、文字集合そのものによってインジェクションを不可能にしています。
シェルの層もありません。サーバーは永続的な Unix ソケット経由で Hammerspoon と通信し、ソケットが使えない場合は spawn(hsPath, ["-c", lua]) を argv 配列で呼び出します。どちらの経路でも、sh がコマンドを解析することはありません。
2. ティア別のツールで、デフォルトは安全
デフォルトのティアは safe で、読み取り、調査、配置操作を行います。任意の Lua を評価する hs_eval もありますが、HS_MCP_TOOLS=all を設定しない限り無効です。
理由についてはセキュリティを参照してください。要点は、脅威はあなた自身ではなく、プロンプトインジェクションだということです。
3. 設定開発のループを支援
Hammerspoon の価値の大半は、独自の init.lua にあります。そのため、このサーバーは Hammerspoon を操作するだけでなく、設定ファイルの作成も支援します。
hs_api_searchは Hammerspoon に同梱されている API ドキュメントを検索するため、エージェントは推測せずにhs.window.moveToUnitの正確なシグネチャを調べられます。hs_console_tailは Hammerspoon のコンソール出力を読み取るため、エージェントは自身のエラーを確認できます。hs_reload_configは編集後にinit.luaを再読み込みします。
編集し、再読み込みし、コンソールを読み取り、修正します。エージェントはこのループを自ら実行できます。
クイックスタート
前提条件
-
macOS。
-
Node.js 24 以降。
-
インストール済みで、実行中の Hammerspoon:
brew install --cask hammerspoon -
Hammerspoon の設定で
hs.ipcモジュールが読み込まれていること。~/.hammerspoon/init.luaに次の行を追加します。require("hs.ipc")その後、Hammerspoon のメニューバーアイコンから設定を再読み込みします。これにより、
hsコマンドラインツールがインストールされ、有効になります。これがないと、hs -cは通信相手を見つけられません。
クライアントを設定する前に、ブリッジが動作することを手動で確認します。
hs -c "return 1 + 1"
2 が表示されれば、準備完了です。
MCP クライアントに追加する
Claude Code:
claude mcp add hammerspoon -- npx -y @vukvukovich/hammerspoon-mcp
mcpServers JSON ブロックを受け付ける任意のクライアント:
{
"mcpServers": {
"hammerspoon": {
"command": "npx",
"args": ["-y", "@vukvukovich/hammerspoon-mcp"]
}
}
}
危険なティアを有効にするには、環境変数を追加します。Claude Code:
claude mcp add hammerspoon -e HS_MCP_TOOLS=all -- npx -y @vukvukovich/hammerspoon-mcp
JSON:
{
"mcpServers": {
"hammerspoon": {
"command": "npx",
"args": ["-y", "@vukvukovich/hammerspoon-mcp"],
"env": {
"HS_MCP_TOOLS": "all"
}
}
}
}
まず hs_health を呼び出すよう、エージェントに指示してください。hs バイナリが見つかったか、Hammerspoon が実行中か、hs.ipc が応答したかを報告します。
ツール一覧
ツールは41個で、安全なティアに38個、ゲートで保護されたものが3個あります。
| ツール | ティア | 機能 |
|---|---|---|
hs_health | safe | ブリッジの状態を報告します。解決された hs のパス、Hammerspoon が応答するかどうか、バージョンを確認できます。 |
hs_api_search | safe | Hammerspoon に同梱された API リファレンスを検索し、正確なシグネチャを返します。 |
hs_console_tail | safe | Hammerspoon コンソールの末尾 N 行を返します。 |
hs_reload_config | safe | ~/.hammerspoon/init.lua を再読み込みします。 |
hs_notify | safe | フォーカスを奪わずに、一時的な画面上のアラートを表示します。 |
hs_list_windows | safe | ウィンドウを ID、タイトル、所有アプリ、画面、フレームとともに一覧表示します。 |
hs_focus_window | safe | ID、またはタイトルの一部を指定してウィンドウにフォーカスします。 |
hs_move_window | safe | 絶対スクリーンピクセル単位で、ID を指定してウィンドウを移動またはサイズ変更します。 |
hs_window_layout | safe | left-half や quarter-top-left などの名前付きプリセットにウィンドウをスナップします。 |
hs_list_apps | safe | 実行中のアプリケーションを、バンドル ID、PID、ウィンドウ数とともに一覧表示します。 |
hs_launch_app | safe | 名前を指定してアプリケーションを起動するか、すでに実行中の場合はフォーカスします。 |
hs_focus_app | safe | すでに実行中のアプリケーションを前面に表示します。 |
hs_screens | safe | 画面を ID、名前、フレーム、プライマリ画面かどうかとともに一覧表示します。 |
hs_machine_status | safe | バッテリー、明るさ、Wi-Fi、アイドル時間、オーディオ、ホスト情報を 1 回の呼び出しで取得します。 |
hs_audio_devices | safe | オーディオの出力デバイスと入力デバイスを、現在のデフォルトとともに一覧表示します。 |
hs_audio_set_device | safe | デフォルトの出力デバイスまたは入力デバイスを、たとえばヘッドフォンに切り替えます。 |
hs_audio_volume | safe | デフォルトデバイスの音量とミュート状態を取得または設定します。 |
hs_brightness | safe | 内蔵ディスプレイの明るさを取得または設定します。 |
hs_media_control | safe | システムのメディアキーを使って、再生、一時停止、スキップ、または前の項目に戻ります。 |
hs_list_spaces | safe | 画面ごとにデスクトップ(Spaces)を、位置と現在のデスクトップがどれかとともに一覧表示します。 |
hs_goto_space | safe | ID または 1 から始まる位置を指定してデスクトップを切り替えます。 |
hs_eval | unsafe | 任意の Lua を評価します。HS_MCP_TOOLS=all が必要です。 |
hs_applescript | unsafe | AppleScript を実行します。Mail、Notes、Reminders、Finder にアクセスします。HS_MCP_TOOLS=all が必要です。 |
hs_ui_press | unsafe | hs_ui_inspect で検出した UI 要素を押します。検査結果の expectLabel または expectRole が指定されていない場合は実行を拒否し、要素が検査時の状態と一致しなくなった場合も実行を拒否します。HS_MCP_TOOLS=all が必要です。 |
hs_window_layout のプリセット:left-half、right-half、top-half、bottom-half、 | ||
maximize、center、thirds-left、thirds-center、thirds-right、 | ||
two-thirds-left、two-thirds-right、および4つの quarter-* コーナー。 | ||
| 位置は画面の使用可能なフレームを基準に計算されるため、メニューバーとDockが考慮され、 | ||
| 原点が負の位置にある2台目のモニターでも機能します。 |
hs_ui_inspect が返すのは構造とラベルのみで、テキストフィールドやドキュメントの内容は
返しません。エージェントが操作するために必要なのは構造であり、パスワードマネージャーを
構成するのは内容だからです。
unsafe ティアのツールは、明示的にオプトインしない限り登録されません。デフォルト設定で
接続したクライアントのツール一覧には、hs_eval、hs_applescript、hs_ui_press は
表示されません。
設定
すべての設定は環境変数で行い、起動時に一度だけ読み込まれます。
| 変数 | 値 | デフォルト | 説明 |
|---|---|---|---|
HS_MCP_TOOLS | safe | all | safe | 登録するティアを指定します。all では、unsafe ティアの hs_eval、hs_applescript、hs_ui_press が追加されます。 |
HS_MCP_TRANSPORT | socket | spawn | socket | Lua から Hammerspoon に接続する方法です。永続的なUnixソケット(約10倍高速で、初回呼び出し時に自動でセットアップされ、必要に応じて自動的にspawnにフォールバック)か、呼び出しごとに1つの hs プロセスを起動します。 |
HS_MCP_HS_PATH | 絶対パス | 自動検出 | hs バイナリへのパスです。通常とは異なる場所にインストールした場合に設定します。 |
HS_MCP_DOCS_PATH | 絶対パス | アプリバンドルから取得 | hs_api_search で使用する、Hammerspoon に同梱されたAPIドキュメントJSONへのパスです。 |
HS_MCP_LOG_LEVEL | debug | info | warn | error | info | stderrログの詳細度です。プロトコルを運ぶstdoutにはログを出力しません。 |
HS_MCP_TOOLS に認識されない値を指定すると、警告を大きく出して safe にフォールバックします。
より広いティアにフォールバックすることはありません。入力ミスによって利用制限付きのツールが使えなくなる
ことはありますが、使えるようになることはありません。hs パスのデフォルト値を決める検出順序については、
docs/ARCHITECTURE.md を参照してください。
セキュリティ
HS_MCP_TOOLS=all を設定する前に、このセクションをお読みください。
サーバーの実行場所
サーバーはローカルプロセスです。MCP クライアントが起動し、stdio 経由で通信します。 サーバーはユーザーアカウントで実行されます。ネットワークリスナーもリモートからアクセスできる インターフェースもありません。
つまり、サーバーはユーザーの権限も継承します。Hammerspoon はアクセシビリティなどの macOS TCC (Transparency, Consent, and Control)権限を保持し、画面収録やオートメーションの権限も保持している 場合があります。Hammerspoon 内で実行されるものはすべて、それらの権限を使って動作します。このサーバーが 権限を追加することはなく、取り消すこともできません。
実際の脅威モデル
リスクは、あなたが信頼できないことではありません。リスクはプロンプトインジェクションです。
エージェントは、ウェブページ、README ファイル、イシュー本文、ログ行、ほかのツールの出力など、常に信頼できないテキストを読み取ります。そうしたテキストには、どれも指示が含まれている可能性があります。エージェントがそれに従うこともあります。これは仮定の話ではなく、解決もされていません。
したがって、すべてのツールについて問うべきなのは、エージェントが説得されてこれを呼び出した場合、どれほど深刻なことになるかです。
- 厳選された動詞の影響範囲は小さく抑えられます。
hs_move_windowの場合、最悪でもウィンドウが間違った場所に移動する程度です。迷惑ではありますが、元に戻せて、目にも見えます。 - 任意の Lua には影響範囲の上限がありません。Hammerspoon の Lua は、シェルコマンドの実行、クリップボードの読み取り、画面のキャプチャ、キー入力の監視、ネットワークリクエストの送信ができます。インジェクションが一度成功すれば、気付かれないままマシンを完全に制御されます。
この差こそが、階層を設けている理由です。
HS_MCP_TOOLS=all が意味すること
これを設定すると、hs_eval、hs_applescript、hs_ui_press が登録されます。その時点から、エージェントはあなたのアクセシビリティ権限を持つプロセス内で、自分が書けるあらゆる Lua や AppleScript を実行し、UI 要素を押せるようになります。画面とキーボードも使えるシェルを渡すようなものだと考えてください。
これは実際に役立つモードです。エージェントがスニペットを直接試せると、Hammerspoon の設定の作成やデバッグがずっと速くなります。自分で見守っているセッションで、依頼した作業に使い、終わったら無効にしてください。ウェブを閲覧する長時間稼働中のエージェントや、無人のエージェントでは有効にしたままにしないでください。
デフォルトで安全というのは、危険なツールをあなたが使いこなせないという主張ではありません。有効にするのは、特定の日に、特定の理由があって、自分で意図的に決めるべきだという主張です。
あえて含めていないもの
これらは見落としではありません。理由のある拒否です。
- 生のシェル実行。 エージェントにはすでに、各ホスト側でサンドボックス化され、監査されるシェルツールがあります。Mac 制御サーバーが、二つ目の、しかも劣るシェルになる必要はありません。
- キー入力やクリックの合成。 たまたまフォーカスされているウィンドウに合成入力を行うのは、余計な手順を加えた任意のコード実行です。そのウィンドウがターミナルなら、「このテキストを入力」と「このコマンドを実行」は同じ操作です。
- クリップボードの読み取り。 クリップボードには、パスワード、トークン、プライベートメッセージが入っています。コピーしてから数秒以内に入っていることもよくあります。クリップボードを読み取るツールは、最も機密性の高い短期間だけ存在するデータを狙う情報窃取の手段です。
- スクリーンショット。 理由は同じです。画面キャプチャには、エージェントに尋ねていないウィンドウも含め、画面に表示されているすべてのものが写ります。
これらの一部は、後日それぞれ明示的なオプトインの設定を設けて復活する可能性があります。現在の hs_eval と同じ方式です。いずれもデフォルトの階層に含まれることはありません。
脆弱性の報告
公開イシューではなく、リポジトリで セキュリティアドバイザリ を作成してください。
知っておくべきこと:呼び出しはキューに入ります
Hammerspoon は単一スレッドで Lua を実行するため、呼び出しがいくつ届いても、一度に一つだけ実行します。測定結果では、400ms の呼び出しを4つ同時に発行すると、417ms ではなく1629msかかります。
サーバーはそれに応じて、同時に4件までキューに入れます。これは理由もなく設けた制限ではありません。制限を設けないと、同時呼び出しは単に待たされるだけでなく、失敗し始めます(テストでは15件中5件が成功)。また、このパターンにより、Hammerspoon は自身の IPC レイヤー内で2回クラッシュしました。
実際の影響として、キューは一つしかないため、遅いツールがほかのツールをブロックします。何かが止まっているように感じたら、たいていは一つの呼び出しがキューを占有しています。 ARCHITECTURE.mdに測定結果があります。
トラブルシューティング
まずは hs_health を実行してください。次のどの状態に該当するかを確認できるように設計されています。
hs が見つからない。 サーバーは決められた場所を検索し、その後 PATH を検索します。Hammerspoon が別の場所にある場合は、HS_MCP_HS_PATH にバイナリの絶対パスを設定してください。GUI から起動した MCP クライアントの PATH は、Homebrew が含まれない最小限のものになっていることがよくあります。そのため、ターミナルで動作するパスがサーバーでは機能しない場合があります。迷った場合は、この環境変数を設定してください。
Hammerspoon が実行されていない。 hs CLI はクライアントです。通信先となる Hammerspoon アプリが実行されている必要があります。Hammerspoon を起動して、もう一度試してください。
hs.ipc が読み込まれていない。 Hammerspoon は実行されていますが応答がないか、hs バイナリが存在しません。どちらの場合も、通常は ~/.hammerspoon/init.lua に require("hs.ipc") がありません。これを追加し、メニューバーアイコンから設定を再読み込みしてから、ターミナルで hs -c "return 1 + 1" を確認してください。
クライアントの一覧にツールが表示されない。 見つからないのが hs_eval の場合、デフォルトの階層が意図どおりに機能しています。クライアントのサーバー設定で HS_MCP_TOOLS=all を設定し、新しい環境変数でサーバーが再起動されるようにクライアントを再起動してください。
ツールがタイムアウトする。 Hammerspoon はシングルスレッドです。設定がループで停止している場合や、モーダルダイアログが処理をブロックしている場合、呼び出しは返ってきません。hs_console_tail でコンソールを確認するか、設定を再読み込みしてください。
開発
git clone https://github.com/vukvukovich/hammerspoon-mcp.git
cd hammerspoon-mcp
npm install
| スクリプト | 説明 |
|---|---|
npm run build | tsc で TypeScript をコンパイルして dist/ に出力します。 |
npm run typecheck | 出力せずに、すべての型をチェックします。 |
npm run lint | ESLint を実行します。 |
npm run lint:fix | ESLint を自動修正付きで実行します。 |
npm run format | Prettier で整形し、変更を書き込みます。 |
npm run format:check | Prettier で整形をチェックするだけです。 |
npm test | ユニットテスト(Vitest)を実行します。 |
npm run test:watch | ユニットテストをウォッチモードで実行します。 |
npm run test:coverage | カバレッジ付きでユニットテストを実行します。 |
npm run test:integration | 統合テストを実行します。実際に起動している Hammerspoon が必要です。 |
npm run check | CI で実行されるすべてのチェックを行います:型チェック、Lint、整形、テスト。 |
技術スタック:strict モードの TypeScript 5.9、ESM のみ、Node 24 以降、@modelcontextprotocol/server v2 SDK、スキーマ用の Zod v4、Vitest 4、Prettier 3 と併用する typescript-eslint 8。ビルドには通常の tsc を使い、バンドラーは使用しません。
コントリビューションの前に、CONVENTIONS.md(必須ルール)と CONTRIBUTING.md(ワークフローとコミット形式)をお読みください。設計については docs/ARCHITECTURE.md にまとめています。
ライセンス
MIT。Copyright (c) 2026 Vuk Vukovich。LICENSE を参照してください。
Hammerspoon は独立したプロジェクトであり、独自のライセンスを持ち、このプロジェクトとは提携していません。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。