AI

FastMCP 4とは?sessionless対応と廃止APIから読む3系からの移行判断

FastMCP 4は、PythonでMCPサーバーを書くためのフレームワークであるFastMCPの次期メジャー版です。内部エンジンをMCP Python SDK v2へ載せ替え、2026-07-28リビジョンのsessionless protocolを話せるようになりました。ただし2026年7月30日時点で公開されているのは4.0.0b1というベータで、PyPIのstableは3.4.5のままです。この記事では、廃止された3つのContextメソッドとその代替、snake_case化やhttpx2への切り替えといった移行項目、TasksExtensionやUserSessionの位置づけ、そして4系へ上げるか3系に据え置くかの判断基準を実装目線で整理します。FastMCPそのものの基本構文はFastMCPでMCPサーバーを構築する基本の書き方を先に押さえておくと読み進めやすくなります。

まとめ|4系はベータであり、上げる理由がある案件だけが今動く

FastMCP 4の変更点はツールの書き方ではなく、その下の通信層に集中しています。3系のコードはデコレータの形をほぼ保ったまま動きますが、サーバーからクライアントへ要求を押し込む3つのAPIだけは、代替なしで削除されました。ここを踏んでいるかどうかが移行難易度をほぼ決めます。

今上げる理由がはっきりしているのは、ロードバランサの背後で水平に並べたい場合、バックグラウンドタスクを標準の拡張で扱いたい場合、OAuthのclient credentialsでマシン間認証を通したい場合の3つです。逆に、呼び出し側のモデルを借りるsamplingがサーバーの本質になっている実装、pydanticを2.12へ上げられない基盤、httpxを直接掴んだ自作クライアントを抱えている場合は、3系に留まる判断が合理的です。ベータである以上、当面はバージョンを完全に固定して検証環境から入れます。

FastMCP 4の位置づけ|SDK v2とsessionless対応への移行要点

4系を「機能追加の版」と読むと移行計画を誤ります。土台の入れ替えだからです。

3系との違いはプロトコル層|2026-07-28仕様のsessionless対応

従来のMCPは、initializeで握手してから接続を保持し、その上でやり取りを続ける設計でした。2026-07-28リビジョンでは、この前提が外れる設計です。1回のリクエストが認証情報もプロトコル世代も自分で運ぶため、どのレプリカが受けても同じ結果を返せる構造です。結果としてセッションアフィニティがデプロイ要件から消え、ロードバランサの設定を素直に書けるようになりました。FastMCP 4は、この新しい世代と従来の握手世代の両方を1つのサーバープロセスで話し分けます。仕様そのものの背景はMCP(Model Context Protocol)の標準規格としての位置づけで整理しています。

4.0.0b1というベータ段階とPyPI上の安定版を比べた実測結果

版の状況は正確に押さえてください。GitHubのリリース一覧では、v4.0.0b1が2026年7月28日にpre-release表示で公開されています。その前後にv4.0.0a1とv4.0.0a2があり、安定版の4.0.0はまだ出ていません。一方でPyPIのJSONメタデータを引くと、info.versionは3.4.5、requires_pythonは3.10以上でした。つまりpip install fastmcpを素で叩くと3系が入ります。

4系を入れるには版を明示します。pipならpip install "fastmcp==4.0.0b1"です。uvを使う場合は、pyproject.tomlのdependenciesにfastmcp==4.0.0b1を書いたうえで、[tool.uv]のconstraint-dependenciesにfastmcp-slim==4.0.0b1を並べる指定が必要になります。公式もベータ期間中は完全なピン留めを求めており、範囲指定で拾わせる書き方は避けます。

mode=”auto”による世代交渉と、旧クライアントの扱い

1つのサーバーが2世代を話すため、どちらで接続したかを決める仕組みが必要です。クライアント側はmodeで指定し、既定のmode="auto"なら双方が話せる最も新しい世代へ寄せます。握手世代へ固定したいときはClient(server, mode="legacy")と書きます。サーバー側の実装を世代ごとに分岐させる必要はありません。既存のクライアントはmodeを触らないまま接続でき、対応していない相手には従来の握手で落ちます。トランスポート層の前提はStreamable HTTPとSSEの違いと使い分けを踏まえると読み解きやすくなります。

破壊的変更の中心|3つのContextメソッド廃止と代替の書き方

公式が「4系で既存サーバーを壊す可能性が最も高い箇所」と名指ししているのが、ここです。

ctx.sampleなど3つのContextメソッドが削除された設計上の理由

sessionlessな接続では、実行の途中でサーバーからクライアントへ要求を押し込む経路がありません。この経路に依存していたのがctx.sample()ctx.sample_step()ctx.list_roots()の3つでした。FastMCP 4は、これらをすべてのプロトコル世代から削除しています。握手世代の接続でも動かしません。互換シムを残して静かに挙動が変わるより、アップグレード直後に例外で止めたほうが安全だという判断です。移行前のコードベースでは、まずこの3つをgrepして該当箇所を数えます。件数がゼロなら移行の山は越えています。

InputRequiredResultでユーザー入力を往復処理へ置き換える方法

ユーザーへの問いかけは、コールバックから往復へ形が変わりました。ツールは処理を止めて待つ代わりに、聞きたい内容を記述したInputRequiredResultを返した時点で一度終了です。クライアントはユーザーの答えを添えて同じ呼び出しを再送し、ツールは2巡目でctx.input_responsesから答えを読みます。要求ごとにキーを振り、答えは同じキーで返ってきます。

実装で引っかかりやすいのは初回の判定です。ctx.input_responsesは1巡目ではNoneで、2巡目以降にマッピングが入ります。したがってツール関数の冒頭でNoneかどうかを見て、「まだ聞いていない」と「答えが返ってきた」を分岐させる形になります。この型はツール専用ではありません。プロンプトもリソースもリソーステンプレートも同じ手順で、クライアントがprompts/getresources/readを答え付きで再発行します。

ctx.elicitのresponse_type必須化と世代ごとの挙動差

ctx.elicit()自体は残りますが、response_type引数が必須になりました。加えて、sessionless世代の接続で呼ぶと例外を送出します。握手世代の接続だけで動く前提のコードなら残せますが、新世代のクライアントが混ざった時点で落ちます。新規に書くならInputRequiredResultへ寄せるほうが世代を選びません。samplingについては代替が用意されていないため、LLMのAPIをサーバー側から直接呼ぶ形に書き換えます。呼び出し側のモデルを借りること自体が価値だった実装は、この書き換えで前提が変わる点に注意してください。

移行チェックリスト|改名・依存引き上げ・互換ブリッジ停止の確認手順

プロトコル層の変更に伴って、機械的に潰せる変更もまとまった数が入りました。順序を決めて片付けます。

フィールド名のsnake_case化と互換ブリッジを停止する確認手順

MCP Python SDK v2でプロトコル型のフィールド名がsnake_caseへ揃いました。代表的なものは次の通りです。

3系までの名前 4系の名前 出てくる場所
inputSchema input_schema ツール定義の入力
mimeType mime_type リソースの応答
isError is_error ツール結果の判定

旧名でも当面は通ります。互換ブリッジが旧名を新名へ回し、警告を出す作りだからです。ただし警告のまま出荷すると移行が終わりません。書き換えを終えたらmcp_camelcase_compat = Falseを設定してブリッジを切り、旧名が残っていないことをテストで確かめます。

McpErrorのキーワード引数化とhttpx2への切り替え

エラー生成の書き方が変わりました。McpError(ErrorData(...))という位置引数の型は通らなくなり、McpError(code=-32000, message="text")のようにキーワード引数で組みます。ErrorDataを自前で組み立てるユーティリティを持っているなら、そこが集中的な修正点になります。

影響範囲が読みにくいのはHTTPクライアントの入れ替えです。FastMCPはhttpxからhttpx2へ移りました。カスタムのHTTPクライアントを差し込んでいる箇所、例外型でリトライを判定している箇所、テストでトランスポートを差し替えている箇所は、import httpximport httpx2へ直したうえで例外階層を再確認します。ライブラリ側の型注釈にhttpxのクラスが露出していると、型チェックで初めて気づくことになります。

サーバーAPIの改名内容と依存パッケージ引き上げ時の確認事項

合成まわりのメソッドが改名されました。as_proxy()create_proxy()へ、import_server()mount()へ、mount(prefix=)の引数はmount(namespace=)へ変わります。プロキシとサーバー合成を組み合わせて構成を作っている実装ほど当たる件数が増えます。

依存の前提も上がりました。pydanticは2.12以上、FastAPIは0.133.0以上が要ります。FastAPIアプリからMCPサーバーを生成する構成を採っているなら、この引き上げを先行タスクとして切り出したほうが安全です。作業順は、依存の引き上げ、削除APIのgrep、改名の置換、互換ブリッジの停止、テストの通過という流れで進めると手戻りが出にくくなります。TypeScript側でも同時期に似た規模の移植が走っており、両方の言語でサーバーを持っている組織はMCP TypeScript SDK v2のパッケージ分割と移行要点と並べて計画を立てると全体像がつかめます。

TasksExtensionとUserSession|状態管理とタスク運用の仕組み

セッションが消えると困るのが、長時間処理とユーザー単位の状態です。4系はこの2つに別々の答えを用意しました。

バックグラウンドタスクの有効化手順とバックエンドの選択基準を整理

時間のかかる処理は、拡張として提供されるタスク機能へ逃がします。導入はpip install "fastmcp[tasks]"で、コード側はfrom fastmcp_tasks import TasksExtensionしてmcp.add_extension(TasksExtension())を1行書きます。3系でtask=Trueだけ書いていた場合、この登録がないと動かない点が変更箇所です。

個別のツールは@mcp.tool(task=True)で有効化の対象です。これはTaskConfig(mode="optional")の省略形で、クライアントがタスク機能に対応していれば非同期、していなければ同期で走ります。厳密に制御したいときはmode="required"で未対応クライアントを弾き、mode="forbidden"で常に同期にします。バックエンドは既定がmemory://で単一プロセス限定です。複数レプリカで動かす場合はTasksExtension(url="redis://localhost:6379/0", concurrency=20)のようにRedisまたはValkey互換のストア指定が必要です。環境変数FASTMCP_DOCKET_URLFASTMCP_DOCKET_NAMEFASTMCP_DOCKET_CONCURRENCYでも同じ設定を上書きできるため、コンテナ運用では環境変数側へ寄せる構成が扱いやすくなります。クライアントのポーリング間隔はTaskConfigpoll_intervalで示唆できます。

UserSessionとSessionIdによるユーザー単位の状態管理

プロトコルからセッションが消えた代わりに、アプリケーション層で状態を宣言する仕組みが入りました。ツールの引数にUserSession型のパラメータを置くと、そのユーザーに紐づく状態を読み書きできます。前提は認証です。状態を誰に束ねるかを決められないと成立しないため、認証なしの構成では使えません。逆に言えば、認証済みの利用者ごとに会話の文脈を持たせたいなら、接続を保持しなくても組めるようになりました。

補完・キャッシュ・パス安全性を本番運用で設定する際の注意点を整理

周辺の機能も本番前提で整備済みです。@mcp.completionデコレータを書くと、プロンプトやリソーステンプレートの引数について入力途中の文字列から候補を返却可能です。応答キャッシュはcache_ttlcache_scopeで指定し、スコープの取り違えが情報漏えいに直結する部分なので既定値のまま流さず明示します。リソーステンプレートのパス安全性は既定で有効になり、ディレクトリを遡る指定を弾きます。認可では、必要なスコープが足りないときにInsufficientScopeErrorが上がるようになりました。マシン間の認証には、信頼する発行者を登録して未署名のエージェントを受けるIdentityAssertionと、OAuth 2.0のclient credentialsを実装したClientCredentialsOAuthProviderが加わっています。対話的なログインを挟めないバックエンド連携は、ここが実装の入口になります。

4系へ上げる条件と3系に据え置く条件|移行判断の基準を言い切る

ベータである以上、全案件が今動くべきだとは考えません。条件で切り分けます。

今すぐFastMCP 4の検証を始めるべき3つの条件と判断基準

1つ目は、MCPサーバーを複数レプリカで水平に並べたい場合です。sessionlessならリクエストが自己完結するため、セッションアフィニティを前提にしたルーティングを捨てられます。サーバーレスやオートスケール環境では、この一点だけで移行の価値が出ます。2つ目は、数分単位の処理をツールとして提供したい場合です。TasksExtensionが標準の拡張として入ったことで、自前のジョブキューとステータス問い合わせAPIを作り込む必要がなくなります。3つ目は、バックエンドのサービスから対話的ログインなしでMCPサーバーを叩きたい場合です。ClientCredentialsOAuthProviderが入ったため、独自トークン発行の仕組みを持たずに済みます。いずれも該当するなら、まず検証環境で4.0.0b1をピン留めして既存テストを流すところから始めます。

FastMCP 3系に据え置くほうが妥当になる3つの条件と判断基準

次の3条件のどれかに当たるなら、安定版の4.0.0が出るまで動かない判断を採ります。第1に、ctx.sample()で呼び出し側のモデルを借りることがサーバーの存在理由になっている場合です。この機能はsessionless設計へ移植されず、公式も3系に留まるよう案内しています。書き換えるならサーバー側で自前のLLM接続を持つ構成に変わり、モデル選択とコスト負担の主体が移ります。設計判断であって作業ではありません。第2に、pydanticを2.12へ、FastAPIを0.133.0へ引き上げられない基盤です。他ライブラリとの版の噛み合わせで止まるなら、そこを先に解きます。第3に、httpxを直接扱う自作クライアントやテストダブルを広く抱えている場合です。httpx2への切り替えは修正箇所が散らばりやすく、ベータ追従と同時に走らせる作業量ではありません。

ベータ期間中の検証環境を作る手順と安定版までの進め方の判断目安

据え置く判断をした案件でも、検証だけは先に置いておくと安定版の到着時に慌てずに済みます。手順は3段に分かれます。まず本番から切り離したブランチで4.0.0b1を完全にピン留めし、uvならconstraint-dependenciesまで記載が必要です。次に削除された3つのContextメソッドと改名されたサーバーAPIをgrepし、当たった件数は移行工数の見積もりとして記録対象です。最後に互換ブリッジを切った状態でテストを流し、snake_case化の取りこぼしを洗い出します。ここまでで移行工数の輪郭が出るため、四半期の計画に載せられます。MCPサーバーの設計と運用を外部の体制に置く選択を検討しているなら、生成AI開発・AI受託開発のように実装から運用まで委託できる範囲と自社で持つ範囲を先に切り分けておくと、版の追従コストを含めた見積りがぶれません。

よくある質問

移行判断でよく問われる論点を、公式ドキュメントとパッケージメタデータの実測に沿って整理します。

FastMCP 4はもう正式リリースされていますか?

2026年7月30日時点では正式版は出ていません。GitHubのリリースタグではv4.0.0b1がpre-release表示で2026年7月28日に公開されており、PyPIのinfo.versionは3.4.5のままです。pip install fastmcpを素で実行すると3系が入るため、4系を試すにはpip install "fastmcp==4.0.0b1"のように版を明示します。

3系のコードは4系でそのまま動きますか?

デコレータでツールを定義しているだけの実装なら、ほぼそのまま動きます。止まるのはctx.sample()ctx.sample_step()ctx.list_roots()を呼んでいる箇所で、これらは全プロトコル世代から削除されました。ほかにMcpErrorの生成、httpxを直接扱う箇所、as_proxy()などの改名されたサーバーAPIが修正対象になります。フィールド名のsnake_case化は互換ブリッジが警告付きで吸収します。

sessionless対応にすると既存のクライアントは接続できなくなりますか?

接続可能です。4系のサーバーは握手世代とsessionless世代の両方を話し、接続時に双方が扱える最も新しい世代へ寄せます。クライアント側の既定はmode="auto"で、握手世代へ固定したいときだけmode="legacy"を指定します。世代ごとにサーバー実装を分岐させる必要はありません。

3系で書いていた task=True はそのまま使えますか?

登録が1行必要です。4系ではタスク機能が拡張として切り出されたため、pip install "fastmcp[tasks]"で導入し、mcp.add_extension(TasksExtension())を書いてから@mcp.tool(task=True)が効きます。既定のバックエンドはmemory://で単一プロセス限定なので、複数レプリカで動かすならRedisまたはValkey互換のURLを指定します。

いつ移行するのが妥当ですか?

水平スケール、バックグラウンドタスク、client credentials認証のいずれかを必要としているなら、検証環境での確認を今から始める価値があります。そうでなければ安定版の4.0.0を待ち、その間に削除APIと改名APIのgrepだけ済ませて工数を見積もっておく進め方が現実的です。samplingがサーバーの中心機能になっている実装は、移行そのものが設計変更になるため別扱いで検討します。

関連記事

資料請求

RELATED POSTS 関連記事