メインコンテンツまでスキップ

MCP拡張機能 - Tasks・MCP Apps・Skills

コアプロトコルの外側にあるオプトイン式の拡張機能 (Extensions) の仕組みと、主要な拡張を解説します。拡張はコアとは別にバージョン管理され、クライアントが未対応だと機能しません。採用の前に、対応状況の確認とフォールバックの設計が必要です。コアプロトコルの全体像は MCP入門、2026-07-28 版の変更点は MCP最新仕様 2026-07-28 の変更点と移行 を参照してください。

1. このドキュメントで扱うこと​

  • 拡張機構
  • Tasks 拡張
  • MCP Apps
  • Skills over MCP
  • 認可拡張
  • Server Cards
  • 対応状況の確認
  • 採用判断

拡張機構​

拡張は、コアの仕様の外側で定める、オプトインの追加機能です。モジュール的なもの (認証など)、専門的なもの (業界固有のロジック)、実験的なもの (コアへの取り込みを目指して育てている機能) があります。

拡張は、{vendor-prefix}/{extension-name} 形式の拡張識別子で識別します。公式の拡張は、io.modelcontextprotocol を接頭辞に使います。サードパーティの拡張は、衝突を避けるため、自分が所有するドメインを逆順にした接頭辞 (例: com.example/my-extension) を使います。

双方が capabilities.extensions で、対応を明示してオプトインします (SEP-2133)。2026-07-28 版はステートレスのため、宣言の場所が、方向ごとに決まっています。

  • クライアント: 各リクエストの _meta["io.modelcontextprotocol/clientCapabilities"] に extensions を入れる
  • サーバー: server/discover の応答の capabilities.extensions に入れる
{
"_meta": {
"io.modelcontextprotocol/clientCapabilities": {
"extensions": {
"io.modelcontextprotocol/ui": {
"mimeTypes": ["text/html;profile=mcp-app"]
}
}
}
}
}

各拡張が、自分の設定オブジェクトのスキーマを定めます。空のオブジェクトは、設定がないことを示します。拡張は常に既定で無効で、開発者の明示的なオプトインが必要です。SDK は、拡張に対応しなくてもプロトコルに適合でき、対応する拡張を SDK のドキュメントに書くことが推奨されています。

拡張は、コアと独立して進化します。更新は拡張のリポジトリーの保守者が管理し、コアの保守者のレビューは要りません。互換性のない変更 (フィールドの削除や改名、型の変更、必須フィールドの追加) は、設定の中のフラグやバージョンで吸収し、避けられないときだけ、新しい識別子 (例: io.modelcontextprotocol/my-extension-v2) にします。

片方が対応していないときは、対応する側が、コアの動作へフォールバックするか、拡張が必須ならエラーで拒否します。たとえば、UI 付きのツールを出すサーバーは、UI 拡張に対応しないクライアントにも、意味のあるテキストの結果を返します。

公式の拡張は、MCP の GitHub 組織の ext- で始まるリポジトリーにあります。実験的な拡張は、experimental-ext- で始まるリポジトリーで、ワーキンググループなどの下で育てられ、SEP (Extensions Track) を経て公式になります。

Tasks 拡張​

Tasks は、長時間かかる処理を、永続的なハンドルで扱う拡張です。識別子は io.modelcontextprotocol/tasks です。2025-11-25 版では、コアの実験的な機能でしたが、2026-07-28 版で拡張に移りました (SEP-2663。仕様は ext-tasks)。

接続を開いたまま待つのでは解決できない問題を、Tasks が扱います。

  • 長い接続が要らない。多くのクライアントや中継機器は、数秒を超える接続にタイムアウトを設けている
  • クラッシュに強い。タスク ID は永続的なハンドルで、クライアントが切断や再起動をしても、同じ ID で再開できる
  • 進捗が見える。状態と、任意のステータスメッセージを持つ
  • 途中で入力を求められる。input_required になり、クライアントが tasks/update で応える
  • サーバー主導。タスクにするかどうかは、リクエストごとにサーバーが決める。クライアントは、拡張を 1 回オプトインし、どちらの形の結果が来ても処理できるようにしておく

流れは次のとおりです。

  1. クライアントが、リクエストごとの capability に io.modelcontextprotocol/tasks を入れる。サーバーも server/discover で同じ拡張を宣言する
  2. サーバーは、長時間になると判断したリクエストに、最終結果の代わりに CreateTaskResult (resultType: "task") を返す。taskId、初期状態、ttlMs、推奨のポーリング間隔 (pollIntervalMs) を含む。タスクは、応答を返す前に、永続的に作成する
  3. クライアントが tasks/get で状態を取得する。終了状態では、result か error が入る
  4. 途中で入力が必要なら、状態が input_required になり、tasks/get の応答に inputRequests が入る。クライアントは tasks/update で、inputResponses を返す
  5. completed では、result に、同期で返したはずの結果が入る。failed では、error に JSON-RPC のエラーが入る
  6. クライアントは、tasks/cancel でいつでも取り消しを要求できる。協調的な取り消しで、サーバーが必ず止まるとは限らない
状態意味
working処理中
input_requiredサーバーがクライアントの入力を待つ。inputRequests を参照
completed完了。result に最終出力
failed実行中に JSON-RPC エラー。error に詳細
cancelled取り消された (常に守られるとは限らない)

completed、failed、cancelled は終了状態で、以後は変わりません。tasks/result と tasks/list は廃止されました。結果は tasks/get で得ます。ポーリングが基本ですが、サーバーが対応していれば、subscriptions/listen で notifications/tasks を購読して、状態の通知を受け取れます。通知には完全なタスクの状態が入るため、追加の tasks/get は不要です。

サーバーは、クライアントが拡張を宣言していないときに、CreateTaskResult を返してはいけません。クライアントは、タスク ID を永続化し (再起動後に再開するため)、pollIntervalMs を守ってポーリングします。

Tasks は、CI のパイプライン、バッチ処理、人間の承認、ジョブ ID を持つ外部システムのラップ、不安定な接続のような場面に向いています。数秒で終わる処理には、使わなくてかまいません。

MCP Apps​

MCP Apps は、ツールの結果として、チャート、フォーム、ダッシュボード、動画のプレーヤーといった対話的な UIを、会話の中に描画する拡張です (識別子 io.modelcontextprotocol/ui)。別のウェブアプリへのリンクを返す代わりに、会話の流れの中で操作でき、アプリからサーバーのツールを呼び出し、ホストが新しい結果をアプリへ届けられます。

仕組みは、2 つの MCP のプリミティブの組み合わせです。

  1. ツールの定義の _meta.ui.resourceUri に、ui:// のリソースを指定する。ホストは、ツールを呼ぶ前に、このリソースを先読みできる
  2. ホストが、サーバーから UI のリソース (通常は、JavaScript や CSS をまとめた HTML) を取得する。外部のスクリプトなどを読み込むオリジンは、_meta.ui.csp で指定する
  3. ウェブのホストは、HTML をサンドボックス化された iframe の中に描画する。_meta.ui の permissions で、マイクやカメラなどの追加の権限を要求できる
  4. アプリとホストは、postMessage の上の JSON-RPC (ui/initialize など、ui/ で始まる独自のメソッドを含む、MCP の方言) で通信する。アプリは、ツールの呼び出し、メッセージの送信、モデルのコンテキストの更新を要求できる

セキュリティは、サンドボックス化された iframe が支えます。アプリは、親ページの DOM、Cookie、ローカルストレージに触れず、親を遷移させたり、スクリプトを実行したりできません。ホストは、アプリが呼べるツールや、リンクを開く機能を制限できます。サーバーの作者を完全に信頼しなくても、サードパーティのアプリを描画できる、というのが設計の狙いです。

向いているのは、データの探索 (地図やグラフのドリルダウン)、多数のオプションの設定フォーム、リッチなメディア (PDF、3D) の表示、リアルタイムの監視、複数段階のワークフローです。UI がもたらす利点が要らないなら、通常のウェブアプリのほうが単純です。

MCP Apps に未対応のクライアントのために、UI 付きのツールも、意味のあるテキストの結果を返す設計にします。詳細な API は 公式の MCP Apps ドキュメント を参照してください。

Skills over MCP​

Skills over MCP (識別子 io.modelcontextprotocol/skills) は、Agent Skills の仕様 に沿ったスキル (SKILL.md と、任意の補助ファイルを含むディレクトリー) を、MCP サーバーから発見、取得するための拡張です。コードレビューや文書処理のような、複数のツールを組み合わせる再利用可能な手順を、それが説明するサービスと同じ場所に置けます。クライアントは、メタデータから使えるスキルを発見し、手順や補助ファイルは必要になったときに読みます。SEP-2640 は Final で、Skills over MCP ワーキンググループが維持しています。一方、SDK とホストの対応は、まだ進行中です。

サーバーは、resources capability と、この拡張の宣言 (任意の directoryRead 設定を含む) を持ち、次のメソッドを実装します。

メソッド用途
skills/listスキルの一覧。各項目に uri、frontmatter、ファイルのマニフェスト (resources) を持つ
skills/getURI を指定して、スキルの項目を 1 件取得 (更新にも使う)
resources/readSKILL.md や補助ファイルの内容を取得 (既存のリソース機能)
resources/directory/read任意。ディレクトリーの直下の子を一覧 (directoryRead: true のとき)

スキルの URI は、skill://code-review/SKILL.md のように、skill:// を推奨しますが、ほかのスキームも使えます。マニフェストは、SKILL.md と補助ファイルのすべてについて、URI、SHA-256 のダイジェスト、バイト数を持ちます。ホストは、使う前にバイト数とダイジェストを検証し、SKILL.md の frontmatter を、項目の frontmatter と突き合わせなければなりません。検証に失敗した内容は使わず、項目を更新します。ダイジェストは、サーバーのマニフェストとの整合性を示すだけで、内容を信頼してよいことは意味しません。スキルの内容は、信頼できない入力として扱います。ホスト側のコードの実行や、allowed-tools のような権限の付与には、スキルごとの利用者の明示的な承認が必要です。承認は、ファイルの URI とダイジェストの集合に束縛され、ファイルが変わったら取り消されます。

スキルの識別は、サーバーの識別と URI の組です。名前は、一意とは限らないラベルにすぎないため、ホストは同名のスキルが黙って入れ替わらないようにします。

認可拡張​

認可の拡張は、ext-auth リポジトリーで管理される、コアの認可を補う仕組みです。

拡張識別子用途
OAuth Client Credentialsio.modelcontextprotocol/oauth-client-credentials対話的なログインのない、マシン間 (M2M) 認証
Enterprise-Managed Authorizationio.modelcontextprotocol/enterprise-managed-authorization企業の IdP による一元的なアクセス制御

仕組みと実装は、それぞれ MCPの認可 と MCPの認可拡張とエンタープライズ導入 で詳しく扱います。

Server Cards​

Server Card は、MCP サーバーを、接続の前に発見するための、静的なメタデータの文書です (SEP-2127)。server/discover は、接続先を知り、接続できたあとの、ライブな発見です。Server Card は、その前の段階を埋め、クライアントや Registry が、サーバーの所在、トランスポート、対応するプロトコルのバージョンを、接続せずに知れるようにします。IDE の自動設定や、ドメインのクロールによるインデックス化が、主な用途です。

  • 文書は、リモートの MCP サーバーの識別 (name、version、description など)、リモートのエンドポイント (URL、ヘッダー、変数のテンプレート、対応するプロトコルのバージョン)、名前空間付きの _meta を持つ
  • ドメイン単位の発見は、AI Catalog (/.well-known/ai-catalog.json) が、Server Card へのリンクを持つか、埋め込む。カード自体は、任意の URI に置けて、<streamable-http-url>/server-card が推奨の場所
  • 意図的に、ツール、リソース、プロンプトの定義と、capabilities、拡張の対応を含めない。これらは、ユーザーやセッションによって変わるため、静的な文書では表現できず、実行時に */list で確認する
  • 公開で、読み取り専用の文書。資格情報、内部ネットワークの構成、ユーザー固有のデータを含めてはならない。HTTPS で配信し、カードと server/discover が食い違うなら、ライブの server/discover の値を優先する

規定の詳細は、実験的な拡張のリポジトリー (experimental-ext-server-card) に置かれ、変わる可能性があります。ローカルにインストールするパッケージも扱う Registry の server.json とは別物です (詳細は MCP Registryとサーバーの配布)。

対応状況の確認​

拡張は、クライアントとサーバーの双方が対応して初めて動きます。クライアントごとの対応は、公式の Extension Support Matrix で確認します。コミュニティが保守する一覧で、執筆時点では、おおむね次のとおりです。

拡張対応状況の概要
MCP AppsClaude (ウェブ)、Claude Desktop、VS Code の GitHub Copilot、Microsoft 365 Copilot、Goose、Postman、ChatGPT、Cursor などが対応
Skills一部対応 (ChatGPT、fast-agent、MCP Inspector は部分対応)。mcpc が対応
OAuth Client Credentials一覧では mcpc が対応
Enterprise-Managed Authorization一覧では Archestra.AI と mcpc が対応

Tasks は、この一覧には載っていません。この表は変わるため、採用の判断の直前に、必ず最新の一覧を確認してください。認可の拡張は、コアの認可の機能 (DCR、CIMD) とは別に追跡されます。

採用判断​

拡張は、クライアントが未対応なら機能しません。採用の判断では、次のことを確認します。

  1. 利用するクライアントが、その拡張に対応しているか (対応状況の一覧と、実機での確認)
  2. 未対応のクライアントで、機能が失われたときの、フォールバックがあるか
  3. 拡張の仕様の成熟度。公式の拡張か、実験的な拡張か。実験的なものは、変わる可能性がある

2. 主要な拡張​

拡張用途補足
Tasks非同期の長時間処理、途中入力、永続的なハンドル2025-11-25 では実験的機能。2026-07-28 で拡張に移行
MCP Apps対話的 UI の埋め込みClaude Desktop などのホストで描画
Skillsエージェントのワークフロー手順の配布SEP-2640 は Final。Skills over MCP ワーキンググループが維持。SDK とホストの対応は進行中
OAuth Client Credentialsマシン間 (M2M) 認証認可拡張
Enterprise-Managed AuthorizationIdP による一元的なアクセス制御認可拡張
Server Cards接続前のサーバーの発見実験的な拡張のリポジトリーで規定 (SEP-2127)

3. 開発者がつまずきやすいポイント​

3.1 拡張をクライアントの対応なしに前提にする​

拡張は、既定で無効で、双方の宣言が必要です。クライアントの _meta に、拡張が入っているかを確認してから使います。Tasks のように、結果の形が変わる拡張は、宣言していないクライアントに返してはいけません。

3.2 UI だけで結果を返す​

MCP Apps に対応しないクライアントでは、UI が表示されません。ツールは、UI がなくても意味のあるテキストや構造化された結果を返します。

3.3 Tasks を、同期の呼び出しのように扱う​

CreateTaskResult は、最終結果ではありません。resultType を確認し、tasks/get で、終了状態までポーリングします。pollIntervalMs を無視した高頻度のポーリングは避けます。タスク ID は、永続化して、再起動後に再開できるようにします。tasks/result と tasks/list は廃止されています。

3.4 input_required の応答先を取り違える​

通常の MRTR では、再試行の tools/call に inputResponses を付けます。Tasks では、tasks/update で返します。どちらを使うかは、返ってきた結果の形で判断します。

3.5 拡張の識別子と設定を誤る​

識別子は、完全な文字列 (io.modelcontextprotocol/tasks など) で、空のオブジェクトは設定がないことを示します。破壊的な変更は、新しい識別子になるため、バージョン付きの識別子が現れることがあります。

3.6 スキルの内容を信頼する​

Skills で配られた SKILL.md は、信頼できない入力です。ツールの description と同様に、プロンプトインジェクションの経路になり得ます。ホスト側のコードの実行や権限の付与には、承認を求め、ダイジェストで内容の変化を検出します。詳細は AIエージェント特有の脅威 - プロンプトインジェクションとツール汚染 を参照してください。

3.7 Server Card にツールの一覧や機密を入れる​

Server Card は公開文書です。ツールや capabilities は、実行時の */list と server/discover で確認するもので、カードには書きません。資格情報も入れません。

3.8 対応状況の一覧を固定の事実として扱う​

一覧は、コミュニティが保守していて、頻繁に変わります。ドキュメントやコードに表を写さず、リンクを張り、採用の時点で確認します。

4. コード例​

拡張を宣言するクライアントのリクエスト​

{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "run_pipeline",
"arguments": { "repo": "example/app" },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {
"extensions": {
"io.modelcontextprotocol/tasks": {}
}
},
"io.modelcontextprotocol/clientInfo": { "name": "ExampleClient", "version": "1.0.0" }
}
}
}

サーバーの宣言 (server/discover)​

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"supportedVersions": ["2026-07-28"],
"capabilities": {
"tools": {},
"extensions": {
"io.modelcontextprotocol/tasks": {},
"io.modelcontextprotocol/ui": {}
}
},
"ttlMs": 3600000,
"cacheScope": "public"
}
}

MCP Apps の UI を参照するツール定義​

ツールの _meta.ui.resourceUri が、UI のリソースを指します。

{
"name": "show_sales_dashboard",
"description": "Show sales by region. Returns a text summary as well as an interactive dashboard.",
"inputSchema": {
"type": "object",
"properties": { "year": { "type": "integer" } },
"required": ["year"]
},
"_meta": {
"ui": { "resourceUri": "ui://sales/dashboard" }
}
}

Tasks のクライアントのポーリング​

結果の形 (resultType) で処理を分けます。TypeScript の擬似コードです。タスクの項目の正確な形は、Tasks 拡張の仕様 (ext-tasks) で確認してください。

async function callMaybeTask(client: McpClient, params: CallToolParams) {
const first = await client.request("tools/call", params);
if (first.resultType !== "task") return first; // 通常の結果

const taskId = first.task.taskId;
await persistTaskId(taskId); // 再起動後に再開できるようにする
let delay = first.task.pollIntervalMs ?? 2000;

for (;;) {
await sleep(delay);
const t = await client.request("tasks/get", { taskId });
switch (t.status) {
case "completed":
return t.result;
case "failed":
throw new Error(t.error.message);
case "cancelled":
throw new Error("task cancelled");
case "input_required": {
const inputResponses = await collectInputs(t.inputRequests);
await client.request("tasks/update", { taskId, inputResponses });
break;
}
default:
delay = t.pollIntervalMs ?? delay; // working
}
}
}

5. まとめ​

  • 拡張は、コアの外側のオプトイン式の機能。capabilities.extensions で双方が宣言し、識別子は {vendor-prefix}/{extension-name}
  • Tasks は、長時間の処理を taskId のハンドルで扱い、tasks/get のポーリングと tasks/update で進める。tasks/result と tasks/list は廃止
  • MCP Apps は、サンドボックス化された iframe に対話的な UI を描画する。未対応のクライアント向けに、テキストの結果も返す
  • Skills over MCP は、skills/list と skills/get と resources/read で、スキルを発見、取得する。内容は信頼できない入力で、ダイジェストで検証する
  • 認可の拡張は、OAuth Client Credentials と Enterprise-Managed Authorization
  • Server Card は、接続前の発見のための公開メタデータ。ツールや capabilities は含まない
  • 採用前に、Extension Support Matrix で対応状況を確認し、フォールバックを設計する

参考資料​