mizulba
MCP ツール設計とAI向け品質改善
MCP サーバーの品質改善は入力品質ゲートを先に固める
約2か月前
MCP サーバーを配布対応する前に、ツールの入力品質ゲートをサーバー側へ寄せると、クライアント差異に左右されず品質を保ちやすい。特に知識保存系では、tool description、input schema、validation error に規約を埋め込み、prompt/resource は補助にする。ゲートは hard error、warning、normalized proposal に分けると、品質と UX を両立しやすい。
MCP ツール設計は API 境界より AI の判断境界を優先する
約2か月前
MCP ツールを設計するときは、HTTP API の CRUD 境界をそのまま露出するより、AI が安全に判断できる操作境界を優先する。read、write、delete は混ぜず、add/update の違いだけが迷いを生む場合は upsert 化する。一方で、異なる編集対象を巨大な manage ツールにまとめると入力設計の迷いが増えるため、対象ごとに意図ベースの少数ツールへ整理するのがよい。
MCP ツールの inputSchema は zod を単一の定義元にする
約2か月前
低レベルの MCP Server API ではツール一覧に JSON Schema が必要な場合でも、各ツールに手書き JSON Schema を分散させず、zod schema を単一の定義元にして登録時に JSON Schema へ変換すると保守しやすい。全ツールに生成 schema が存在することを起動時に検証すれば、手書き fallback への戻りや schema 漏れを早期に検出できる。
MCPツールの削除確認は登録元と周辺定義を分けて見る
約2か月前
MCPサーバーでツールを削除したか確認する際は、handlerディレクトリやtool.tsファイルの存在だけで判断せず、実際にListToolsへ渡す登録配列を一次情報として確認する。未登録のhandler、input schema、型、APIクライアント関数が残ると、公開ツールではなくても保守上は削除漏れに見えるため、登録元・schema・型・サービス関数をセットで棚卸しする。
MCPツールの網羅テストは登録一覧を単一の基準にする
約2か月前
MCPサーバーで全ツールのテストを追加する場合、各handlerの文言テストだけで網羅性を担保しようとすると保守負荷が高くなる。登録済みツール一覧を取得する関数を用意し、その一覧を基準にツール名、inputSchema生成、annotations、handlerファイルとの一致を検証すると、未登録ツールやschema漏れを低コストで検出できる。
MCPツール説明とstructuredContentは同時に整える
約2か月前
MCPツールのAIからの使いやすさを改善する場合、descriptionの意図ベース化とstructuredContentの標準化は同時に設計するとよい。descriptionはAIがツール選択するための情報、structuredContentは実行結果を後続処理で扱うための情報なので、read系は安定したキーで返し、write系も成功時にsuccess/action/対象IDや対象データを返すと判断と連携が安定する。
MCPの公開面はツール説明だけでなく全レスポンスを英語化する
約2か月前
MCPサーバーをディレクトリ掲載や複数AIクライアント向けに整える場合、tool description だけでなく inputSchema の説明、handler の成功・エラー文、README、setup 用スキル文面まで同じ言語に統一する。AI が読む schema とユーザーが見る text response の言語が混在すると、ツール選択や後続処理の一貫性が落ちるため、残存チェックをテストや grep で検出できるようにすると保守しやすい。
候補集合を渡す経路に汎用検索/一覧ツールを流用しない
約1か月前
エージェントやUIなどの消費者に「ある目的の候補集合」を渡したいとき、既存の汎用検索/一覧エンドポイントをそのまま流用したくなる。だが汎用検索を流用すると、そのツールが持つ3つの性質を一緒に背負う。
流用で背負う3つ
- デフォルト取得上限: 汎用検索はページング前提でデフォルト件数上限(例100)を持つ。全件が欲しい経路で流用すると黙って上限で頭打ちになる。
- 本文込みのペイロード: 一覧系はレコード本体(本文等の重いフィールド)を返すことが多く、候補一覧だけ欲しいのに本文の塊を転送する。
- softなフィルタ: 絞り込み条件を呼び出し側の指示(プロンプトやクエリ引数)に依存すると、呼び出し側が条件を忘れれば漏れる。公開/非公開やテナント境界など安全上絶対守りたい条件で特に危険。
判断基準
候補集合に次のいずれかが要るなら、汎用検索の流用でなく目的専用の索引取得を作る。
- 全件が要る(恣意的上限を置きたくない)→ 索引はid/title等の軽いキーだけにし本文を載せない。軽いので全件返しても安い。本文は索引から個別取得の二段でオンデマンドに取る。
- 条件を確実に守らせたい(公開のみ等)→ プロンプト遵守のsoftでなくクエリ側で強制するhardな専用経路にする。
- その目的だけの選別述語が汎用検索の一般パラメータとズレるなら、汎用側へフラグを増やさず目的専用クエリに分ける。
落とし穴
contextに本文を詰めないためにagentへ検索させるとしても、検索ツールが本文返却とデフォルト上限を持てば、バルク本文も恣意的上限も検索ツール側に隠れて残るだけで消えない。
検証
デフォルト上限を超える件数のデータを用意し、候補経路が全件返すか、索引ペイロードに本文が含まれないか、呼び出し側からフィルタを外してもクエリが除外を維持するかを確認する。
生成 JSON Schema と手書き schema を併用するなら入れ子も再帰 merge する
28日前
MCP ツールなどで zod 由来の生成 JSON Schema と handler 固有の手書き schema を合成する場合、トップレベルの properties だけを merge すると不十分。配列 item の object properties や nested object の中に handler 側だけで定義した項目があると、生成 schema 側の親 property が丸ごと勝って、その項目が公開 schema から消える。
判断基準
- 生成 schema を単一の定義元にしつつ、handler 固有の説明や追加 property を残す設計では、object の properties、array の items、required を再帰的に merge する。
- 同名 property は生成 schema を優先して型制約の正本を保ち、handler 側だけにある property は消さない。
- regression test はトップレベル property だけでなく、array item 内の nested property まで確認する。
検証
tools/list など実際にクライアントへ公開される schema を取得し、handler が受け付ける nested field が inputSchema にも出ているか確認する。単体テストだけでなく、起動済みサーバーの公開 schema を見ると、登録時の annotation や merge 処理の漏れを発見しやすい。
出力をローカライズする AI スキル/プロンプトは、定義と例を正準言語で統一し、出力言語は『ユーザーの言語で書け』指示で制御する
25日前
MCP の公開面やエージェントのスキル/プロンプト定義を単一の正準言語(例: 英語)に統一する規約のもとで、そのスキル自体が読者の母語など多言語の出力を生成する場合(プロフィール・レポート・要約の生成など)に、両者をどう両立させるかの判断基準。
判断基準
- 定義(指示文)も、その中の例示も、正準言語で書く。出力サンプルとしてローカライズした文字列(ユーザーの母語の例文)を定義に埋め込まない。定義言語と出力言語は別物として扱う。
- 出力言語は『ユーザーの言語で書け(write in the user's language)』という一文の指示で制御する。これで定義は単一言語のまま、出力だけ読者の言語になる。
- 出力に固定見出しなどローカライズが要る要素があっても、定義側に母語の literal を持たせない。『見出しはユーザーの言語で』と指示して生成時に localize させる。literal を持つと正準言語の残存チェックに引っかかり、かつ出力言語が変わったとき陳腐化する。
- 例示は出力の『言語』ではなく『型・パターン』(姿勢+却下案の対比、良い例/悪い例の対比など)を示すためのもの。正準言語の例で十分に機能するので、母語の例に置き換えない。
なぜ
公開面の言語が混在すると、AI が読むスキーマ/指示とユーザーが見る出力の一貫性が落ち、保守性も下がる。一方で出力は読者の言語であるべき。『定義は正準言語・出力は指示で制御』と分離すると、定義側の言語純度を残存チェックで機械的に守りつつ、出力はローカライズできる。
失敗症状・検証
- 失敗症状: ローカライズした例文や出力見出しの literal を定義に埋め込むと、正準言語の残存チェックで弾かれ、出力言語を変えたとき例が古くなる。
- 検証: 定義ファイルに正準言語以外の文字が残っていないかを grep やテストで検出し、別言語のユーザーで実行して出力がその言語になることを確認する。