agent-as-model について
agent-as-modelは、MCPホストのエージェントを生成モデルとして使うローカルMCPサーバーで、モデル提供元のAPIキーは不要です。OpenAIやAnthropic形式のリクエストツールに加え、構造化出力の検証とツール呼び出しの受け渡しに対応します。
主な機能
- 01ホストのサンプリングによる生成リクエスト
- 02チャット形式と生プロンプト形式への対応
- 03JSON Schemaによる構造化出力の検証
- 04ツール定義の転送と呼び出し結果の返却
- 05ペルソナの入力と出力の検証
- 06検証可能なカーソルによる会話継続
活用シーン
- 01MCPツール経由でホストエージェントのモデルを利用
- 02プロバイダーキーなしで生成APIを呼び出す
- 03スキーマ検証済みの構造化レスポンスを要求
MCP 対応
接続先ホストのエージェントにMCP samplingで生成を依頼し、結果をツール経由で返します。旧プロトコル経路ではホストのsampling機能が必要で、新しいマルチラウンドトリップ経路も説明されています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
5掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| model | string | いいえ | モデルのエイリアス。agent-default はホスト独自のモデルを意味します。 |
| tools | any | いいえ | ホストのモデルに転送するオプションのツール定義です。各定義は {name, description, input_schema} 形式で、input_schema はルート型が 'object' の JSON Schema オブジェクトです。ホストが sampling.tools 機能を通知した場合にのみ転送されます。それ以外の場合は破棄され、サーバー側で警告が記録されて、呼び出しはプレーンテキストにフォールバックします。 |
| persona | any | いいえ | この呼び出しのオプションの persona 契約です:{name, input_schema, output_schema}。name は必須で、空にできません。サーバーはステートレスで、persona レジストリを保持しません。input_schema が指定されると、何かを送信する前にリクエスト引数(messages、model、temperature、max_tokens、output_schema、tools、tool_choice、previous_response_id)がそれに照らして検証されます。output_schema が指定されると、ホストの補完テキストは JSON として解析でき、そのスキーマに適合する必要があります。persona.output_schema と output_schema は併用できません。 |
| messages | array | はい | チャットメッセージ。system ロールは system プロンプトになります。 |
| max_tokens | integer | いいえ | 生成する最大トークン数。 |
| temperature | any | いいえ | サンプリング温度。ホストが対応している場合に適用されます。 |
| tool_choice | any | いいえ | オプションのツール選択モードです。tools とともに転送され、tools が指定された場合の既定値は 'auto' です。 |
| output_schema | any | いいえ | オプションの JSON Schema(ルート型は object)です。指定されると、サンプリングリクエストにはこのスキーマを入力スキーマとする必須ツールがちょうど 1 つ含まれ、返却前に補完がこのスキーマに照らして検証されます。 |
| previous_response_id | any | いいえ | ホストが管理するマルチターン継続用のセッションカーソル(オプション)です。サーバーはセッション状態を保持しません。蓄積した履歴を messages で渡し直し、前のターンのカーソルをここに渡してください。'' はカーソルチェーンを開始します(未検証);'cur_<64 hex>' は検証済みチェーンを続行し、渡し直された履歴と照合します(不一致の場合は期待値と受信値を明示してエラーになります);'resp_<32 hex>'(responses_create のレスポンス ID)は渡された履歴を起点として新しいチェーンを開始します。指定されると、補完はプレーンテキストではなく JSON '{"completion": "<text>", "response_id": "cur_<...>"}' として返され、省略時は従来どおりプレーンテキストが返されます。 |
詳細
agent-as-model
エージェントがモデルであり、API キーでもある真の MCP サーバーです。
mcp-name: io.github.fernandogarzaaa/agent-as-model
インストール
uvx agent-as-model
VS Code からワンクリックでインストールできます:
ディープリンクには、サーバーの実際のインストール設定
({"name":"agent-as-model","command":"uvx","args":["agent-as-model"]})
が、公式の VS Code MCP 開発者ガイドで定められた形式で
vscode:mcp/install? ハンドラーに URL エンコードされて含まれています。
対応ホスト:サンプリングに対応するホストのみ
このサーバーは MCP サンプリングを通じて動作するため、ワンクリックインストールと 以下のガイドは、サンプリングに対応するホスト(VS Code、 Goose、fast-agent、opencode)のみを対象としています。Claude Code と Cursor は、 サンプリングに対応するまでは対象外です。手動での Claude Code の手順は、 それでも試してみたい方のために後述しています。
Goose
~/.config/goose/config.yaml に追加します(または goose configure を実行し、
Add Extension、Command-line Extension の順に選択します):
extensions:
agent-as-model:
enabled: true
type: stdio
name: agent-as-model
cmd: uvx
args: ["agent-as-model"]
timeout: 300
fast-agent
fastagent.config.yaml の mcp.servers に追加し、
エージェントの servers=[...] リストに agent-as-model を含めます:
mcp:
servers:
agent-as-model:
transport: "stdio"
command: "uvx"
args: ["agent-as-model"]
opencode
opencode mcp add agent-as-model -- uvx agent-as-model
または、opencode.json(プロジェクトのルート、または ~/.config/opencode/opencode.json)に追加します:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"agent-as-model": {
"type": "local",
"command": ["uvx", "agent-as-model"]
}
}
}
手動での設定
Claude Code(手動での手順として掲載。サンプリングが実装されるまではワンクリックインストールの対象外です):
claude mcp add agent-as-model -- uvx agent-as-model
MCP JSON を受け付けるクライアントには、次の内容を貼り付けてください:
{
"mcpServers": {
"agent-as-model": {
"command": "uvx",
"args": ["agent-as-model"]
}
}
}
Python 3.10 以降と、MCP の sampling 機能を宣言するホストが必要です。API キーは一切不要です。
ローカルのチェックアウトから実行する場合:python -m agent_as_model。リポジトリからインストールせずに実行する場合:uvx --from git+https://github.com/fernandogarzaaa/agent-as-model agent-as-model。
アイデア
AI 製品では通常、何か有用なことをする前にモデル API キーが求められます。 このサーバーはその仕組みを逆転させます。ツールは製品がすでに使っている リクエスト形式でやり取りし、知能は MCP 接続の向こう側にいるエージェントから 得られます。エージェントがモデルです。エージェントがキーです。
ツール
chat_complete — OpenAI のチャット補完形式のリクエストを受け取り、補完テキストを返します。
{
"messages": [
{"role": "system", "content": "You are terse."},
{"role": "user", "content": "Explain MCP sampling."}
],
"model": "agent-default",
"temperature": 0.7,
"max_tokens": 500
}
messages_create — Anthropic のメッセージ形式のリクエストを受け取り、補完テキストを返します。
system は文字列またはテキストブロックのリストを受け付けます。メッセージの内容は
文字列またはテキストブロックのリストを受け付けます。
responses_create — OpenAI Responses API 形式のリクエストを受け取り、Responses API
レスポンスオブジェクトを返します。input は文字列(1 つのユーザーメッセージ)または
入力項目 {role, content} のリストです。role は user、assistant、system、または
developer です。content は文字列またはテキストパーツ
({type: "input_text"|"text", input_text: "..."})のリストです。
system と developer の項目は instructions とともにシステムプロンプトに統合され、
instructions が先頭に配置されます。テキスト以外のパーツは拒否されます。
max_tokens は他のツールと同じ名前を使用します(Responses API では
max_output_tokens という名前です)。output_schema、tools、tool_choice、および
persona の動作は、他の補完ツールとまったく同じです。
返されるオブジェクトは {"id": "resp_<unique>", "object": "response", "model": <the model alias passed in>, "output": [...]} です。ホストからのプレーンテキストの
応答は、1 つの output_text ブロックを持つ単一の message 項目になります。
ホストがツールを呼び出して応答する場合、付随するテキスト(空でない場合)は
message 項目になり、各ツール呼び出しは function_call 項目になります:
{"type": "function_call", "id": "fc_<call id>", "call_id": "<host tool-call id>", "name": "...", "arguments": "<JSON>"}。ホストの
ツール呼び出し ID は call_id に対応し、オブジェクト ID はそこから生成されます。
generate — 生のプロンプト文字列を入力し、補完テキストを出力します。同じホストモデルを使用し、
チャット形式にはしません。チャット形式が不要な呼び出し元向けの簡潔な経路です。プロンプトは
システムプロンプトなしで単一のユーザーサンプリングメッセージとして送信され、ロールの変換も
行われません。model、temperature、max_tokens は他のツールとまったく同じように動作します。
チャットツール固有の機能であり、generate はオーバーヘッドがゼロであるため、tools、
output_schema、tool_choice パラメーターはありません。オプションの persona コントラクトには
対応していますが、これはリクエストとレスポンスの検証のみを行い、サンプリングのオーバーヘッドは
追加しません。
list_models — このサーバーが提供する唯一のモデル、つまりホストエージェント独自のモデルの
エイリアスである agent-default を返します。
構造化出力 — チャット形式の3つの補完ツールは、オプションの output_schema(ルート型が
object の JSON Schema オブジェクト)を受け付けます。指定すると、サンプリングリクエストには、
そのスキーマを入力スキーマとするツールが1つだけ含まれ、必須のツール選択として指定されます。
ホストはそのツールを呼び出して応答する必要があるため、そのツール使用時の入力が構造化された
補完結果になります。サーバーはその入力をスキーマに照らして検証し、JSON テキストとして返します。
ホストの応答がスキーマに違反している場合は、明示的にエラーになります。不正な出力が
エラーなく返されることはありません。スキーマ自体も事前に検証されるため、不正なスキーマは
呼び出し元のエラーであり、処理中に予期せず発生する問題ではありません。
ツール使用のパススルー — チャット形式の3つの補完ツールは、ツール定義のリストである
tools({name, description, input_schema}。input_schema はルート型が object の
JSON Schema オブジェクト)と、tool_choice(auto/required/none、デフォルトは auto)
も受け付けます。定義は事前に検証され(名前が空でなく一意であること、有効なオブジェクト
スキーマであること)、どちらのプロトコル世代でもサンプリングリクエストでホストのモデルに
転送されます。転送はホストの sampling.tools 機能によって制限されます。この機能を
通知しないホストにはツールなしのリクエストが送られ、機能低下はサーバー側で警告として
ログに記録され、呼び出しはプレーンテキストを返します。ホストがツール呼び出しで応答した場合、
ツールは次の安定した形式の JSON テキストを返します(キーはソートされます)。
{"text": "...", "tool_calls": [{"id": "...", "input": {...}, "name": "..."}]}。
ホストがプレーンテキストで応答した場合は、これまでどおりテキストを返します。tools と
output_schema の両方を渡すとエラーになります。output_schema はすでに必須のツールとして
実装されているため、両者を組み合わせると矛盾します。
ペルソナ — 4つすべての補完ツール(chat_complete、
messages_create、responses_create、generate)は、オプションの persona
({name, input_schema, output_schema})を受け付けます。サーバーはステートレスです。
ペルソナレジストリはなく、ホストが呼び出しごとにペルソナを渡し、どちらのプロトコル世代でも
同じ検証が行われます。何かを送信する前に、ペルソナ自体が検証されます(name は必須で
空でないこと、指定された場合の input_schema と output_schema は、ルート型が object の
有効な JSON Schema オブジェクトであること)。また、指定された場合は、ツールのリクエスト引数が
input_schema に照らして検証されます。検証済みのリクエストオブジェクトは、デフォルト値を
適用したツールのパラメーター一式から persona 自体を除いたものです。chat_complete では
messages、model、temperature、max_tokens、output_schema、tools、
tool_choice が含まれます(messages_create では system も含まれます)。generate では
prompt、model、temperature、max_tokens が含まれます。ホストの応答後、補完テキストは
JSON として解析でき、指定された場合は output_schema に照らして検証できる必要があります。
無効な出力は、ペルソナ名を示して明示的にエラーになります。output_schema とは異なり、
ペルソナの output_schema はサンプリングリクエストを変更しません(必須のツールは追加されません)。
ホストはプレーンテキストで応答し、サーバーがそれを解析します。output_schema と
persona.output_schema の両方を渡すとエラーになります。構造化出力コントラクトの指定元として
両者が矛盾するためです。
会話の継続 — サーバーはセッション状態を保持しないため、複数ターンにわたる会話の継続はホスト側で管理します。4つすべての補完ツールは省略可能な previous_response_id を受け付け、各補完レスポンスには、継続時に渡し直すカーソルが含まれます。カーソルは cur_ + 正規化された JSON {"model","tool","transcript"} の sha256(キーをソートし、区切り文字はコンパクトにする)です。transcript はアシスタントのターンまでの会話を表します。これは改ざんを検出できるコミットメントであり、決定論的なので、自分で再計算できます。チェーンを開始するには "" を渡します。継続するには、前のターンのカーソルとともに、蓄積した履歴(受け取ったとおりの前のアシスタントのターンを含む)を渡します。サーバーは履歴からカーソルを再計算し、一致しない場合は期待値と受信値を示して明示的にエラーを返します。responses_create のレスポンス ID(resp_...)は、不透明な ID にはコミットメントが含まれないため、エラーにせず新しいチェーンの起点になります。previous_response_id が指定されている場合、テキストツールはプレーンテキストの代わりに {"completion": "<text>", "response_id": "cur_<...>"} を返し、responses_create では id フィールドにカーソルを格納します。previous_response_id を省略すれば、それ以外はすべて以前とまったく同じ動作になります。以前のターンから分岐するには、そのターンまで履歴を切り詰め、そのカーソルを渡します。構造化された履歴チャネルがない generate では、cur_ カーソルを渡すと検証を黙って省略せず、明示的にエラーになります。現在のプロンプトと補完に対するカーソルを生成するには "" を渡します。
動作の仕組み
- プロダクト(またはエージェント)が、通常のチャットメッセージを使って
chat_completeを呼び出します。 - サーバーはそれらを補完ペイロードに変換し、ホストに補完を依頼します。2026年以前の接続では、これは直接的な
sampling/createMessageリクエストです。2026-07-28以降では、サーバーはサンプリング API を呼び出す代わりに、完全なペイロードを含む複数回のラウンドトリップを伴うInputRequiredResultを返し、補完は再試行ラウンドで届きます。どちらの時代でも、同じツール本体で対応します。 - ホストエージェントが独自のモデルで補完を生成し、サーバーがテキストを返します。
model引数はモデルのヒントとしてのみホストに渡されます。agent-defaultは「独自のモデル」を意味します。
注意事項
- サンプリングは上流で非推奨になっています(SEP-2577、2026-07-28 の仕様、最短で 2027-07-28 に削除)。公式の移行先はプロバイダー API キーです。このプロジェクトが存在するのは、エージェントをモデルとして使うアーキテクチャこそが目的であり、キーではないためです。ここで使用している、どちらの仕様世代にも対応できる形式は、両方の仕様世代で動作させ続けるために認められた方法です。
- ホストが制御します。サンプリングはホストの同意とポリシーの下で実行されます。2026-07-28 より前の接続でホストにサンプリング機能がない場合、失敗を黙って見過ごすのではなく、明確な
MISSING_REQUIRED_CLIENT_CAPABILITYエラーが返ります。2026-07-28 以降の MRTR 経路にはサンプリング機能は必要ありません。 - ツール呼び出しごとにホストモデルの呼び出しが1回発生するため、レイテンシーが生じます。これは思考用のエンドポイントであり、高速なエンドポイントではありません。
- ツール呼び出しはそのまま転送され、実行されることはありません。サーバーはツール定義をホストのモデルに転送し、ホストからのツール呼び出しを JSON として返しますが、自ら実行することはありません。どちらの方向でも、画像と音声は明示的なエラーで拒否され、黙って破棄されることはありません。
ロードマップ
- サンプリングに対応していないホスト向けのプロバイダーキーへのフォールバック(オプトイン。呼び出しごとの選択権はユーザーにあります)。
- ツール選択を必須にする方法を使った構造化出力(提供済み:両方の補完ツールに
output_schemaを追加し、サーバー側でjsonschemaパッケージを使って検証します)。 - ツール使用のパススルー(提供済み:両方の補完ツールに
tools/tool_choiceを追加し、ホストのsampling.tools機能で制限。プレーンテキストへの明示的なフォールバックと、文書化された JSON の結果形式を備えています)。 - ツールとしての、より多様なプロダクト形式(埋め込み形式のリクエストは意味のある形でサンプリングできないため、設計上対象外です)。
開発
python3 -m pytest tests/ -q
python3 -m ruff format . && python3 -m ruff check .
125 件のテストがすべて成功しています。メッセージ翻訳の単体テストに加え、スクリプト化されたホストに対して MCP の完全なループ(ツール呼び出しからサンプリングされた完了まで)をエンドツーエンドで実行しています。最新のマルチラウンドトリップ方式と従来の直接サンプリング方式の両方を対象に、構造化出力の経路(サンプリングパラメーターと MRTR ペイロードで必須ツールを 1 つ指定するケース、検証の成功、明確な検証失敗)、ツール使用のパススルー経路(両方式での tools と tool_choice の転送、機能がない場合に明示的な警告をログに記録してプレーンテキストへフォールバックする処理、文書化された JSON 結果の形式、tools と output_schema の競合)、generate ツール(両方式でシステムプロンプトもツールもないユーザーメッセージ 1 件、パラメーターのパススルー、ツールの一覧表示、説明文)、ペルソナ関連の経路(3 つすべての完了ツールでペルソナを提示する処理、リクエスト側での検証成功と送信前の拒否、レスポンス側での検証成功と明確な失敗、不正なペルソナの拒否、output_schema と persona.output_schema の競合、両方式での同一動作)、およびホストが管理するセッションカーソルプロトコル(正規カーソルの計算を固定する処理、チェーンの開始、両方式での複数ターン継続の正常動作と方式をまたいだカーソルの一致、編集されたユーザーターン、編集されたアシスタントターン、モデルの変更において、改ざんされた履歴の検証に失敗し、期待値と受信値を明示する処理、不正なカーソル形式、新しいチェーンの起点となる不透明な resp_ ID、previous_response_id が省略された場合に従来の戻り値の形式を変更しない処理、カーソル経路での responses_create の ID をカーソルとして使う処理、generate の簡易経路における検証の制限、切り詰めによる分岐、InputRequiredResult を返す前に行う MRTR の第 1 ラウンドの検証)をテストしています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。