AIエージェント・MCP

MCP Tasks拡張とは?tasks/getポーリングとサーバ主導の非同期設計を解説

MCP Tasks拡張とは?tasks/getポーリングとサーバ主導の非同期設計を解説

MCPの2026-07-28版仕様で、時間のかかるツール呼び出しの扱い方が入れ替わりました。接続を保ったまま結果を待つのではなく、サーバがその場でタスクの取っ手だけを返し、クライアントが後から取りに行く形です。この仕組みがTasks拡張(io.modelcontextprotocol/tasks)で、2025-11-25版ではコアの実験的機能だったものが独立した拡張として整理し直されました。本記事では能力宣言からタスク生成、状態遷移、入力待ちの解消までを仕様に沿って追い、SDKの実装状況を踏まえた採用条件を示します。

まとめ:MCP Tasks拡張を入れる条件と、同期のまま据え置く判断の分かれ目

Tasks拡張が効くのは、ツール1本の実行時間が数十秒を超え、その途中で接続が切れても仕事を続けたいサーバです。CIの起動、バッチ処理、承認待ち、外部ジョブAPIの呼び出しが該当します。逆に、数秒で返るツールしか持たないサーバに入れても、増えるのは状態管理の負債だけです。

設計上の要点は、タスクにするかどうかをサーバが決める点です。クライアントは拡張へ対応していると宣言するだけで、リクエストごとの指定はしません。実装の負担はサーバ側に寄り、クライアント側に要るのは、通常の結果とタスクの取っ手のどちらが返っても壊れないよう応答の受け口を二股にしておくことだけです。

ただし2026年8月時点では、公式SDKに拡張の実行時実装がまだ入っていません。後述するとおりTypeScript SDKのタスク関連の型は2025-11-25版の語彙のまま非推奨として残されており、動かすにはハンドラの自前登録が要ります。仕様に沿って先に組むか、SDKの追随を待つかは、案件の納期と保守体制で分かれると考えてください。

MCP Tasks拡張の定義と、2026-07-28版で正式拡張になるまでの経緯

まず拡張の位置づけを、識別子と対応範囲から押さえます。仕様上、Tasksはコアの機能ではなく、交渉して初めて有効になる拡張のひとつです。

io.modelcontextprotocol/tasksが扱えるリクエストの範囲

拡張識別子はio.modelcontextprotocol/tasksです。仕様が定義するのはメソッド3本(tasks/get・tasks/update・tasks/cancel)、結果の多態を見分ける判別子resultType: "task"、状態と結果を運ぶTaskという形の3点に絞られます。

タスク化できるリクエストは、現時点ではtools/callのみです。将来ほかの種別へ広げる可能性が明記されているため、タスク処理をツール呼び出しの内部へ密に埋め込まず、リクエスト種別から切り離した層として組んでおくと後の追随が楽になります。

仕様が挙げる、接続を保持したまま結果を待つ方式が詰まる4つの理由

公式ドキュメントは、接続を開いたまま待てば済むのではないかという問いに正面から答えています。第一に、長寿命の接続はタイムアウトに阻まれ、数秒を超えると現実的でなくなること。第二に、タスクIDは耐久性のある取っ手なので、切断や再起動を挟んでも同じIDでポーリングを再開できること。

第三に、状態と任意の状態メッセージを持つため進捗が外から見えること。第四に、途中で確認が要るときinput_requiredへ移して要求を差し出せることです。最後の1点は、サーバからの予告なしのメッセージや2本目の接続を使わずに済ませる設計として書かれています。

2025-11-25版の実験的機能から拡張へ整理し直された変更点

2025-11-25版では、Tasksはコアの実験的な機能として置かれていました。2026-07-28版はこれをSEP-2663に基づく拡張へ移し、あわせてメソッド構成を削っています。旧版にあった一覧取得のtasks/listは仕様から外れました。

理由はセキュリティの記述に明示されています。一覧が無いため、呼び出し元をまたいでタスクの存在を漏らす事故が起きません。仕様はこれを、範囲指定を誤ると無関係なタスクIDが露出しうる旧版に対する改善だと書いています。セッションを前提にしないステートレスなコアへ寄せた結果、一覧の範囲を安全に定める根拠自体が無くなった、という筋道です。

能力宣言からタスク生成までの実装手順と、サーバが決めるという原則

ここからは通信の並びを追います。宣言、生成、受け取りの3段で守るべき条件が異なります。

クライアントが毎リクエストの_metaで拡張対応を宣言する書き方

クライアントは、リクエストごとの能力として拡張を申告します。置き場所はparams._metaの下です。

{
  "method": "tools/call",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/clientCapabilities": {
        "extensions": {
          "io.modelcontextprotocol/tasks": {}
        }
      }
    }
  }
}

値は空のオブジェクトで、対応している事実だけを示します。拡張固有の設定項目は現時点で定義されていません。一度宣言して終わりではなく毎回のリクエストへ載せる点が、旧版との運用上の違いです。

サーバ側の広告と、宣言が無いクライアントへ返す-32021エラー

サーバはserver/discoverの応答に含まれるcapabilities.extensionsへ同じ識別子を並べます。守る条件は2つです。拡張を宣言していないクライアントへタスクを返してはならないこと、そしてタスクを返さずに処理できない場合はコード-32021(必要なクライアント能力の不足)で拒否し、不足している拡張を付随情報に書いて返すことです。

この分岐は実装で落としやすい箇所です。毎回確認せずサーバ側の設定だけで切り替えると、旧来のクライアントが理解できない結果を受け取って壊れます。ハンドラの入口で_metaを読む処理を共通化してください。

resultTypeで分岐する応答の受け方と、耐久性を先に満たす順序

タスクを作ったサーバは、通常の結果の代わりにCreateTaskResultを返します。中身はTaskと同じ形で、判別子としてresultTypeに"task"が入ります。

{
  "result": {
    "resultType": "task",
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
    "status": "working",
    "createdAt": "2025-11-25T10:30:00Z",
    "lastUpdatedAt": "2025-11-25T10:40:00Z",
    "ttlMs": 60000,
    "pollIntervalMs": 5000
  }
}

見落とせないのが順序の条件です。仕様は、返したIDに対するtasks/getが解決する状態になるまでこの応答を返してはならないと定めています。結果整合な保存基盤なら、整合が取れるのを待ってから応答してください。この決まりのおかげで、クライアントは生成直後に空振り前提のポーリングを打たずに済みます。

Taskの5状態と、ttlMs・pollIntervalMsをどの値で運用するかの決め方

タスクは耐久性のある状態機械として定義されています。状態と時間の項目を取り違えると、クライアント側の待ち時間が破綻します。

workingから終端3状態までの遷移と、statusMessageの使い分け

状態は5つで、うち3つが終端です。

状態 意味 付随フィールド
working 処理中 なし
input_required 入力待ち inputRequests
completed 完了(終端) result
failed 失敗(終端) error
cancelled 取消(終端) なし

遷移はworkingとinput_requiredの間を往復でき、どちらからも終端へ落ちます。終端に達した後は状態が変わりません。statusMessageはどの状態にも付く任意の文字列で、処理中なら進捗、取消なら理由を入れます。利用者やモデルへ見せてよいと明記されているため、人が読める文にしてください。

completedとfailedの線引きと、isErrorがtrueのツール結果の扱い

この2つの境目は、実装で最も間違えやすい箇所です。failedを使うのは、実行中にJSON-RPCのエラーが起きた場合に限られます。ツール自体は動いたが業務的に失敗した場合、つまり結果のisErrorがtrueになるケースはcompletedとして扱います。

仕様はtasks/getが元のリクエストの返り値をそのまま返すと書いており、JSON-RPC以外のエラーにfailedを使う禁止も明示しています。取り違えると再試行判定が誤作動します。プロトコル層の失敗は再試行の余地があり、業務的な失敗は繰り返しても結果が変わらないからです。

pollIntervalMsとttlMsに置く値と、期限切れ後の扱いの決め方

pollIntervalMsはサーバが提案するポーリング間隔で、クライアントは尊重すべきとされています。詰めて叩くクライアントへレート制限をかけてよいとも書かれています。仕様例では5000ミリ秒が置かれており、外部ジョブAPIの応答周期に合わせて決めるのが現実的でしょう。

ttlMsは生成からの生存期間で、無期限ならnullを入れます。期限を過ぎたサーバはタスクをfailedにしてよく、その後の削除も許されます。運用値は想定処理時間の数倍を置き、外部ジョブ側の保持期間を超えないよう揃えてください。

input_requiredで止まったタスクを進める手順と、取消が協調的である意味

途中で人の確認が要る処理は、この拡張が想定する主用途のひとつです。承認ゲートを挟む業務フローは、ここの設計で使い勝手が決まります。

inputRequestsのキー一意性と、重複提示を防ぐクライアント側の責務

タスクがinput_requiredになると、tasks/getの応答にinputRequestsという写像が入ります。クライアントはその中身を利用者やモデルへ提示し、tasks/updateのinputResponsesで応答を返します。

キーの扱いには明確な規則があります。ひとつのタスクの生涯を通じてキーは一意で、応答済みのキーを別の要求へ再利用してはなりません。クライアント側は連続するポーリングをまたいでキーを重複排除し、同じ確認を二度見せない責務を負います。サーバ側は未知や解決済みのキーへの応答を無視できます。

タスク生成前の多段往復と、実行の最中に届く入力要求の切り分け

似た仕組みが2つあるため、どちらを使うかを先に決めてください。タスクを作る前、たとえば処理を進めてよいかを確かめてから生成したい場合は、元のリクエストを繰り返す多段往復の流れです。タスクを作った後、実行の最中に確認が要る場合はinputRequestsとinputResponsesの組を使います。

信頼の扱いも押さえてください。inputRequestsが運ぶ確認要求は、サーバから直接届いた要求と同じ信頼モデルで扱うべきだと仕様は述べています。タスクを経由したからといって権限が上がるわけではありません。AIエージェントにMCPで外部ツールを接続する実装手順で扱ったtool定義と認可の設計が、そのままここへ効いてきます。

tasks/cancelが受領のみを約束する仕組みと、クライアント側の後始末

tasks/cancelは取消の意思表示であって、停止の保証ではありません。サーバの義務は空の結果で受領を返すことだけで、実際に止めるかどうかはサーバ側の判断です。取消後にcancelled以外の終端へ達することもあり得ます。通常の取消通知をタスクの取消へ流用することも明確に禁じられています。

クライアント側は、取消を送った時点でそのタスクの状態を捨ててよいとされています。応答済みキーを保持し続ける必要はなく、cancelledになるまでポーリングを続ける義務もありません。取消の送信をもって追跡を打ち切る作りが素直でしょう。

Streamable HTTPで要るMcp-Nameヘッダと状態保存先を決める設計

ステートレスなコアの上でタスクを動かすと、状態をどこに置くかという問いが残ります。ここは仕様の要求と、案件側の基盤設計が交わる箇所です。

taskIdをヘッダへ載せて中継装置に経路を固定させる仕組み

Streamable HTTPでtasks/get・tasks/update・tasks/cancelを送るとき、クライアントはMcp-Nameヘッダへparams.taskIdと同じ値を入れなければなりません。狙いは経路の固定で、中継装置や負荷分散装置が後続のリクエストを状態の持ち主へ届けられるようにするためです。

仕様はこれを、正しく動かすために通常は必要になる、と表現しています。裏を返せば、サーバを複数台で動かす構成なら、経路固定か共有ストレージのどちらかが前提条件です。ヘッダ名の規約に沿って、メソッド名はMcp-Methodへ入ります。

タスクの状態を耐久性のある置き場へ書き出すときの選択肢と項目

タスクは耐久性のある状態機械なので、プロセス内のメモリだけで持つ設計は仕様の要求を満たしません。応答を返す前に書き込みを終える必要があるため、確認が取れる置き場を選びます。外部のジョブAPIを包む形なら、そのジョブIDをタスクIDへ写す方式が素直で、状態も向こう側へ委ねられます。

自前で持つ場合、必要なのはタスクIDを鍵にした少数の項目だけです。状態、状態メッセージ、生成時刻、更新時刻、生存期間、終端時の結果か誤りになります。保存先はMCP TypeScript SDK v2のステートレス化方針と揃えてください。

ポーリングから通知へ切り替える条件と、タスクで使えない通知の種類

サーバはnotifications/tasksで状態変化を押し出せます。クライアント側はsubscriptions/listenに対象のタスクID一覧を渡して購読し、サーバは受領通知の中で購読を認めたIDを返します。通知にはtasks/getが同時点で返すのと同じ完全な状態が載るため、追加の往復が要りません。

既定はあくまでポーリングで、通知は任意の上乗せです。拡張を宣言していないクライアントが通知だけを求めた場合、サーバは-32021で拒否します。進捗通知やログ通知をタスクの購読経路へ流すことは禁じられているため、進捗を伝えたいならstatusMessageへ載せる形になります。

公式SDKに実行時実装が無い現状と、自前で書く範囲を見積もる方法

ここからは仕様の外側、実装の現在地です。採用判断に直結するため、公開されているコードを直接確認しました。

TypeScript SDKのタスク関連型が非推奨のまま残されている実測結果

2026年8月24日時点で、TypeScript SDKの主要パッケージは2026年7月27日に2.0.0が公開されています。ところが型定義を見ると、CreateTaskResult・GetTaskRequest・CancelTaskRequestといったタスク関連の型には、いずれも「2025-11-25版の通信語彙であり、SDKの実行時実装は無い。相互運用のために取り込み可能な状態で残している」という趣旨の非推奨注記が付いています。

テスト用の入力例も同じ傾向でした。タスク関連の例が置かれているのは2025-11-25のディレクトリで、2026-07-28側にあるのはサーバ能力に拡張識別子を並べた1件だけです。Python SDKも2026年7月28日にv2.0.0が出ましたが、拡張の実行時実装は揃っていません。

ハンドラを自前で登録する場合に実装が必要になる項目と工数の目安

現状で動かすなら、書く範囲は次のとおりです。3メソッドのハンドラ登録、リクエストごとのクライアント能力の確認、判別子付きの結果を組み立てる処理、状態の保存と読み出し、生存期間の満了処理、入力要求のキー管理になります。通知まで出すなら購読の受け口も加わります。

分量は大きくありませんが、耐久性と一意性の要求が絡むためテストの手間が本体より重くなります。FastMCP 4のようにセッション非依存へ寄せた枠組みなら、保存層を差し替えるだけで済む余地があります。

受託の見積もりに載せる工数項目と、SDK追随時の手戻りの読み方

見積もりでは、拡張対応を機能追加ではなく基盤変更として立てるのが実情に合います。状態保存の設計と実装、経路固定を含む配備構成の変更、旧来クライアントとの二股対応、満了と取消の異常系試験の4項目です。生成AI開発・AI受託開発のご相談でも、この4項目を最初に切り分けると総額の見通しが立ちます。

手戻りの読み方も先に共有してください。SDKが拡張へ追随した際、置き換わるのはハンドラ登録と型の周辺に限られ、状態保存と配備構成は残ります。先行実装の大半は捨てにならない見込みで、この見立てを前提に着手時期を決めるとよいでしょう。

受託開発でTasks拡張を採用する条件と、見送るべき3つの場面の線引き

最後に判断の線を引きます。仕様が良くできていることと、いまその案件へ入れるべきかは別の問題です。

採用が成立するのは処理時間・切断耐性・承認待ちのうち2つ以上

採用が成立する条件を3つに絞りました。ツール1本の実行が数十秒を超えること、接続が切れても仕事を続ける必要があること、途中で人の承認が挟まることです。2つ以上に当てはまるなら、Tasks拡張で組む価値があります。

1つしか当てはまらない場合は、代替策のほうが安く済みます。処理時間だけが問題なら、ツールを分割して短い呼び出しの連鎖にする手が有効でしょう。承認だけが問題なら、確認を先に取ってから実行する多段往復で足ります。

見送る場面1:数秒で返る参照系のツールしか持たないサーバ構成

参照系のツールばかりを提供するサーバでは、入れる意味が薄くなります。取っ手を返して取りに来てもらう往復が、処理そのものより長くかかるからです。加えてタスクの保存と満了処理という保守対象が増えます。

この場合に必要なのは、拡張への対応ではなく応答時間の測定です。95パーセンタイルが数秒に収まっているなら、同期のまま据え置いてください。

見送る場面2:接続するクライアント側が拡張へ対応していない案件

サーバが対応しても、クライアントが宣言しなければタスクは返せません。仕様がそれを禁じているためです。利用するクライアントを自分たちで選べない社内基盤の案件では、足並みが揃うまで効果が出ません。

回避策はあります。旧来のクライアント向けに、サーバ内部でポーリングを回し最終結果だけを同期で返す実装です。仕様の後方互換の項も同じ方針を示しますが、この経路では接続保持の問題が残ります。

見送る場面3:状態を耐久的に持つ基盤を用意できない配備の構成

3つ目は基盤側の制約です。応答を返す前に状態の書き込みを終える要求と、複数台構成での経路固定は、いずれも配備の作りに手を入れる話になります。共有ストレージも経路固定も持ち込めない環境では、仕様の要求を満たせません。

UI表現と組み合わせる構想がある案件では、順序にも注意してください。MCP Appsとはで整理したとおり、長時間処理の途中経過を画面に出す設計はTasks拡張と対で成立します。基盤の手当てが先で、画面はその後です。

よくある質問

2025-11-25版のTasksと2026-07-28版のTasks拡張は何が違いますか?

位置づけとメソッド構成が違います。旧版ではコアの実験的な機能でしたが、2026-07-28版ではSEP-2663に基づく拡張として切り出されました。メソッドはtasks/get・tasks/update・tasks/cancelの3本へ整理され、一覧取得は外れています。サーバが決める原則も明文化されました。

クライアントが拡張に対応していない場合はどうなりますか?

サーバはタスクを返せません。宣言が無いクライアントへタスクを返すことは仕様で禁じられています。タスクを使わずに処理できるなら同期で返し、不可能なら-32021で拒否して不足する拡張を付随情報に書きます。サーバ側の設定ではなくリクエストごとの_metaを見て分岐してください。

タスクの一覧を取得する方法はありますか?

この拡張には用意されていません。旧版の一覧取得は2026-07-28版で削られました。理由はセキュリティの項にあり、一覧が無いことで呼び出し元をまたいだタスクの存在漏れが起きない、という整理です。一覧が要るなら、自社の管理画面や業務データベース側で持つ設計にしてください。

ポーリングと通知はどちらを実装すべきですか?

まずポーリングです。仕様上ポーリングが既定で、通知はサーバが任意で上乗せする位置づけになっています。クライアントはpollIntervalMsを尊重して間隔を空け、終端まで問い合わせます。接続数や遅延が問題になった段階で購読を足す順序が現実的でしょう。

公式SDKだけでTasks拡張へ対応できますか?

2026年8月24日時点では、そのままでは対応しきれません。TypeScript SDKのタスク関連の型は2025-11-25版の語彙として非推奨の注記が付き、実行時実装は無いと明記されています。動かすにはハンドラの自前登録が要り、SDKの版上げ時に置き換わるのは主にハンドラ周辺です。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.09 テックブログ IDCFクラウドの不正アクセスとランサムウェア被害|利用者の初動と別基盤への復旧手順
  2. 2026.10.08 テックブログ 大阪公立大学のランサムウェア被害と仮想化基盤の停止|全授業休講に至った経緯とバックアップを守る設定
  3. 2024.11.08 テックブログ OpenAPI GeneratorでJavaコードを自動生成する方法|CLI導入からSpring・ライブラリ選択まで
  4. 2026.10.09 テックブログ 京王電鉄のランサムウェア被害とグループ共通基盤:決済・ポイント・予約が止まった範囲と遮断の初動
  5. 2026.10.09 テックブログ ニッスイのサイバー攻撃で日水物流の入出荷停止|委託先クラウド障害に荷主が備える手順

RELATED POSTS 関連記事

目次