KeyboardExtAX について
KeyboardExtAXは、Simulatorで起動中のサードパーティ製iOSキーボードのアクセシビリティツリーを読み取り、論理座標付きのJSONスナップショットを返します。キーボード情報を必要とする自動化向けで、観察専用のためジェスチャーは実行しません。
主な機能
- 01読み取り専用のキーボードアクセシビリティスナップショット
- 02要素情報と論理タップ座標
- 03シミュレーターごとの常駐XCTestランナー
- 04CLIとstdio MCPインターフェース
- 05構造化エラーと詳細診断情報
活用シーン
- 01Simulator上のカスタムキーボードの操作要素を確認
- 02キー座標を別のジェスチャーツールに渡す
- 03スクリーンショットなしでキーボードの情報を取得
MCP 対応
stdio MCPサーバーはkeyboard_snapshotツールを公開します。CLIと同じコントローラーを呼び出し、構造化されたスナップショットを返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx keyboard-ext-axDEVELOPER_DIROptional path to the Xcode Developer directory used to build and run the XCTest harness.KEYBOARD_EXT_AX_CACHE_DIRシークレットOptional cache directory for shared build products and per-simulator runner state.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
KeyboardExtAX

Simulator で実行中のサードパーティ製 iOS キーボード拡張機能の、高速で読み取り専用のアクセシビリティスナップショットを取得します。
このプロジェクトが作られた理由
カスタム iOS キーボードは、独立したアプリ拡張機能プロセスで実行されます。クライアントアプリがそのキーボードを表示すると、通常の UI 自動化では、クライアントアプリのアクセシビリティツリーは認識できても、キーボードの有用な子孫要素は認識できないことがほとんどです。キーボード全体が不透明な 1 つの要素として表示される場合もあります。
その結果、実用上の自動化には次のようなギャップが生じます。
- スクリーンショットでキーボードは確認できますが、ピクセルから信頼できるタップ座標を抽出するには時間がかかり、壊れやすくなります;
- クライアントアプリのアクセシビリティスナップショットでは、拡張機能のキーやコントロールが公開されないことがあります;
- クエリのたびに新しい XCTest セッションを開始するにはコストがかかり、キーボードのフォーカスを乱す可能性があります;
- キーボードのレイアウトが変わるたびに、XCTest の要素ハンドルは古くなります;
- 自動化エージェントがテストプラン、ポート、ビルド成果物、ランナープロセスを管理する必要はありません。
KeyboardExtAX はこのギャップを埋めます。バンドル識別子を使って、すでに実行中のキーボード拡張機能に XCTest を直接接続し、アクセシビリティ階層を解析して、絶対論理座標を含むプレーンな JSON を返します。永続的なランナーによってウォーム状態のスナップショットを高速に取得でき、小規模なコントローラーがビルド、キャッシュ、ポート、シミュレーターごとのライフサイクルを管理します。
KeyboardExtAX は読み取り専用です。アプリの起動、テキストフィールドへのフォーカス、返された座標を使ったジェスチャーの実行には、XcodeBuildMCP などの別の自動化ツールを使用してください。
クイックスタート:MCP
keyboard-ext-ax-mcp を stdio MCP サーバーとして設定します。多くの MCP クライアントでは、次のような形式の設定を使用します。
{
"mcpServers": {
"KeyboardExtAX": {
"command": "keyboard-ext-ax-mcp",
"env": {
"DEVELOPER_DIR": "/Applications/Xcode.app/Contents/Developer"
}
}
}
}
MCP クライアントがシェルの PATH を引き継がない場合は、command -v keyboard-ext-ax-mcp で表示される絶対パスにコマンドを置き換えてください。
サーバーは 1 つのツールを公開します。
keyboard_snapshot(
simulator_id: "<SIMULATOR_UDID>",
extension_bundle_id: "com.example.keyboard.extension",
raw: false
)
入力例:
{
"simulator_id": "2D78332B-A3C3-4CEE-962B-99EF531FD201",
"extension_bundle_id": "com.example.keyboard.extension"
}
結果は構造化された MCP コンテンツとして返されます。MCP レイヤーは CLI と同じコントローラーに直接処理を委譲するため、ビルドキャッシュ、セッション、エラー、出力は同一です。
クイックスタート:CLI
クライアントのテキストフィールドにフォーカスし、指定したキーボードが表示された状態で実行します。
keyboard-ext-ax snapshot \
--simulator <SIMULATOR_UDID> \
--extension com.example.keyboard.extension
結果をファイルに書き込むには --output /tmp/keyboard.json を追加します。ネストされたツリーと XCTest の診断情報を取得するには --raw を追加します。
対応範囲と制限事項
KeyboardExtAX は現在、次に対応しています。
- macOS ホスト;
- iOS Simulator;
- サードパーティ製キーボード拡張機能;
- Xcode 26.5;
- 読み取り専用のアクセシビリティスナップショット。
次の機能には対応していません。
- タップ、スワイプ、文字入力;
- クライアントアプリの起動または前面への表示;
- ユーザーに代わってキーボードを選択または有効化すること;
- 物理 iOS デバイスへのアクセス;
- ウィジェット、Live Activities、その他の拡張機能タイプとの互換性の保証;
- テストしていない Xcode バージョンでのパーサー互換性の保証。
パーサーは XCUIApplication.debugDescription を読み取ります。そのテキスト形式には、文書化された互換性の保証がないため、対応を表明する前に各 Xcode バージョンで検証する必要があります。
要件
- macOS
- 目的の iOS Simulator ランタイムをインストールした Xcode 26.5
- Python 3.10 以降
- 対象のシミュレーターにキーボードアプリと拡張機能がインストール済みであること
- 設定 → 一般 → キーボード → キーボードでキーボードが有効になっていること
- テキストフィールドにフォーカスした前面のクライアントアプリ
Xcode が複数インストールされている場合は、DEVELOPER_DIR または --developer-dir で使用するものを選択します。
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
インストール
Homebrew(推奨)
brew install nikitosina/tap/keyboard-ext-ax
uv を使った PyPI からのインストール
両方の実行ファイルを恒久的にインストールします。
uv tool install keyboard-ext-ax
または、永続的にインストールせずに MCP サーバーを実行します。
uvx keyboard-ext-ax mcp
ソースからのインストール
git clone https://github.com/Nikitosina/KeyboardExtAX.git
cd KeyboardExtAX
python3 -m venv .venv
.venv/bin/python -m pip install -e .
source .venv/bin/activate
どの方法でインストールしても、keyboard-ext-ax と keyboard-ext-ax-mcp が利用できます。MCP サーバーは keyboard-ext-ax-mcp または keyboard-ext-ax mcp で起動できます。
同梱の Xcode プロジェクトは、そのまま使用できます。XcodeGen が必要なのは、keyboard_ext_ax/harness/project.yml を変更する場合のみです。
出力
デフォルトの応答は、コンパクトなフラット配列です。
{
"ok": true,
"snapshot_id": "9543E2AA-C4D9-4281-9645-7792F7953FE3",
"simulator_udid": "2D78332B-A3C3-4CEE-962B-99EF531FD201",
"extension_bundle_id": "com.example.keyboard.extension",
"pid": 12345,
"elapsed_ms": 103.4,
"round_trip_ms": 106.1,
"session_reused": true,
"total_ms": 171.8,
"elements": [
{
"ref": "0.0.3",
"type": "Key",
"identifier": "space",
"label": "Space",
"frame": {
"x": 112,
"y": 746,
"width": 178,
"height": 44
},
"center": {
"x": 201,
"y": 768
},
"tap_x": 201,
"tap_y": 768
}
]
}
要素のフィールド
| フィールド | 意味 |
|---|---|
ref | このスナップショット内でのみ有効な安定したパスです。レイアウトを変更した場合は更新してください。 |
type | XCTest のアクセシビリティ要素のタイプです。 |
identifier | 拡張機能から提供される場合のアクセシビリティ識別子です。 |
label | 拡張機能から提供される場合のアクセシビリティラベルです。 |
frame | Simulator 座標での絶対論理フレームです。 |
center | フレーム中心の正確な浮動小数点座標です。 |
tap_x, tap_y | ジェスチャーツールですぐに使える、中心を丸めた整数座標です。 |
座標はスクリーンショットのピクセルではなく、Simulator の論理座標です。同じシミュレーターで使用する場合は、XcodeBuildMCP に渡す前に拡大縮小しないでください。
セッション管理
keyboard-ext-ax status
keyboard-ext-ax status --simulator <SIMULATOR_UDID>
keyboard-ext-ax stop --simulator <SIMULATOR_UDID>
keyboard-ext-ax stop --all
シミュレーターごとに 1 つのランナーを維持します。複数のシミュレーターには同時に問い合わせることができます。再利用されたランナーが拡張機能プロセスを失った場合、KeyboardExtAX はランナーを 1 回再利用し、client_refocus_required を返します。
エラー
エラーは、安定したコードを持つ JSON オブジェクトです。
| コード | 意味 | 対処方法 |
|---|---|---|
client_refocus_required | 新しいランナーまたは再起動されたランナーの準備ができています。 | クライアントのテキストフィールドにフォーカスし直して、リクエストを繰り返してください。 |
extension_not_active | 3 回試行しても XCTest をアタッチできませんでした。 | システムキーボードではなく、指定した拡張機能が表示されていることを確認してから、再試行してください。 |
runner_start_failed | 永続的な XCTest ランナーの準備ができませんでした。 | 返された log と log_tail を確認してください。 |
build_failed | XCTest ハーネスのビルドに失敗しました。 | 返されたビルドログを確認し、選択されている Xcode を検証してください。 |
xcode_unavailable | Xcode を検出または照会できませんでした。 | DEVELOPER_DIR を設定するか、--developer-dir を渡してください。 |
extension_bundle_id_missing | ランナーに拡張機能の識別子が渡されませんでした。 | extension_bundle_id を指定してください。 |
snapshot_failed | XCTest で予期しないスナップショットエラーが発生しました。 | raw: true を指定して再試行し、診断情報を確認してください。 |
CLI の終了コードは次のとおりです。
- 成功時は
0。 - 拡張機能が非アクティブである場合など、通常のスナップショット状態エラーでは
2。 - ライフサイクル、ビルド、またはコントローラーの障害では
1。
アーキテクチャ
MCP client / CLI
│
▼
KeyboardExtAXController
├─ build cache
├─ per-simulator lock and state
├─ free-port allocation
└─ XCTest runner lifecycle
│ JSON over loopback TCP
▼
PersistentKeyboardExtAXTests
│ XCUIApplication(bundleIdentifier:)
▼
Active keyboard extension process
│
▼
Parsed tree → compact elements → MCP/CLI JSON
このリポジトリに含まれるホストアプリは、XCTest の足場です。スナップショットモードではホストアプリを起動せず、利用側のフォアグラウンドクライアントアプリに置き換わることもありません。
ライセンス
KeyboardExtAX は MIT License の下で利用できます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。