MCPには以前から、サーバーからクライアントへ構造化されたLog Messageを送るProtocol LevelのLogging機能がありました。
しかし2026年7月28日のMCP仕様で、このLogging機能はRoots・Samplingとともに非推奨になりました。
非推奨後も一定期間は動作しますが、新しくMCPサーバーを作るなら、この仕組みを前提に設計するのは避けたほうがよいでしょう。
この記事では、MCPのProtocol Level Loggingがなぜ非推奨になったのか、stdioとStreamable HTTPを問わずログをどこへ設計するべきか、代替として案内されているOpenTelemetryとの関係を解説します。stdioサーバーでstdoutとstderrを混同してはいけない理由そのものはMCPのstdioサーバーが接続できない原因で詳しく扱っているため、この記事ではTransportを問わないログ設計と、Protocol Loggingの非推奨化にしぼって解説します。
- MCPのProtocol Level Loggingとは
- 2026-07-28でLogging機能が非推奨になった
- ctx.infoやsendLoggingMessageを新規実装の中心にしない
- 非推奨は「今すぐ壊れる」という意味ではない
- stdioならstderr、という結論自体は変わらない
- Streamable HTTPならstdoutを通信路として使わない
- stdio/HTTP両対応サーバーではログ設計を統一する
- Requestの時間や失敗率を追いたいならOpenTelemetry
- stderrとOpenTelemetryはどちらか一方ではない
- 移行の優先順位を決める
- MCPサーバーのログはどこに出す?に関するよくある質問
- まとめ
MCPのProtocol Level Loggingとは
MCPには、サーバーがlogging Capabilityを宣言すると、構造化されたLog MessageをMCP Clientへ通知できる仕組みが以前から存在します。
代表的なMethodや通知が次のものです。
logging/setLevel notifications/message
クライアントはlogging/setLevelでサーバーへ受け取りたいLog Levelを指定し、サーバーはnotifications/messageでdebug、info、warning、errorなどのSeverityを持つログをProtocol経由で送信できます。
開発者がターミナルへ書くstderrログとは別に、MCP Client自身がログを受け取って表示・保存できるようにするための仕組みです。
2026-07-28でLogging機能が非推奨になった
2026年7月28日のMCP仕様では、Roots・Sampling・Loggingの3つの機能がまとめて非推奨になりました。
MCP公式では、この非推奨化にあわせて移行先も案内されています。
Roots → Toolの引数やServer設定でディレクトリやファイルを渡す Sampling → LLM Provider APIと直接統合する Logging → stdioはstderrへ、構造化されたObservabilityはOpenTelemetryへ
つまりLoggingについては、「Protocol経由でクライアントへログを送る」という設計そのものから離れ、stdio Transportではstderrを使い、本格的な監視が必要ならOpenTelemetryを使うという方向に整理されています。
非推奨は機能を仕様上の「Deprecated」状態にするものであり、最低12ヶ月の非推奨期間中は動作が保証されます。今すぐ動かなくなるわけではありませんが、新規実装の前提にするべきではありません。
ctx.infoやsendLoggingMessageを新規実装の中心にしない
古いMCPサンプルを検索すると、次のようなコードが見つかる場合があります。
await ctx.info(...)
server.sendLoggingMessage(...);
これらはProtocol経由でMCP ClientへLog Notificationを送るためのAPIです。
TypeScript SDKでは、Server.sendLoggingMessageやMcpServer.sendLoggingMessage、Handler Context上のctx.mcpReq.logなどがDeprecated Annotationの対象になっています。
ただし、これは「呼び出すと即座にエラーになる」という意味ではありません。既存のRuntime APIはv1時代と同じ呼び出し方・同じWireの挙動のまま残り、非推奨期間中は引き続き利用できます。
新しくMCPサーバーを作るなら、
logger.info(...)
のような通常のApplication Loggingを基本にしたほうが、将来のProtocol変更の影響を受けにくくなります。
非推奨は「今すぐ壊れる」という意味ではない
Deprecated化はAnnotationレベルの変更であり、既存コードのWire上の挙動はそのまま残ります。
そのため、
すでにctx.info()やsendLoggingMessage()を使ってデプロイ済みのMCPServer
があっても、慌てて書き換える必要はありません。
気をつけるべきなのは、
これから作るMCP ServerでもProtocol Loggingを中心に設計する
ことです。ここを避けておけば、将来Logging Subsystemが実際に削除されたときの移行コストを抑えられます。
stdioならstderr、という結論自体は変わらない
Protocol Loggingが非推奨になっても、stdio TransportでのApplication Loggingの原則は変わりません。
stdoutはJSON-RPC Messageの通信路であり、通常のログはstderrへ出します。
Pythonなら標準のloggingモジュール、Node.jsやTypeScriptならconsole.error()やLogging Libraryを使い、stdoutを汚さないようにします。
この基本ルールと、import時の出力混入やバッファリングされたprint()の挙動など、stdio特有の落とし穴はMCPのstdioサーバーが接続できない原因|stdoutにログを出してはいけない理由にまとめています。
Streamable HTTPならstdoutを通信路として使わない
stdioとStreamable HTTPではログの考え方が異なります。
Streamable HTTPではMCP MessageがHTTP RequestとResponseを通して送られます。MCP Serverは独立したHTTP Serverとして動作し、単一のMCP EndpointでPOSTなどを処理します。stdioとStreamable HTTPの構成の違いそのものはMCPのstdioとStreamable HTTPの違いで解説しています。
そのためstdioのように、
stdoutへログを書くとJSON-RPC Streamが壊れる
という構造ではありません。
Web Serverとして動作しているPythonアプリなら、そのFrameworkやApplication Loggerを利用できます。
logger.info("MCP HTTP request received")
Node.jsでも通常のApplication Logging Infrastructureを利用できます。
ただし本番運用では、単純にconsole.log()へ大量のログを出すより、構造化LoggingやCloud Logging Service、OpenTelemetryを利用したほうが追跡しやすくなります。
stdio/HTTP両対応サーバーではログ設計を統一する
同じMCP ServerをstdioとStreamable HTTPの両方で動かす場合は、Transportを意識しなくても安全なLogging設計にしておくと便利です。
Pythonなら標準Loggingを共通で使えます。
logger = logging.getLogger(__name__)
stdioではstderrへ出します。Streamable HTTPの本番環境では、HandlerをCloud LoggingやFile、OpenTelemetry Collectorなどへ変更できます。
Toolコード自体には、
logger.info(...)
だけを書き、出力先はApplication設定で切り替える構造にしておけば、Tool実装側で「stdioだからstderr」「HTTPだから別Logger」と分岐する必要がありません。
Requestの時間や失敗率を追いたいならOpenTelemetry
「ログをどこに出すか」と考えているものの、本当に欲しいのが、
どのToolに何msかかったか どのRequestでエラーになったか 外部APIに何msかかったか
という情報なら、通常の文字列LogよりTracingのほうが適している場合があります。
MCPのLogging機能が非推奨になった際、代替として案内されている先もOpenTelemetryです。すべてのRequest、所要時間、成功・失敗を追跡したいなら、Log LineではなくSpanという単位で記録する設計に切り替えます。
単純な開発ログならstderrで十分ですが、本番のMCP Serverを複数台・長期間運用するならOpenTelemetryの導入も検討する価値があります。
stderrとOpenTelemetryはどちらか一方ではない
stderrとOpenTelemetryは競合するものではありません。
開発中はstderrへ、
INFO server started DEBUG tool registered ERROR API request failed
と出して素早く確認できます。
本番環境ではOpenTelemetryで、
Request Trace Tool Call Span 外部HTTP Request Database Query Error Latency
を追跡します。さらに重大なApplication Errorだけ通常LoggerからCloud Loggingへ送る構成もできます。
MCPだから特殊なLogging Systemを作る必要はありません。一般的なWeb ApplicationやBackend Serverと同じようにLoggingとTracingを分け、stdioを利用するときだけ「stdoutをProtocol専用にする」という制約を追加すると考えると分かりやすくなります。
移行の優先順位を決める
すでに稼働しているMCP Serverがctx.info()やsendLoggingMessage()を使っていても、非推奨期間中は動作するため、緊急に書き換える必要はありません。
優先して見直したいのは次の順番です。
1. これから新規に作るMCP ServerでProtocol Loggingを使わない 2. stdioの既存サーバーでstdoutへのログ混入がないか確認する 3. 本番監視が必要なサーバーからOpenTelemetry導入を検討する 4. 既存のProtocol Logging依存コードは12ヶ月の非推奨期間中に計画的に移行する
すべてを一度に変える必要はなく、まず新規実装から通常のApplication Loggingへ寄せていくだけでも、将来のProtocol変更に振り回されにくくなります。
MCPサーバーのログはどこに出す?に関するよくある質問
QMCPのProtocol Level Loggingは今すぐ使えなくなりますか
Aすぐには使えなくなりません。2026-07-28での非推奨化はAnnotationレベルの変更で、既存のRuntime APIは同じ呼び出し方・同じWireの挙動のまま、最低12ヶ月の非推奨期間中は動作します。ただし新規実装の前提にするのは避けたほうがよいです。
Qctx.info()やsendLoggingMessage()を使っている既存サーバーはどうすればよいですか
A非推奨期間中は動作するため、慌てて書き換える必要はありません。次にサーバーを大きく手直しするタイミングで、通常のApplication Logging(stdioならstderr、HTTPなら通常のWebアプリのLogger)へ寄せていくのが現実的です。
QProtocol Loggingの代わりに何を使えばよいですか
AMCP公式の移行方針では、stdio Transportでは開発者向けログをstderrへ出し、本格的なObservabilityが必要な場合はOpenTelemetryを利用する方向が案内されています。単純な開発ログと、Request単位のTracingを分けて考えると設計しやすくなります。
QstdioとStreamable HTTPでログの出し方は同じでよいですか
A出力先は異なります。stdioではstdoutがJSON-RPCの通信路のためログはstderrへ出す必要がありますが、Streamable HTTPではstdoutが通信路ではないため、一般的なWebアプリケーションと同じLogging Infrastructureを使えます。両対応するサーバーでは、Loggerの呼び出し方を共通化し、出力先だけをTransportや環境設定で切り替える設計が安全です。
Qstderrへログを出していれば、OpenTelemetryは不要ですか
A小規模な開発中はstderrだけでも十分です。ただし複数のMCP Serverを本番で長期運用し、どのToolに何msかかったか、どのRequestで失敗したかを追跡したい場合は、ログ行よりSpan単位で記録できるOpenTelemetryのほうが適しています。stderrとOpenTelemetryは併用できます。
QMCPサーバーだから専用のロギング設計が必要ですか
A専用の仕組みを新たに作る必要はありません。一般的なWebアプリケーションやバックエンドサービスと同じようにLoggingとTracingを分けて設計し、stdio Transportを使うときだけ「stdoutをMCP Protocol専用にする」という制約を追加する、という考え方で十分です。
Q非推奨化の対象はLoggingだけですか
Aいいえ。2026-07-28の仕様では、Roots・Sampling・Loggingの3つの機能がまとめて非推奨になりました。Rootsの代わりにToolの引数やServer設定でディレクトリやファイルを渡す、Samplingの代わりにLLM Provider APIと直接統合するといった移行方針がそれぞれ案内されています。
まとめ
MCPのProtocol Level Loggingは、2026年7月28日の仕様でRoots・Samplingとともに非推奨になりました。
非推奨化はAnnotationレベルの変更で、既存コードはすぐには壊れませんが、新規にMCP Serverを作るならctx.info()やsendLoggingMessage()を中心に設計するのは避けるべきです。
移行方針としては、stdio Transportでは通常のApplication Loggingをstderrへ、本格的なObservabilityが必要な場合はOpenTelemetryへという整理になっています。
stdio・Streamable HTTPのどちらで動かす場合でも、MCP特有の専用ロギングシステムを新たに作る必要はなく、一般的なWebアプリケーションと同じLoggingとTracingの設計に、Transportごとの制約を1つ加えるだけで十分です。
stdioでのstdout/stderrの具体的な落とし穴はMCPのstdioサーバーが接続できない原因を、stdioとStreamable HTTPの選び方はMCPのstdioとStreamable HTTPの違いをあわせて参考にしてください。

