modelcontextprotocol / modelcontextprotocol/java-sdk

Servlet transports block Tomcat thread

オープン
#859 コメント 1 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

needs confirmation
主要言語
Java
スター
3.7k
フォーク
1.1k
平均マージ
1日 15時間
マージ済み PR(30日)
9

説明

Bug Description

All Servlet-based transports in the SDK (e.g., HttpServletStreamableServerTransportProvider, HttpServletSseServerTransportProvider, HttpServletStatelessServerTransport) call .block() on the Tomcat request thread when processing incoming HTTP requests.

Although AsyncContext is used to hold connections for SSE/streaming, the Tomcat thread remains parked until tool execution completes. As a result, the reactive/async architecture does not provide any real thread efficiency: the request thread stays blocked for the entire duration of the tool call.

With SyncToolSpecification and immediateExecution=false, the tool handler is executed on a separate thread (typically from the boundedElastic pool). This prevents blocking logic from running on the Tomcat thread itself, but the request thread still remains blocked waiting for completion.

With AsyncToolSpecification(via McpAsyncServer), handlers are expected to return fully asynchronous operations (e.g., non-blocking I/O). However, because the transport calls .block(), the HTTP request handling remains synchronous. The handler is not automatically scheduled on another thread unless the developer explicitly does so.

As a result, both SyncToolSpecification and AsyncToolSpecification ultimately block the Tomcat request thread until completion.

I’m not sure if this behavior is intentional. Based on the design of McpAsyncServer, I would expect the transport layer to release the Tomcat thread immediately and allow the reactive pipeline to complete asynchronously. (AsyncContext + subscribe).

Image Image

@pratik2294

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

HttpServletStreamableServerTransportProvider、HttpServletSseServerTransportProvider、HttpServletStatelessServerTransport から始め、受信リクエストが .block() を呼び出す箇所と、AsyncContext がどのように使用されているかを追跡します。SyncToolSpecification と AsyncToolSpecification のパスを比較し、その後、リアクティブ操作が継続して正常に完了する間に、リクエストスレッドが解放されることを確認します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
java
領域
api, backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
48/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。