Received request before initialization was complete
Description
I’m encountering the same issue as described here: https://github.com/modelcontextprotocol/python-sdk/issues/423
Example Code
Version Information
2.3.0
Additional Context
No response
Is this different than the bug reported in the low-level SDK, or does the traceback relate to FastMCP?
I was working with the MCP Python SDK and migrated to FastMCP. During the process, I confirmed that the same error also occurs in FastMCP.
I understand that you encountered the error using FastMCP, but FastMCP's low-level server instance is the same as the one in the MCP SDK, so unless there is something FastMCP-related in a traceback, this issue should only be opened on the low-level repo (e.g. # 423) because it probably can not be solved here.
@jlowin I’ve documented the issues I encountered while using the FastMCP SSE version.
After reviewing the comments and logs above, I believe this issue does indeed originate from the mcp.server path in the MCP Python SDK.
Python sse_app example code
uv run uvicorn main:app --host 127.0.0.1 --port 9000 --reload
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastmcp import FastMCP
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
mcp = FastMCP('agent-server')
@mcp.tool(
name="add",
description="add function",
)
def add(a:int, b:int):
return a+b
app.mount("/", mcp.sse_app())
Experiment code
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>MCP SSE Client</title>
</head>
<body>
<h1>SSE MCP Experiment</h1>
<pre id="log"></pre>
<script src="./common.js"></script>
</body>
</html>
// common.js
let isInitialized = false;
const host = "http://localhost:9000";
const log = (msg) => {
document.getElementById("log").textContent += msg + "\n";
};
const $fetch = (path, body) => {
return fetch(path, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
};
const eventSource = new EventSource(
`${host}/sse?transportType=sse&url=${host}/sse`
);
eventSource.onopen = () => {
log("✅ SSE Connected");
};
eventSource.onerror = (err) => {
log("❌ Error: " + (err.message || JSON.stringify(err)));
};
eventSource.onmessage = (event) => {
log("📨 Server Message: " + event.data);
};
eventSource.addEventListener("endpoint", async function handler(event) {
if (isInitialized) return;
isInitialized = true;
const endpoint = event.data;
log("🛠️ server send endpoint: " + endpoint);
await fetch(host + endpoint, {
method: "POST",
body: JSON.stringify({
jsonrpc: "2.0",
id: 0,
method: "initialize",
params: {
protocolVersion: "2024-11-05",
capabilities: {
roots: {
listChanged: true,
},
tools: {
listChanged: true,
},
sampling: {},
},
clientInfo: {
name: "ExampleClient",
version: "1.0.0",
},
},
}),
}).then(async (response) => {
const text = await response.text();
log("✅ initialize:" + text);
});
await fetch(host + endpoint, {
method: "POST",
body: JSON.stringify({
method: "notifications/initializedialize",
jsonrpc: "2.0",
params: {},
}),
}).then(async (response) => {
const text = await response.text();
log("✅ notifications/initializedialize:" + text);
});
await fetch(host + endpoint, {
method: "POST",
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "tools/list",
params: {},
}),
}).then(async (response) => {
const text = await response.text();
log("✅ tools/list:" + text);
});
});
Error log
ERROR: Exception in ASGI application
+ Exception Group Traceback (most recent call last):
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 403, in run_asgi
| result = await app( # type: ignore[func-returns-value]
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
| return await self.app(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\fastapi\applications.py", line 1054, in __call__
| await super().__call__(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\applications.py", line 112, in __call__
| await self.middleware_stack(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
| raise exc
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
| await self.app(scope, receive, _send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\middleware\cors.py", line 93, in __call__
| await self.simple_response(scope, receive, send, request_headers=headers)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\middleware\cors.py", line 144, in simple_response
| await self.app(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
| await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
| raise exc
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
| await app(scope, receive, sender)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\routing.py", line 714, in __call__
| await self.middleware_stack(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\routing.py", line 734, in app
| await route.handle(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\routing.py", line 460, in handle
| await self.app(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\applications.py", line 112, in __call__
| await self.middleware_stack(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
| raise exc
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
| await self.app(scope, receive, _send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\fastmcp\server\http.py", line 59, in __call__
| await self.app(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
| await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
| raise exc
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
| await app(scope, receive, sender)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\routing.py", line 714, in __call__
| await self.middleware_stack(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\routing.py", line 734, in app
| await route.handle(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\routing.py", line 288, in handle
| await self.app(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\routing.py", line 76, in app
| await wrap_app_handling_exceptions(app, request)(scope, receive, send)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
| raise exc
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
| await app(scope, receive, sender)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\starlette\routing.py", line 73, in app
| response = await f(request)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\fastmcp\server\http.py", line 206, in sse_endpoint
| return await handle_sse(request.scope, request.receive, request._send) # type: ignore[reportPrivateUsage]
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\fastmcp\server\http.py", line 171, in handle_sse
| async with sse.connect_sse(scope, receive, send) as streams:
| File "C:\Users\nmins\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 217, in __aexit__
| await self.gen.athrow(typ, value, traceback)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\mcp\server\sse.py", line 128, in connect_sse
| async with anyio.create_task_group() as tg:
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\anyio\_backends\_asyncio.py", line 772, in __aexit__
| raise BaseExceptionGroup(
| exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Exception Group Traceback (most recent call last):
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\mcp\server\sse.py", line 147, in connect_sse
| yield (read_stream, write_stream)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\fastmcp\server\http.py", line 172, in handle_sse
| await server._mcp_server.run(
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\mcp\server\lowlevel\server.py", line 489, in run
| async with AsyncExitStack() as stack:
| File "C:\Users\nmins\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 714, in __aexit__
| raise exc_details[1]
| File "C:\Users\nmins\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 217, in __aexit__
| await self.gen.athrow(typ, value, traceback)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\fastmcp\server\server.py", line 87, in wrap
| yield context
| File "C:\Users\nmins\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 697, in __aexit__
| cb_suppress = await cb(*exc_details)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\mcp\shared\session.py", line 209, in __aexit__
| return await self._task_group.__aexit__(exc_type, exc_val, exc_tb)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\anyio\_backends\_asyncio.py", line 772, in __aexit__
| raise BaseExceptionGroup(
| exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\mcp\server\session.py", line 146, in _receive_loop
| await super()._receive_loop()
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\mcp\shared\session.py", line 349, in _receive_loop
| await self._received_request(responder)
| File "C:\workspaces\experiment_sse\.venv\lib\site-packages\mcp\server\session.py", line 171, in _received_request
| raise RuntimeError(
| RuntimeError: Received request before initialization was complete
+------------------------------------
Same here, but for stdio
same error
I think this is addressed by https://github.com/modelcontextprotocol/python-sdk/pull/1478