flutter-mcp-boundary-audit について
ツール定義、検出、検証、実行の境界におけるスキーマの整合性を監査する、リポジトリ非依存のスキルです。MCP、RPC、プラグイン、API 契約の実装を保守し、公開スキーマと実行時の挙動の差を調べる人を対象とします。
主な機能
- 01各段階のスキーマ追跡
- 02一覧と呼び出し経路の比較
- 03各ゲートウェイの検証確認
- 04スキーマ移行と型変換の監査
- 05再現可能な所見と証拠の提示
活用シーン
- 01ゲートウェイ間のスキーマ変更のレビュー
- 02一覧と実行時検証の差の発見
- 03移行ツールによるスキーマ保持の確認
- 04統合テストでの厳格な入力処理の検証
MCP 対応
MCP スタックでは、MCP の一覧、レジストリ、ゲートウェイ、呼び出し経路にまたがるツールスキーマを監査し、公開契約と実行時検証の一致を確認します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ arenukvern/ mcp_flutter --skill flutter-mcp-boundary-auditインストール後、Claude Code で/flutter-mcp-boundary-auditを入力して読み込まれたか確認します。
同梱ファイルreference.md
詳細
契約境界の監査
スキル ID:
flutter-mcp-boundary-audit— 名前は歴史的なもので、内容はリポジトリに依存しません。同じワークフローは、MCP スタック、RPC ゲートウェイ、プラグインレジストリ、OpenAPI 形式の契約にも適用できます。
mcp_flutter では、このスキルを使って Flutter アダプターのパリティを監査します。
fmt_* カタログスキーマ、CLI の exec、VM サービス拡張ゲートウェイ、動的
ディスカバリー、マイグレーター、コンシューマー向けプラットフォームドキュメントが対象です。
アプリのディスカバリーや Flutter ブリッジを変更する場合はここで対応し、正規の IntentCall レジストリ/セッションのセマンティクス、
スキーマポリシー、プラットフォームへのプロジェクション、公開動作を変更する場合は上流で対応してください。
スプリットブレインのバグを見つけます。つまり、クライアントがリスト、カタログ、ドキュメントで確認できる内容と、呼び出し時にランタイムが適用する内容が異なる、または検証が一部のゲートウェイにしか存在しないバグです。
よくある症状:
- 公開されている
requiredフィールドと、呼び出しが受け付ける内容が異なる(空のペイロードで成功する、誤ったキーが無視される) - ホスト/カタログ経由では検証されるが、プロセス内または拡張経由では検証されない(またはその逆)
- マイグレーターまたはコード生成が、空または制限の緩いスキーマのプレースホルダーでエントリーを書き換える
- 同じ論理機能が異なるスキーマで二重に登録されている(リスト表示と呼び出し、または経路 A と経路 B)
- コードはフェイルクローズなのに、ドキュメントに「常に制限なし」または「検証なし」と古い記述が残っている
実行するタイミング
| トリガー(一般) | 監査の焦点 |
|---|---|
| ツール/ハンドラーの作成、登録時のスキーマ設定 | 作成からディスカバリーペイロードまで |
| アプリ/ランタイム側での動的登録またはプラグイン登録 | ランタイムでハンドラー実行前に検証 |
サーバーレジストリ、転送/ディスパッチ、カタログの *_client_tool ヘルパー | レジストリのリスト表示と呼び出し |
| ランタイムへの委譲前のホストゲートウェイ(VM 拡張、IPC、HTTP プロキシ) | ホストで委譲前に検証し、スキーマがない場合はフェイルクローズ |
プロセス内の呼び出し(invokeDirect、ブラウザーフック、組み込みブリッジ) | リスト表示と同じスキーマを使用し、実行前に検証 |
| アノテーション付きソースからのエントリーマイグレーター/コード生成 | 制限の緩いフォールバックではなく、スキーマを保持 |
| 共有スキーマモジュールと重複した定義 | 二経路間のパリティ |
| ブリッジハンドラー、非スカラー引数 | エンコーディング(JSON、protobuf など)とハンドラーの期待値 |
| プラットフォーム/ADR/登録に関するドキュメント | 古い記述とコードの相違 |
複数のゲートウェイが同じ論理ツールを利用する場合、JSON Schema、OpenAPI のリクエストボディ、protobuf の RPC メッセージ、またはプラグインマニフェストの入力形状を変更した後にも実行してください。
境界チェックリスト
変更を加えたすべてのツールまたは RPC について、作成 → 検出 → 検証 → 実行の流れを追跡してください。
| ステップ | 確認事項 | 確認場所(リポジトリ内) |
|---|---|---|
| 作成 | 正規の入力スキーマが、ツールキットやブリッジのラッパーで破棄されることなく、登録/記述子の型に引き継がれていますか? | 作成レイヤー/エントリーモデル/コードジェネレーターの出力 |
| 作成 | ブリッジツールは、レガシーハンドラー向けに非スカラー引数を一貫した形式でエンコードしていますか? | ブリッジヘルパー、アダプターレイヤー |
| 検出 | 動的登録で完全な inputSchema が送信されていますか({} や暗黙の any ではありませんか)? | アプリ登録 API、マニフェスト出力機能 |
| 検出 | ホストのツール一覧/カタログに、ランタイムレジストリと同じスキーマが公開されていますか? | ツール一覧ハンドラーとアプリ登録の比較 |
| サーバーレジストリ | レジストリの意図/メタデータでは、許容的なプレースホルダーではなく、実際のスキーマが使われていますか? | レジストリビルダー、MCP ツール → 意図のマッピング |
| 検証(レジストリ) | 転送/ディスパッチで、execute の前に検証が呼び出されていますか? | レジストリの転送パス |
| 検証(ホストゲートウェイ) | ホストゲートウェイは委譲の前に検証していますか? スキーマがない場合はフェイルクローズしますか? | ゲートウェイの実装 |
| 検証(ランタイム) | ランタイムコールバックはハンドラーの前に検証していますか? | サービス拡張機能/インプロセスフック |
| 検証(ワイヤー) | ワイヤー引数が文字列/マップの場合、ワイヤー形式を受け取る経路では、厳密な検証の前に型変換が適用されていますか? | 型変換モジュールとホスト専用の型付き JSON |
| 検証(インプロセス) | 直接呼び出しでは、execute の前に検証していますか? | インプロセスのエントリー呼び出し |
| 検証(CLI) | CLI の exec/カタログコマンドでは、MCP の一覧表示と同じスキーマを使っていますか? | CLI ディスパッチとサーバーツールの比較 |
| 実行 | 本番コードに、先行する validate なしで実行される .execute(/ハンドラーディスパッチはありますか? | grep(以下を参照) |
| マイグレーター | 移行処理で、ソーススキーマのプリミティブ型/必須項目/additionalProperties が保持されていますか? | マイグレーター、コード生成 |
| ドキュメント | プラットフォーム/登録に関するドキュメントは、実際のフェイルクローズ動作と一致していますか? | プラットフォームのドキュメント、ADR |
ゲートウェイの差異
同じ論理ツールでも、異なるゲートウェイを経由する場合があります。それぞれでスキーマと検証の順序が一致している必要があります。
Authoring (entry / descriptor)
├─► Runtime registration ──► extension/callback ──► handler
├─► In-process register (WebMCP / embedded) ──► invokeDirect
└─► Host list/catalog ──► catalog invoke ──► host gateway ──► runtime
| ゲートウェイの役割 | 先に検証する対象 | スキーマがない場合は失敗するか? |
|---|---|---|
| ランタイムコールバック(拡張機能、プラグインフック) | ハンドラー | はい(本番ツール) |
| レジストリ転送 | execute/ハンドラー | はい |
| ホストゲートウェイ(ランタイムへのプロキシ) | 委譲呼び出し | はい |
| インプロセス呼び出し | execute | はい |
| カタログ/fmt_*/CLI ラッパー | ランタイムへの転送 | はい(一覧表示と同じ) |
CLI の exec | コマンドディスパッチ | はい |
**要注意:**検証がテスト内だけ、カタログ経路だけ、または一覧表示だけで行われていて、変更が実際に使う経路では行われていない場合です。
ワイヤー型変換(該当する場合)
スタックによっては、ワイヤー上で文字列キーのマップが渡されます(VM サービス拡張機能、型指定が緩い JSON-RPC)。次の役割を分けて考えてください。
| 仕組み | 役割 |
|---|---|
| スキーマ用の型変換 | 厳密なスキーマ検証の前に、ワイヤー上の文字列からプロパティ型に変換 |
| ハンドラー側のワイヤーパーサー | ハンドラーが引き続き生のワイヤーマップを読み取る場合に任意で使用 |
| ワイヤーへの送信エンコード | ハンドラー引数 → ワイヤーで安全に扱える表現 |
一方にだけ型変換を追加した場合は、ホストゲートウェイとランタイムコールバックを再監査してください。型付き JSON を前提とするホストは、ランタイムで既に型変換済みだと思い込んではいけません(逆も同様です)。
デュアルパスの整合性
論理的な機能が二重に存在することはよくあります。
| パス | 一般的な役割 | 一覧表示/呼び出し |
|---|---|---|
| ランタイム/アプリの動的パス | 実行中のアプリまたはプラグインホストに登録される | 拡張機能名、動的レジストリ |
| ホストカタログ | サーバー側の MCP ツール、CLI エイリアス、OpenAPI ルート | ワイヤー上のプレフィックス付きまたはプレフィックスなしの名前 |
共有ツールごとに、以下を比較します。
requiredキーadditionalProperties: false(または同等の厳格さ)- ホスト専用フィールド(例:
connection)が片方のパスにのみ存在するか - プロパティの型/列挙値
- デフォルト値と型変換の動作
意図的な差異は、プラットフォーム契約ドキュメントに記載します(テストだけに記載しないでください)。
危険パターンの grep
リポジトリのルートから実行します。使用言語とパッケージ構成に合わせて glob を調整してください。
# Empty or permissive advertised schemas (JSON Schema style)
rg "inputSchema:\s*const\s*\{\s*'type':\s*'object'" --glob "*.dart" -g '!test/fixtures/**' -g '!**/after_*.dart'
rg '"type"\s*:\s*"object"\s*,\s*\}' --glob "*.{dart,ts,js,json,yaml}"
rg "_emptyObjectSchema|additionalProperties:\s*true" --glob "*.{dart,ts,js}"
# OpenAPI / generic permissive bodies
rg "additionalProperties:\s*true" --glob "*.{yaml,yml,json}"
rg "schema:\s*\{\s*\}" --glob "*.{yaml,yml}"
# Execute without validate (review each hit; exclude tests/fixtures)
rg "\.execute\(" --glob "*.{dart,ts,js}" | rg -v "validate|test/|_test\.|\.test\."
# Direct invoke bypass
rg "invokeDirect|invoke_direct|directInvoke" --glob "*.{dart,ts,js}"
# Manual review: validate appears before execute on each path
# Permissive registry placeholders
rg "emptyObjectSchema|empty_object_schema|placeholder.*schema|inputSchemaFrom" --glob "*.{dart,ts,js}"
# Migrator stripping schemas
rg "inputSchema|input_schema" --glob "*migrate*"
# Duplicate registration (e.g. JS + native)
rg "registerTool|register_tool" --glob "*.{dart,ts,js}"
# Stale “always permissive” docs
rg -i "permissive|additionalProperties:\s*true|no validation|accepts anything" --glob "*.md"
# Bridge / JSON args
rg "jsonEncode|JSON\.encode|serialize.*argument" --glob "*{bridge,entry,adapter}*"
リポジトリへの適応を完了した後、プロジェクト固有のパターンを追加します。
E2E の証明
一覧表示と無効な呼び出しを対象とする統合テストを実行します(特定のアプリパスに限定しません)。
チェックリスト:
- ツール/リソースの一覧表示(または OpenAPI GET)で、意図した箇所に
requiredと厳格なadditionalPropertiesが示される。 requiredが不足した状態で呼び出す → 構造化された失敗(ok: false、4xx、または検証エラー)となる。ハンドラーの副作用が発生する前に失敗すること。- スキーマが厳格な場合、余分なプロパティを指定して呼び出す → 同じ失敗モードとなる。
- デュアルパスが存在する場合、カタログとランタイム登録の両方の名前で再実行する。
任意:共有モジュールと重複定義を比較するスキーマ整合性の単体テスト(デバイスは不要)。
レポートテンプレート
## Finding: [title]
- **Severity**: P0 | P1 | P2
- **Boundary**: authoring | discovery | validation | execute
- **Gateway**: runtime-callback | registry | in-process | host-gateway | cli | migrator | docs
- **Files**: ...
- **Symptom**: clients/docs see X; runtime does Y
- **Fix**: ...
- **Proof**: test name or grep command
トラッカー(任意)
リポジトリで superpowers/tracker またはハードニングプログラムを使用している場合は、新しい調査結果をそこに記録するか、イシューとして登録します。回帰がない限り、完了済みの項目を再オープンしないでください。
リポジトリへの適応
監査の前に、このマップを埋めます(監査メモまたは PR の説明に記載してください)。
| 役割 | 該当箇所 | メモ |
|---|---|---|
| 作成 | 例:エントリーモデル、OpenAPI 仕様、@Tool アノテーション | 正規のスキーマが定義されている場所 |
| 検出 | 例:registerDynamics、プラグインマニフェスト、MCP tools/list | クライアントが読み取るもの |
| レジストリ/カタログ | 例:動的レジストリ、サーバーツールテーブル | 一覧表示と呼び出しのエントリーポイント |
| ホストゲートウェイ | 例:VM 拡張機能プロキシ、API ゲートウェイ、サイドカー | 委譲前に検証するか |
| ランタイムコールバック | 例:サービス拡張機能、プラグインホスト RPC | ハンドラーの前に検証するか |
| プロセス内呼び出し | 例:WebMCP、埋め込み JS ブリッジ | tools/list と同じか |
| CLI | 例:exec、プレフィックス付き/プレフィックスなしのエイリアス | MCP と同じスキーマか |
| 共有スキーマモジュール | 例:interaction_input_schemas、OpenAPI コンポーネント | 信頼できる唯一の情報源か |
| マイグレーター/コード生成 | 例:migrate agent-entries | required/properties を保持するか |
| プラットフォームドキュメント | 例:INTENTCALL_PLATFORM.md、README の契約セクション | フェイルクローズのコードと一致するか |
チェックリスト
- ツール登録パス(作成 → 検出)をマッピングする。
- 一覧表示のゲートウェイと呼び出しのゲートウェイをマッピングし、すべての中継点を列挙する。
- スキーマ表現(JSON Schema マップ、OpenAPI、protobuf、Dart
ObjectSchemaなど)をマッピングする。 - リポジトリ固有の危険パターンを 2~3 個追加する(寛容なプレースホルダー、呼び出しヘルパー名など)。
- デュアルパスのツールを特定し、共有モジュールまたは意図的な分割を記録する。
- 変更した各ゲートウェイで、厳格なツールを 1 つ選び、統合テストまたは手動検証を実行する。
詳細なリファレンス
実例(mcp_flutter)、ファイルマップ、回帰パターン:reference.md
関連スキル(mcp_flutter)
このモノレポ内で作業する場合のみ:
flutter-mcp-toolkit-custom-tools— エントリーの作成flutter-mcp-toolkit-intentcall-migration— agent-entries の移行flutter-mcp-toolkit-maintain-web— WebMCP/プロセス内呼び出しflutter-mcp-cli-runtime-validation— ランタイムの validate-runtime