mcpField
V
Ventriloquist

Ventriloquist

ローカル
github.com/ShaanGS生産性2今日更新

Ventriloquist について

Ventriloquistは、macOSのアクセシビリティ操作を記録し、Macアプリ向けの型付きツールとしてAIエージェントに提供します。JSONパックに承認済みの手順を保存し、通常の呼び出しではスクリーンショットやモデルを使わずに再生します。

主な機能

  1. 01アクセシビリティAPI経由の操作記録
  2. 02JSONパックでの型付きツール作成
  3. 03アンカーに基づくスクリーンショット不要の再生
  4. 04TextEdit、Notes、VS Code、Slack用パック
  5. 05読み取り専用およびリスク制御

活用シーン

  1. 01Macアプリでの定型操作の自動化
  2. 02TextEdit文書の読み取りや更新
  3. 03VS Codeワークスペースの検索
  4. 04別のアプリ向けパックの作成と実行

MCP 対応

Ventriloquistは`vent serve`からstdio経由でMCPクライアントにアプリ用ツールを提供します。ツールと記録済み操作はパックで定義されます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"shaangs-ventriloquist": {
"command": "uvx",
"args": [
"ventriloquist-mcp"
],
"env": {
"VENT_ALLOW_HIGH": "<VENT_ALLOW_HIGH>",
"VENT_HEAL": "<VENT_HEAL>",
"VENT_HOME": "<VENT_HOME>",
"VENT_READ_ONLY": "<VENT_READ_ONLY>",
"VENT_NO_VALUES": "<VENT_NO_VALUES>"
}
}
}
}
起動コマンドuvx ventriloquist-mcp
設定が必要な環境変数
VENT_ALLOW_HIGHSet to 1 to run tools a pack marks as high risk without asking. Without it, they're offered only to clients that can ask you to confirm each call (MCP elicitation).
VENT_HEALSet to 1 to let the server call a model to re-ground broken anchors. Off keeps serving model-free.
VENT_HOMEDirectory for your own packs and traces. Defaults to ~/.ventriloquist.
VENT_READ_ONLYSet to 1 to serve read-only tools only. Every other call is refused, even with VENT_ALLOW_HIGH.
VENT_NO_VALUESSet to 1, together with VENT_HEAL=1, to keep field values out of what the healer sends to the model.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypiventriloquist-mcp0.3.1

ツール

10

掲載時のツール一覧 · 1 日前に更新

パラメーター型必須説明
bodystringはいメモの内容。1 行目がタイトルになります。

詳細

翻訳後に原文が更新されています。最新の内容は原文をご確認ください。

Ventriloquist のアイコン

Ventriloquist

Mac アプリを、AI エージェントが呼び出せる MCP ツールに変えます。
インストール · 仕組み · パック · セキュリティ

概要

Ventriloquist は、macOS のアクセシビリティ API を通じて Mac アプリを一度学習し、textedit_write_document や slack_filter_channels のような、役立つアクションを型付きツールとして維持します。エージェントは MCP 経由でそれらを呼び出し、呼び出すたびに記録された手順が再生されます。スクリーンショットも、ビジョンモデルも不要で、読み取りは約 85 ms です。どのツールを呼び出すかは、引き続きエージェントが決めます。どこをクリックするかをエージェントが決めることはありません。

エージェントが vent のツールを呼び出します。VS Code で検索ビューを開いてリポジトリ内の refuse を検索し、その後 TextEdit にメモが表示されます。マウスに触れる人はいません。
実際の実行例です。各ツール呼び出しは実時間で再生され、呼び出しの合間のエージェントの待ち時間はカットされています。

1 分で試す

macOS と uv が必要です(brew install uv)。

uv tool install ventriloquist-mcp
vent doctor

vent doctor は、vent に必要な唯一の権限を確認します。アクセシビリティが許可されていないと表示された場合は、「システム設定」>「プライバシーとセキュリティ」>「アクセシビリティ」を開き、ターミナルアプリをオンにして、ターミナルを再起動してから、もう一度実行してください。(pipx install ventriloquist-mcp でもインストールできます。)

では、vent に同梱されているパックを使って TextEdit を操作してみましょう。

echo "hello" > /tmp/vent-demo.txt && open -a TextEdit /tmp/vent-demo.txt
vent run TextEdit write_document --arg text="typed by a pack"
vent run TextEdit read_document

キー入力もスクリーンショットも使わずに、書類が変更されます。パックはアクセシビリティ API を通じてテキスト領域の値を設定し、読み戻して検証します。write_document は最前面にある TextEdit 書類のテキスト全体を置き換えるため、最初の行で一時ファイルを開きます。大切な書類を開いた状態では実行しないでください。

Claude、Cursor、Codex から使用する

vent serve は stdio 経由で MCP を処理します。GUI アプリはシェルの PATH を使わずに MCP サーバーを起動するため、設定には vent の絶対パスが必要です。vent mcp-config を実行すると、お使いのマシンに適したパスを含むエントリが表示されます。

{
  "mcpServers": {
    "ventriloquist": {
      "command": "/Users/you/.local/bin/vent",
      "args": ["serve"]
    }
  }
}
  • Claude Desktop:Claude を終了してから、~/Library/Application Support/Claude/claude_desktop_config.json に設定をマージします。Claude の実行中はこのファイルが書き換えられるため、Claude を開いたまま編集すると変更が失われます。

  • Cursor:~/.cursor/mcp.json に設定をマージします。

  • Claude Code:claude mcp add --scope user ventriloquist -- ~/.local/bin/vent serve

  • Codex CLI:~/.codex/config.toml に追加します。

    [mcp_servers.ventriloquist]
    command = "/Users/you/.local/bin/vent"
    args = ["serve"]
    

アクセシビリティの許可は、vent serve を起動するアプリに付与します。Cursor を使う場合は Cursor 自体に、Claude Code や Codex の場合はターミナルに付与します。そのアプリの許可を有効にし(まだリストにない場合は + ボタンを使用します)、アプリを再起動してください。

Claude Desktop は例外です。権限管理のため、MCP サーバーごとに独立したプロセスとして実行するため、macOS は Claude ではなく vent の Python を確認します。そのため、Claude の許可を有効にしても vent には反映されません。vent mcp-config と vent doctor に、このファイルのパスが表示されます。Finder から「システム設定」>「プライバシーとセキュリティ」>「アクセシビリティ」にファイルをドラッグします(+ のファイル選択画面では選択できません)。その後、Claude を再起動してください。ここでは uvx ではなく、vent mcp-config のエントリを使用してください。uvx を使うと macOS は代わりに uv を確認し、uv に許可を付与すると、uv が実行するすべてのものに許可が適用されます。

呼び出しのたびに「not trusted for Accessibility」というエラーが表示される場合は、許可を有効にすべきアプリまたはファイルの名前がメッセージに示されます。

ツールは textedit_write_document、code_show_search、slack_filter_channels などの名前で表示されます。表示されたら、「VS Code で検索ビューを開き、ワークスペース内の TODO を検索して」のように、自然な言葉で依頼できます。パック内で risk: high と記されたものは、サーバーの起動時に VENT_ALLOW_HIGH=1 が設定されていない限り拒否されます。 docs/SECURITY.mdで、その理由を説明しています。

同梱内容

アプリツール備考
TextEditwrite_document、read_document最前面の書類を操作します。write_document は書類内のテキストをすべて置き換えます
Notescreate_note、read_open_note
VS Codeshow_explorer、show_search、show_source_control、search_workspace--force-renderer-accessibility を付けて VS Code を起動します
Slackshow_home、filter_channelsVS Code と同じフラグを使用します

VS Code や Slack などの Electron アプリは、このフラグを付けて起動した場合にのみ、操作可能なツリーを公開します。たとえば、open -a "Visual Studio Code" --args --force-renderer-accessibility のように起動します。付けずに起動してもツリーを読み取ることはできますが、操作は警告なく無視されます。

アンカーはマシンごと、アプリのバージョンごとに記録されるため、同梱パックは形式を示す動作例であり、お使いの環境での動作を保証するものではありません。ツールが要素を解決できない場合は、安全設計が機能しています(見た目が似た要素のどちらかを推測することはありません)。vent inspect と vent anchor を使えば、約 1 分で再記録できます。docs/ARCHITECTURE.md のセクション 5 を参照してください。

仕組み

アーキテクチャ

多くのコンピューター操作エージェントはインタープリターです。モデルが画面を見て、毎回すべてのクリックを決めるため、処理が遅く、コストが高く、予期しない形で失敗します。これは、そのコンパイラー版です。探索時に一度だけモデルのコストを支払うと、write_document(text) のようなツールが得られます。その後の呼び出しではモデルのトークンを消費せず、1 秒もかかりません。作者の Mac では読み取りに約 85 ms、書き込みに約 0.9 秒かかり、その大半はアプリが落ち着くのを待つ時間です。アプリのアップデートによって記録したアクションが機能しなくなると、モデルが呼び戻されて修正しますが、その修正は承認されるまで隔離されています。

図の上半分はアプリごとに一度実行される部分で、モデルが活躍します。すべてのプローブはポリシーによって審査され、すべてのツールは人間が承認します。下半分は日常的に実際に使う部分で、モデルは一切含まれていません。中央にあるパックファイルが両者をつなぐ唯一のインターフェースです。内容はプレーンな JSON なので、読み取りや差分の確認ができ、リポジトリにもチェックインできます。

Mac のネイティブアプリには、スクリーンリーダーが依存するアクセシビリティレイヤーが何十年も前から備わっています。要素を後で再び見つける方法に気をつければ、アプリを操作するための優れた API にもなることがわかりました。

比較

  • スクリーンショットによるコンピューター操作(Claude や Codex のコンピューター操作機能、およびほとんどのオープンソースエージェント):モデルが画面を見て、アクションを一つずつ選びます。どのアプリでも動作しますが、ステップごとにモデル呼び出しが発生します。
  • Peekaboo や MacOS-MCP などのアクセシビリティ MCP サーバー:アクセシビリティツリーとそのアクションをクライアントのモデルに渡しますが、モデルは呼び出しのたびにクリックを一つずつ決定します。事前に記録する必要はありませんが、何も固定されません。
  • AppleScript サーバー:スクリプティング辞書を備えたアプリでは信頼性がありますが、ほとんどの Electron アプリにはありません。
  • Ventriloquist:記録中にモデルが一度だけ処理します。提供されるのは、承認済みの固定されたツールセットで、モデルを使わずに再生されます。意図的に、上記のどの方法よりも対応アプリが少ない代わりに、呼び出しは低コストで高速であり、毎回同じように動作します。他に近い考え方のものとして、Windows でワークフローを決定論的なコードとして記録するterminatorがあります。

別のアプリ用のパックを作成する

vent doctor Spotify                 # does this app expose a usable tree?
vent explore Spotify --no-values    # a model probes safely, the policy screens every action
vent compile Spotify                # the model proposes tools; you approve each against its literal steps
vent run Spotify <tool> --arg k=v   # call one tool directly
vent verify Spotify                 # dry-resolve anchors; promote quarantined heals

vent explore、vent compile、vent run --heal はモデルを呼び出します。また、VENT_HEAL=1 を設定して壊れたアンカーを修復できるようにした場合は、vent serve もモデルを呼び出します。それ以外ではモデルは使われません。モデルには、インストール済みでサインインしている場合は API キー不要の Claude Code CLI が使われます。そうでない場合は Anthropic API が使われます。次のコマンドでインストールしてください。 uv tool install --with anthropic ventriloquist-mcp そして ANTHROPIC_API_KEY を設定してください。

作成したパックは、vent explore が記録するトレースと並んで ~/.ventriloquist/packs/ に保存されます(保存先を変更するには VENT_HOME を設定してください)。ここにあるパックは、同じアプリ用の同梱パックを置き換えます。修復された同梱パックもここに保存されます。自分のパックを削除すると、同梱パックに戻ります。

制限事項

これは開発者1人による初期リリースです。現時点でできないこと、または注意事項を伴うことは次のとおりです。

  • macOS のみです。 このアプローチ全体は macOS のアクセシビリティ API に依存しています。
  • アクセシビリティの許可範囲は広大です。 macOS は vent を起動したアプリ(ターミナル、Cursor など)、または Claude Desktop 経由の場合は vent の Python に許可を与えます。そのアプリが起動したものや、その Python 上で独自のプロセスとして動作するものは、Mac 上のあらゆるアプリを操作できるようになります。vent 独自のスコープ設定(アプリ名、ポリシー、リスクレベル)は、その許可範囲内での自主規制であり、OS の境界ではありません。詳しくは SECURITY.md T10 を参照してください。
  • パックは1台のマシンで記録されています。 作者の Mac では、ウィンドウのリサイズ、完全な再起動、意図的に劣化させた環境でもアンカーが機能しましたが、2台目の Mac で測定した人はいません。バンドルされたパックがお使いの環境では拒否され、再記録が必要になる場合があります。
  • アプリに利用可能なツリーが必要です。 AppKit アプリにはツリーがあります。Electron アプリと Chromium アプリには --force-renderer-accessibility が必要です。キャンバス上に描画されるもの(Figma のデザインサーフェス、ゲームなど)では、ウィンドウ枠しか公開されず、中身は何も公開されません。
  • アプリが起動しており、ツールが想定するウィンドウが開いている必要があります。 Notes、VS Code、Slack のツールは実行中にアプリを前面に表示し、終了後にフォーカスを戻します。画面がロックされていると、すべてのアプリが空に見えます。
  • 1つのアプリへの呼び出しは同時に1つずつ実行されます。 GUI は共有されるものなので、同じアプリへの並列呼び出しはキューに入ります。
  • 前提条件は文章で示されています。 VS Code の search_workspace には、まず検索ビューを開くよう記載されていますが、これを強制する仕組みはなく、準備なしで呼び出すと失敗します。状態を伴う前提条件への対応は今後の予定です。
  • 高リスクツールは全か無かです。 サーバーが VENT_ALLOW_HIGH=1 を指定して実行されていない場合、ツールは拒否されます。呼び出しごとの確認機能はまだ実装されていません。
  • 探索は実際のアプリに対して行われます。 エクスプローラーはポリシーに従ってクリックや入力を行い、プローブ後に元の状態へ戻しますが、すべてのキー入力を同期するアプリでは、プローブ文字列が取り消される前に送信される場合があります。スクラッチ文書またはテストアカウントで探索し、--no-values を使ってフィールドの内容がモデルに渡らないようにしてください。
  • vent compile はパックにマージせず、置き換えます。
  • 読み取りツールはアプリのテキストをクライアントのモデルに渡します。 vent はこれを信頼できないデータとしてマークします(SECURITY.md T12)。クライアントがその指定を尊重するかどうかは、クライアント次第です。
  • システムダイアログには対応していません。 ファイル選択ダイアログと保存シートは、現時点では対象外です。

アンカーの耐久性の測定

vent harness <app> はアプリの要素のアンカーを記録し、アプリに変更を加え(実際にウィンドウをリサイズし、オプションで完全に終了して再起動します)、その後すべてのアンカーを再度解決できるか試します。見つかった要素が記録された要素と同一であることを証明できた場合にのみ、アンカーが維持されたと見なします。よく似た別の要素に紐づいた場合は誤りとして数えます。実際に重要なのはこの数値です。

このマシンでの数値(macOS 26、小規模なアンカーセット、初期段階):

TextEdit: baseline 100%,  resized 100%,   0 wrong
Finder:   baseline 100%,  resized 100%,   0 wrong
VS Code:  baseline  95%,  resized  87.5%, restart 92.5%, 0 wrong  (40 anchors)
Slack:    baseline  95%,  resized  82.5%, restart 82.5%, 0 wrong  (40 anchors)

ここでは Slack が他のアプリよりも重要です。TextEdit と Finder には AppleScript があり、VS Code には CLI と拡張機能 API があるため、このプロジェクトを正当化するのはスクリプト用の仕組みがまったくないアプリであり、Slack はその中で最初に測定したアプリです。Slack のツリーにはどこにも識別子がないため、アンカーはラベルと祖先チェーンだけに完全に依存しますが、リサイズや完全な再起動の後も、誤った紐づけは一度もありません。維持されなかったものはすべて、曖昧さを理由に拒否されています。

Figma デスクトップは意図的に最悪のケースとして選ばれており、実際にそのとおりの動作をします。アプリのシェル(タブ、ナビゲーション、ボタン)は利用可能なツリーを公開しますが、デザインキャンバスはピクセルとしてレンダリングされるため、何も公開しません。これが、アクセシビリティという考え方が正直に示す限界です。コンテンツがカスタム描画のキャンバスであるアプリでは、ウィンドウ枠はスクリプトから操作できますが、コンテンツは不透明なままです。 VS Code の再起動ラウンドでは、アプリを完全に終了して再起動しますが、その後も 40 個中 37 個のアンカーが、証明可能なほど同じ要素に結び付きます。維持されないものは誤りではなく、拒否です。Chromium のツリーにはラベルのない同一要素のグループが数多くあり、候補 2 つのスコアが近すぎると、リゾルバーは一方を選ぶことを拒否します。VS Code パック独自の厳選されたアンカーは、ビューの切り替え、ウィンドウのサイズ変更、実際のアプリ更新を経ても 6 件中 6 件が維持されました。

アンカーごとの維持率は、呼び出し元が実際に体験することを実態以上に良く見せます。ツールは複数のアンカーに加え、安定化と検証も行うためです。そのため、ツール全体をエンドツーエンドで実行する、もう一つのハーネスモードがあります。 vent harness <app> --tools は、アプリのパックに含まれるすべてのツールを繰り返し実行し、2 サイクルごとにウィンドウのサイズを変更します。

TextEdit: 8/8 calls passed   (4 cycles)
VS Code:  12/16 calls passed (4 cycles, every failure the same tool)
Slack:    6/8 calls passed   (4 cycles, both failures ambiguity refusals)

Slack パックは意図的に最小限の構成です(ナビゲーションとパラメーター化されたサイドバーのフィルター)が、これは単なるアンカーの維持率ではなく、コンパイル済みの機能です。失敗した 2 件は、サイズ変更後にナビゲーションレールのレイアウトが変わり、Home タブに見た目の似た要素が現れたときに発生します。リゾルバーはどちらかを選ぶことを拒否します。安全な失敗ではありますが、失敗であることに変わりはありません。どのアプリでも、どのサイクルでも、誤った要素がクリックされることはありませんでした。

VS Code での失敗はすべて、起動直後に search_workspace を呼び出した場合に発生します。説明には、先に Search ビューを開くよう記載されていますが、この依存関係は説明文にあるだけで、機械的にチェックされる事前条件ではありません。そのため、これを無視した呼び出し元も、このハーネスも、意図どおり失敗します。失敗したすべての呼び出しで、アンカー自体には問題がありませんでした。アンカーごとの成功率 87.5% とツールごとの成功率 75% の差は、GUI における状態の正直な代償であり、状態を考慮した事前条件が今後の修正です。

もう一つ、最初のポータビリティデータがあります。2 台目のマシンではなく、意図的に条件を悪化させた環境での結果です。サイドバーを折りたたみ、すべてのファイルとフォルダーを閉じ、テーマを切り替え、拡張機能を無効にし、ウィンドウのサイズを変更した後、VS Code パックを再検証しました。3 つのアクティビティバーのアンカーは正確に解決され、それらの兄弟要素の構成を変える拡張機能の削除にも影響されませんでした。ビューが存在しなくなった 2 つのビューコンテンツのアンカーは、適切な方法で失敗しました。1 つはその場で拒否し、もう 1 つは同じロールを持つ隣接要素、つまり開いているエディターペインに結び付きましたが、意味的な差異チェックで検出されました。このニアミスを受けて、ランタイムルールを追加しました。アンカーが過去に記録されたことのないラベルを持つ要素には、決して操作を行いません。そのため、開いているエディターに入力してしまうはずだった呼び出しは、操作を拒否し、触れるのを避けた要素の名前を示します。この実行で確認できていないのは、マシン間のポータビリティです。同じマシン、アカウント、アプリのインストール環境での実行でした。実際のテストには vent verify <app> --report out.json を使います。モデルを呼び出さず、アプリの内容も各要素の現在のラベルに限った、小さな JSON の解決テーブルを生成します。他の人の Mac で実行し、結果を送り返してもらうことを想定しています。

実装に反映された現場での知見をいくつか挙げます。macOS の AX ツリーは循環することがあります(応答不能になった TextEdit が、アプリ要素を自身の子として返したことがありました。そのため、すべての走査で循環ガードを使用しています)。バックグラウンドプロセスから再起動したアプリは、実際にフォアグラウンドになるまでメニューバーだけの無効なツリーを返します。保留中の権限ダイアログがあると、その後に起動したすべてのアプリで AX が気付かれないまま劣化します。また、画面がロックされていると、権限チェックは通る一方で、すべてのアプリが空の状態として読み取られます。

設計

コードを読む前に docs/ARCHITECTURE.md を、脅威モデルについては docs/SECURITY.md を読んでください。どちらも実装前に敵対的レビューを受け、その結果を反映して書き直されました。それ以降の各フェーズでも、同じレビューを受けています。 docs/HANDOFF.md には、現在の状態と次の作業が記載されています。

コントリビューション

作者以外のMacからのバグ報告が、現在もっとも役立ちます。特に、バンドルされたパックに対する vent verify <app> --report out.json の出力があると助かります。コードに取り組む場合は、次の手順に従ってください。

git clone https://github.com/ShaanGS/ventriloquist && cd ventriloquist
python3 -m venv .venv && .venv/bin/pip install -e . pytest
.venv/bin/python -m pytest tests/

テストスイートの実行にMacの権限、実行中のアプリ、モデルの認証情報は必要ありません。また、LinuxとmacOSのCIで実行されます。 CONTRIBUTING.mdに、重要なルールが記載されています。

ライセンス

MIT

PyPI テスト Python バージョン Glama スコア

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。