これは、APIテストとAPIライフサイクル管理のためのコマンドラインツールであるApidog CLIをApidogがどのように開発したかを共有する10部構成のシリーズです。順に読むか、興味のある記事に直接ジャンプしてください。
| タイトル | 焦点 | |
|---|---|---|
| 1 | 私たちは126個のMCPツールを構築しました。しかし、それはエージェントにとって最善の解決策ではありません | 問題の発見 |
| 2 | なぜ私たちは全く新しいApidog CLIを開発したのか | アーキテクチャ開発 |
| 3 | 黄金律:CLIは事実を生成し、モデルは事実に従って行動する | 核心哲学 |
| 4 | agentHints: CLIにエージェントと話す方法を教える |
構造化された出力 |
| 5 | SKILL: 運用経験をコードとして出荷する | 運用経験 |
| 6 | 数字は嘘をつかない: ツール呼び出し30%減、トークン25%減 | 定量的結果 |
| 7 | PRDからテストループまで: Apidog CLIによる完全なエージェントワークフロー | 実践チュートリアル |
| 8 | エージェントツールにとってCI/CD互換性が不可欠な理由 | DevOpsの視点 |
| 9 | AIブランチ: AIエージェントによるより安全なプロジェクト変更 | セキュリティ層 |
| 10 | Spec-Firstは昨日。Skill-Firstへようこそ。 | ビジョンと未来 |
MCPが業界のホットスポットとなったとき、私たちは126個の生成ツールを備えた完全なMCPサーバーを構築しました。この記事では、何がうまくいかなかったのか、そしてなぜ「ツールが多い」ことが「エージェントにとって使いやすい」ことを意味しないのかを、実装上の観点から整理します。
MCPの誇大宣伝
2025年初頭、MCP(Model Context Protocol)は業界のホットスポットとなりました。
Anthropicがこのプロトコルを推進し、Cursor、Claude Code、Antigravity、さまざまなAgent IDE、そして多くのSaaS製品がそれに続きました。MCPは、AIエージェントが外部ツールやデータソースに接続するための標準化された方法を提供するものとして注目されました。
その時期、APIを持つほぼすべての製品が同じ質問を受けました。
「MCPに対応していますか?」
Apidogにとって、MCP対応は自然な選択に見えました。
なぜMCPが解決策に見えたのか
Apidogには、API開発に必要な多くの機能があります。
- APIドキュメント
- スキーマ定義
- モックサーバー
- テストケース
- テストシナリオ
- テストスイート
- テストレポート
- インポート/エクスポートワークフロー
- ブランチコラボレーション
- その他多数
もしAIエージェントが新しいソフトウェアのエントリポイントになるなら、これらの機能をMCPツールとして公開するのは妥当に見えます。
当初の期待はシンプルでした。
Apidogの機能をMCPツールとして公開する
↓
エージェントがAPI関連操作を実行できる
↓
ユーザーは自然言語でAPI開発・テスト作業を進められる
想定していたエージェントの操作例は次のとおりです。
- APIドキュメントを照会する
- テストケースを作成する
- テストシナリオを実行する
- プロジェクトデータをインポート/エクスポートする
- 環境と変数を管理する
- ブランチ間でコラボレーションする
当時の仮説はこうでした。
公開する機能が多いほど、エージェントの有効化は進む。
しかし、実装して使ってみると、この仮説は単純すぎました。
実際に構築したもの
私たちはMCP対応を軽く扱ったわけではありません。
Apidog MCPは、数個の手書きエンドポイントを持つデモではなく、完全なMCPサーバーとして実装しました。
1. セッションシステム
MCPクライアントは最初にセッションを初期化します。
サーバー側では以下を行います。
-
sessionIdを生成する - Redisにセッション状態を保存する
- 以降のリクエストで
sessionIdを使って状態を継続する
つまり、これは単発のHTTP呼び出しではなく、プロトコルレベルのセッションシステムでした。
実装イメージは次のようになります。
Client
└─ initialize
└─ Server generates sessionId
└─ Store session state in Redis
Client
└─ tool call with sessionId
└─ Server loads session
└─ Execute tool
└─ Update session state
2. ツールカテゴリ
ツール層も、いくつかの固定エンドポイントを手書きしただけではありません。
Apidogの機能を複数のカテゴリに分けて公開しました。
| カテゴリ | 説明 | 例 |
|---|---|---|
| ネイティブプロジェクトツール | プロジェクトレベルの操作用 | プロジェクト概要、フォルダ構造、リソース詳細 |
| 組み込みドメインツール | Apidogのコア機能 | インポート/エクスポート、エンドポイント詳細、テストケース、テストシナリオ |
| 生成されたOpenAPIツール | OpenAPI定義から自動変換 | ユニークな識別子、パス、HTTPメソッド、入力スキーマを持つ126個のツール |
特に大きかったのが、最後のカテゴリです。
126個の生成されたツール。
各生成ツールには以下を持たせました。
- ユニークな識別子
- 特定のAPIパス
- HTTPメソッド(
GET、POST、PUT、DELETEなど) - フィールド説明、型、列挙値を含む入力スキーマ
- 定義された戻り構造
3. プログレッシブ開示
すべてのツールを一度に露出するとコンテキストが大きくなりすぎます。そこで、動的発見層も実装しました。
エージェントには次の順序で操作させる設計です。
- 利用可能なエンドポイントツールを検索する
listOpenApiEndpoints - 特定ツールのOpenAPI詳細を取得する
getOpenApiDetails - ツールIDで実際のHTTP呼び出しを実行する
executeOpenApi
疑似フローにするとこうです。
User request
↓
Agent calls listOpenApiEndpoints
↓
Agent chooses a candidate endpoint
↓
Agent calls getOpenApiDetails
↓
Agent builds arguments
↓
Agent calls executeOpenApi
これはプログレッシブ開示の試みでした。すべてのエンドポイントを直接公開するのではなく、エージェントが検索し、詳細を取得し、最後に実行することを期待していました。
ランダムなツールの壁
問題は、実際のタスクに入るとすぐに見えました。
たとえば、ユーザーが次のように依頼したとします。
「このエンドポイントのテストを追加して、検証を実行してください。」
人間の開発者から見ると、これは自然なリクエストです。Apidogには必要な機能があります。
- エンドポイントの検索
- テストケースの作成
- テストシナリオの実行
- レポートの生成
しかし、エージェントにとっては、これは一連の判断問題になります。
| 判断ポイント | オプション | 不確実性 |
|---|---|---|
| どこから始めるか? | 先にプロジェクトを見つけるか?先にエンドポイントを探すか? | 明確なガイダンスがない |
| 何を読むべきか? | エンドポイント詳細を読むか?既存のテストケースを一覧表示するか? | どちらも有効に見える |
| どのように作成するか? |
createTestCaseを直接使うか?先にケースグループを探すか? |
要件が隠れている |
| どのように更新するか? |
updateツールを呼ぶか?ステップをインポートして読み戻すか? |
ワークフローが暗黙的 |
ここで重要なのは、エージェントがユーザーの問題を解く前に、まず別の問題を解かなければならないことです。
どのツールを、どの順序で、どの入力で使うべきか?
ツールが存在することと、エージェントが正しく使えることは別問題です。
4つの構造的問題
実世界でのテストと内部フィードバックから、MCPアプローチには4つの構造的問題があると分かりました。
問題1: ツール発見コストが急速に上昇する
Apidogは、12個程度のエンドポイントで表現できる製品ではありません。
| モジュール | 内訳 |
|---|---|
| エンドポイント | 一覧表示、取得、作成、更新、削除 |
| スキーマ | 一覧表示、取得、作成、更新、削除 |
| 環境 | 一覧表示、取得、作成、更新、削除、変数 |
| モック | 設定、有効化、無効化 |
| テストケース | 一覧表示、取得、作成、更新、削除、複製 |
| テストシナリオ | 一覧表示、取得、作成、更新、削除、ステップのインポート、実行 |
| テストスイート | 一覧表示、取得、作成、更新、削除 |
| レポート | 一覧表示、取得、生成、ダウンロード |
| インポート/エクスポート | 複数形式、オプション |
| ブランチ | 一覧表示、作成、マージ、削除 |
ツールが10個から数十個、数百個に増えると、エージェントは本来のタスクを始める前にツール選択に時間を使います。
実装側では、descriptionにワークフローを書き込むことも試しました。
例:
エンドポイントデータを照会する前に、
まず別のツールでプロジェクトを確認し、
次に3番目のツールでプロジェクトメタデータを取得し、
最後に現在のツールを呼び出してください。
小規模なツールセットなら、この方法は機能します。
しかし大規模なツールセットでは、description自体がモデルの注意を奪い合います。
- 説明を増やすほどトークンを消費する
- 説明が増えるほど読まれにくくなる
- ツール数が増えるほど、正しい順序を推測しにくくなる
実装上の教訓は明確です。
ツール説明にワークフローを詰め込む設計は、スケールしにくい。
問題2: ビジネススキーマがコンテキストを侵害する
MCPツールは単なる関数名ではありません。
各ツールには以下が含まれます。
descriptioninput schema- パラメータの型
- 必須/任意の指定
- ネストされたフィールド説明
- 列挙値
- 戻り構造
- エラー処理の説明
控えめに見積もっても、次のようになります。
| 要因 | 値 |
|---|---|
| ツール数 | 100以上 |
| ツールあたりの平均トークン数 | 約500 |
| 合計ツール説明トークン数 | 約50,000 |
ユーザーの質問は50文字程度かもしれません。
しかしモデルは、1つのMCPサーバーのために、まず大量のツール説明を扱う必要があります。
これは理論上の問題ではありません。
Cursorの公式ブログ投稿「Dynamic Context Discovery」では、MCPツール説明、ターミナルセッション、長い会話をオンデマンドで読み込み可能なコンテキストに変換することで、ランタイムトークン消費を46.9%削減したと説明されています。
Traeのアプローチはさらに直接的です。
- ツール数の上限: 40
- 単一ツール説明の制限: 8000文字
初期の内部テストでも、TraeでApidog MCPの一部ツールを呼び出せないケースが報告されました。限られたモデルコンテキストの中で、外部ツールが最初に削られることがありました。
実装観点での結論は次です。
ツール説明は無限にモデルコンテキストへ投入できない。
問題3: プロトコルセッションが実行チェーンを重くする
Apidog MCPサーバーは、ツール呼び出し以外にも多くのプロトコル状態を処理する必要がありました。
| プロトコル状態 | 説明 |
|---|---|
| MCP初期化 | クライアントとサーバー間のハンドシェイク |
sessionId生成 |
セッションの一意な識別子 |
| Redisセッションストレージ | 状態の永続化 |
| トランスポート接続/切断 | 接続管理 |
| セッションタッチ | キープアライブ |
| セッション削除 | 完了時のクリーンアップ |
| JSON応答またはSSE設定 | 出力形式の選択 |
単発のツール呼び出しなら許容できます。
しかしエージェントタスクでは、探索と実行が何度も発生します。
discover tools
↓
read metadata
↓
call tool
↓
read result
↓
choose next tool
↓
call another tool
↓
validate result
このチェーンにプロトコル状態管理が毎回関わると、サーバー側とクライアント側の両方で複雑性が増えます。
さらに、Cursor、Claude Code、Antigravity、Traeなど、複数のエージェントクライアントへの適応にもコストがかかりました。プロトコル互換性の問題も残り、MCPプロトコル自体も新しいバージョンで更新され続けました。
実装側の現実はこうです。
標準プロトコルを採用しても、クライアント差分への適応コストは消えない。
問題4: アトミックなツールでは製品セマンティクスを自然に表現できない
Apidogのテストシナリオは、単純なsteps配列ではありません。
実際には、以下のような要素が絡みます。
| コンポーネント | 複雑さ |
|---|---|
| インポート | エンドポイントまたは既存ケースからステップを取り込む |
| 読み戻し | インポート後の完全な構造を取得する |
| 内部ケース | ステップに埋め込まれたHTTPリクエスト |
| 前/後処理 | リクエスト前後のスクリプト |
| アサーション | 応答検証ルール |
| 変数抽出 | 応答から値をキャプチャする |
| ランタイム環境 | 環境選択、変数 |
| レポート検証 | テスト結果の確認 |
これらを複数のMCPツールに分割しても、エージェントはテストオーケストレーションそのものを理解しなければなりません。
たとえば、エージェントは次のような製品固有のルールを把握する必要があります。
- なぜインポート後に読み戻しが必要なのか
- なぜ内部ケースには異なる更新マーカーがあるのか
- なぜアサーションには特定の比較演算子が必要なのか
- なぜ変数抽出には型制約があるのか
ツールがアトミックであればあるほど、モデルは製品内部のセマンティクスを理解する必要があります。
これはエージェントに任せるには重すぎます。
根本原因
4つの問題の根本原因は同じです。
MCPはツールを接続するのに優れています。しかし複雑なR&Dタスクには、ツール接続だけでなく、実行可能なエンジニアリングプロセスが必要です。
| MCPの強み | MCPの限界 |
|---|---|
| 標準化された接続 | ワークフローを表現できない |
| 統一されたプロトコル | 実行順序をガイドできない |
| ツール公開 | 検証を強制できない |
| 動的発見 | 判断を提供できない |
明確に定義された少数の操作を持つシンプルな製品なら、MCPは十分に機能します。
しかしApidogのように、数十のモジュール、数百の操作、ネストされた構造、隠れたワークフロー、製品固有のセマンティクスを持つ製品では、MCPだけではエージェントが迷いやすい「ランダムなツールの壁」になります。
実装時に確認すべきチェックリスト
MCPサーバーを設計する場合、最初に次の点を確認するとよいです。
[ ] ツール数は40個以下に収まるか?
[ ] 各ツールのdescriptionは短く保てるか?
[ ] ツール呼び出し順序をモデルが推測しなくても済むか?
[ ] ワークフローをdescriptionではなく別の形で表現できるか?
[ ] 入力スキーマはモデルコンテキストを圧迫しないか?
[ ] セッション管理は本当に必要か?
[ ] クライアントごとの互換性差分を吸収できるか?
[ ] 製品固有のルールをモデルに丸投げしていないか?
もし多くの項目に不安があるなら、単純にMCPツールを増やすより、ワークフローを実行可能な形で提供する設計を検討すべきです。
私たちが学んだこと
| 教訓 | 示唆 |
|---|---|
| ツールの増加 ≠ エージェントの有効化向上 | ツール数はメリットではなくコストになり得る |
| ツール説明はコンテキストを奪い合う | 500トークン × 100ツール = 50,000トークンの負担 |
| セッションプロトコルは実行オーバーヘッドを追加する | 各呼び出しが状態管理を伴う |
| アトミックなツールには製品知識が必要 | エージェントが内部オーケストレーションを理解する必要がある |
| 接続 ≠ 実行 | MCPは接続する。CLI + SKILLは実行する |
転換点
この認識から、私たちは別の問いに向き合うことになりました。
もしMCPがエージェント有効化の完全な答えではないなら、何が必要なのか?
私たちはMCPの価値を否定していません。MCPは標準化された接続を提供し、エコシステムにとって重要です。
ただし、Apidogにはさらに次のものが必要でした。
- ツールではなくワークフローを表現できること
- エージェントを正しい順序に沿ってガイドできること
- 書き込み前に検証できること
- エンジニアリングの品質ゲートを強制できること
- 複雑さをモデルではなくシステム側で吸収できること
私たちがたどり着いた答えは、CLI + SKILLでした。
次の記事「なぜ私たちは全く新しいApidog CLIを開発したのか」では、複雑さをモデルコンテキストからエンジニアリングシステムへ移すアーキテクチャ変更と、それがエージェント有効化に与える影響を解説します。
主なポイント
- MCPは「エージェントがツールに接続する方法」として有用
- 私たちは、ツールが多いほど有効化が進むと考え、126個のMCPツールを構築した
- 実際のタスクでは、発見コスト、コンテキスト圧迫、セッションオーバーヘッド、製品セマンティクスの問題が顕在化した
- 根本原因は、MCPが接続を提供する一方で、実行可能なプロセスまでは提供しないこと
- 複雑な製品では、ツール数を増やすより、ワークフローと検証を実装側に持たせる方が有効
Apidogをダウンロードして、1つのワークスペースでAPIの設計、モック、テスト、ドキュメント化を行いましょう。コマンドラインAPIテスト、CI自動化、AIエージェントワークフローのためのApidog CLIについて詳しく学びましょう。
Top comments (0)