Title: FastMCP server with SSE transport fails to shut down on a signal · Issue #514 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: FastMCP server with SSE transport fails to shut down on a signal · Issue #514 · modelcontextprotocol/python-sdk
X Title: FastMCP server with SSE transport fails to shut down on a signal · Issue #514 · modelcontextprotocol/python-sdk
Description: A very simple server fails to shut down on a signal if it processed at least one request: ❯ python test-server.py --port=8085 INFO: Started server process [216035] INFO: Waiting for application startup. INFO: Application startup complete...
Open Graph Description: A very simple server fails to shut down on a signal if it processed at least one request: ❯ python test-server.py --port=8085 INFO: Started server process [216035] INFO: Waiting for application sta...
X Description: A very simple server fails to shut down on a signal if it processed at least one request: ❯ python test-server.py --port=8085 INFO: Started server process [216035] INFO: Waiting for application sta...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/issues/514
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"FastMCP server with SSE transport fails to shut down on a signal","articleBody":"A very simple server fails to shut down on a signal if it processed at least one request:\n\n```\n❯ python test-server.py --port=8085\nINFO: Started server process [216035]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:8085 (Press CTRL+C to quit)\nINFO: 127.0.0.1:55188 - \"GET /sse HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:55192 - \"POST /messages/?session_id=e690de9733914d09aebf2b0e8c78191c HTTP/1.1\" 202 Accepted\nINFO: 127.0.0.1:55192 - \"POST /messages/?session_id=e690de9733914d09aebf2b0e8c78191c HTTP/1.1\" 202 Accepted\nINFO: 127.0.0.1:55192 - \"POST /messages/?session_id=e690de9733914d09aebf2b0e8c78191c HTTP/1.1\" 202 Accepted\nProcessing request of type CallToolRequest\n^CINFO: Shutting down\nINFO: Waiting for background tasks to complete. (CTRL+C to force quit)\n```\n\nThe expected behaviour would be:\n\n```\n❯ python test-server.py --port=8085\nINFO: Started server process [216006]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:8085 (Press CTRL+C to quit)\n^CINFO: Shutting down\nINFO: Waiting for application shutdown.\nINFO: Application shutdown complete.\nINFO: Finished server process [216006]\n```\n\nHere is the code for both the server and the client.\n\nWhat do I miss?\n\nthe server\n\n```\nimport click\nimport sys\nfrom pydantic import Field\nfrom mcp.server.fastmcp import FastMCP\n\n@click.command()\n@click.option(\"--port\", default=8085, help=\"Port to listen\", type=int)\ndef main(port: int):\n mcp = FastMCP(\n \"mcp-echo-tool\",\n debug=True,\n log_level=\"INFO\",\n port=port,\n )\n\n @mcp.tool(name=\"echo\")\n async def echo_tool(string: str = Field(description=\"A string to echo back\")) -\u003e str:\n \"\"\"Echoes back the input string\"\"\"\n return string\n\n mcp.run(transport='sse')\n return 0\n\nif __name__ == \"__main__\":\n sys.exit(main())\n```\n\nand the client\n\n```\nimport asyncio\nimport click\nimport sys\nfrom mcp.client.session import ClientSession\nfrom mcp.client.sse import sse_client\n\nasync def client(url, string):\n async with sse_client(url) as (read, write):\n async with ClientSession(read, write) as session:\n await session.initialize()\n result = await session.call_tool(\"echo\", {\"string\": string})\n print(result.content)\n\n@click.command()\n@click.option('--url', default='http://localhost:8085', help='MCP Server URL', type=str)\n@click.argument('string', type=str)\ndef main(url: str, string: str):\n asyncio.run(client(url, string))\n\nif __name__ == \"__main__\":\n sys.exit(main())\n```\n\n","author":{"url":"https://github.com/growler","@type":"Person","name":"growler"},"datePublished":"2025-04-14T21:46:41.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":11},"url":"https://github.com/514/python-sdk/issues/514"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:e155ee0a-57c0-e15e-4a3d-3edbf84fe88f |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | CDA6:2D8BE0:44B3AD:59E130:6A5FF2CC |
| html-safe-nonce | d55918b72e4bc64f9232441946127831ffbd46fdf4ace08e14ae8b4dbcca0bac |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDREE2OjJEOEJFMDo0NEIzQUQ6NTlFMTMwOjZBNUZGMkNDIiwidmlzaXRvcl9pZCI6IjM5NzE4NjA2MTc4NDA1MjQyOCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | ca2675ecb5f9ddeec153ae77d1d4fb4b84e2cacc484f55cd56e1949c497fb3e2 |
| hovercard-subject-tag | issue:2994309207 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/modelcontextprotocol/python-sdk/514/issue_layout |
| twitter:image | https://opengraph.githubassets.com/aae363a129508888ef64653a52480f8e1ffdae05582f1e863ac9e38e2584d9a6/modelcontextprotocol/python-sdk/issues/514 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/aae363a129508888ef64653a52480f8e1ffdae05582f1e863ac9e38e2584d9a6/modelcontextprotocol/python-sdk/issues/514 |
| og:image:alt | A very simple server fails to shut down on a signal if it processed at least one request: ❯ python test-server.py --port=8085 INFO: Started server process [216035] INFO: Waiting for application sta... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | growler |
| hostname | github.com |
| expected-hostname | github.com |
| None | ec26f1a08b78b3d576999ee8b45a2abc017c95dbee903a8019940cd2e9bf7b3d |
| turbo-cache-control | no-preview |
| go-import | github.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 862584018 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/python-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 862584018 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/python-sdk |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 0a29f0b91ade2368fc0b74327c0f64ec1f98f5ff |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width