modelcontextprotocol / modelcontextprotocol/python-sdk

Server hangs when shutting down if a connection is still open

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

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

bug P1 ready for work
主要言語
Python
スター
24.3k
フォーク
4k
平均マージ
1日 1時間
マージ済み PR(30日)
31

説明

Initial Checks
Description

Hello!

I was testing my MCP server with the inspector npx @modelcontextprotocol/inspector using streamable-http and I noticed that if the inspector is connected, the MCP Server will not shutdown.

We can't keep the server running if a client forgot to disconnect right? This is tested with the official inspector tools, so there might be other clients working the same way.

Shouldn't the server close its active connections/tasks on shutdown?

Reproduction
  1. Run the server (see code snippet)
  2. In the MCP Inspector click "connect"
  3. In the server's terminal hit CTRL+C

At this point

  • The server shows Waiting for connections to close (CTRL+C to force quit) and CTRL+C doesn't work, in fact nothing works except killing the process
  • Clicking "Disconned" in the Inspector cannot disconnect, because Error in /mcp route: TypeError: fetch failed
Evidences

Shell execution

$ python demo-mcp.py                 
INFO:     Started server process [10749]
INFO:     Waiting for application startup.
[08/14/25 11:03:16] INFO     StreamableHTTP session manager started                                                                                                                                                                                 streamable_http_manager.py:110
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
[08/14/25 11:03:21] INFO     Created new transport with session ID: 4134f60ccda44baf8a01733ed94bc0d8                                                                                                                                                streamable_http_manager.py:233
INFO:     127.0.0.1:54629 - "POST /mcp HTTP/1.1" 200 OK
INFO:     127.0.0.1:54629 - "POST /mcp HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:54630 - "GET /mcp HTTP/1.1" 200 OK
^CINFO:     Shutting down
INFO:     Waiting for connections to close. (CTRL+C to force quit)

Inspector proxy Disconnect error

Received DELETE message for sessionId dd8a78d2-d5a8-4ff2-b679-6a8571f7cd0c
Connection refused. Is the MCP server running?
Error in /mcp route: TypeError: fetch failed
    at node:internal/deps/undici/undici:13502:13
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async StreamableHTTPClientTransport.terminateSession (file://.../.npm/_npx/5a9d879542beca3a/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js:355:30)
    at async file://.../.npm/_npx/5a9d879542beca3a/node_modules/@modelcontextprotocol/inspector/server/build/index.js:264:17 {
  [cause]: Error: connect ECONNREFUSED 127.0.0.1:8000
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1636:16) {
    errno: -61,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '127.0.0.1',
    port: 8000
  }
}
Mitigation

Setting the timeout_graceful_shutdown uvicorn config to a few seconds will eventually quit the process, BUT this is exiting with a non 0 exit code, which is an issue trying to run this in production. (This setting has been request here and currently available in FastMCP 2.0)

Example Code
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("demo")

@mcp.tool()
async def hello() -> str:
    return "world"

mcp.run(transport="streamable-http")
Python & MCP Python SDK
Python 3.12.8
mcp 1.12.4

Edit: reproduced with mcp 1.13.0

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

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

はじめの一歩

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

調査の方向性

提供された FastMCP streamable-http の例でシャットダウン動作を再現し、ログに示されている streamable_http_manager.py のセッション処理を調査します。シャットダウン中にアクティブな接続とタスクがどのように処理されるかを追跡し、その後、Inspector が接続されたまま CTRL+C で正常に終了することを確認します。

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

評価

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

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

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