Server Errors During Baseline SSE Test (am I doing something wrong?)
note: clarified and formatted by AI, but the person asking is human!
This bug was identified during baseline testing for a project aimed at modifying the graphiti/mcp_server/graphiti_mcp_server.py script to support multiple LLM providers (OpenAI and Gemini) based on configuration. The goal is to establish a working baseline using the original script before introducing modifications. This test specifically focuses on the OpenAI provider using SSE transport.
Summary
When running the original graphiti/mcp_server/graphiti_mcp_server.py script with SSE transport (--transport sse) and interacting with it using a standard MCP client flow, the server encounters internal validation and runtime errors upon receiving POST requests (initialize, tools/call) on the dynamically provided /messages/... endpoint. This prevents successful processing of client requests.
Environment
-
Server Script:
graphiti/mcp_server/graphiti_mcp_server.py(baseline version from repository) -
Library:
mcp==1.5.0(as specified ingraphiti/mcp_server/uv.lock) -
Core Library:
graphiti-core==0.8.2(with temporary debug logging added toutils/bulk_utils.py) - Python: 3.11
-
Virtual Env:
/path/to/tools/mcp-graphiti/.venv(managed withuv) - Transport: SSE
-
LLM Config: OpenAI (
MODEL_NAME=gpt-4o-mini) - Database: Neo4j (cleared before test)
-
Client: Custom test harness (
mcp_test_harness.py) developed during testing, implementing the standard MCP SSE client flow.
Reproduction Steps
-
Prepare Environment:
- Ensure Neo4j is running and accessible.
- Activate the virtual environment:
source /path/to/tools/mcp-graphiti/.venv/bin/activate - Export necessary environment variables:
NEO4J_PASSWORD,OPENAI_API_KEY,MODEL_NAME="gpt-4o-mini". - Clear Neo4j database:
MATCH (n) DETACH DELETE n;
-
Start Server:
- From the repository root (
/path/to/Documents/Code/graphiti-debug), run:uv run python graphiti/mcp_server/graphiti_mcp_server.py --transport sse - Observe server logs (listens on
0.0.0.0:8000).
- From the repository root (
-
Run Client (Test Harness):
- In a separate terminal (with venv activated), run the debugged test harness:
python /path/to/tools/mcp-graphiti/mcp_test_harness.py http://localhost:8000/sse "OpenAI Baseline Test" "Testing the original server script with OpenAI."
- In a separate terminal (with venv activated), run the debugged test harness:
Expected Behavior
- Client connects via GET to
http://localhost:8000/sse. - Server sends an "endpoint" event with data like
/messages/?session_id=.... - Client sends
initializerequest via POST to the received endpoint URL (e.g.,http://localhost:8000/messages/?session_id=...). - Server returns
202 Acceptedfor the POST request. - Server sends the
initializeresult via a "message" event on the original/ssestream. - Client receives the
initializeresult, confirms initialization. - Client sends
tools/callrequest (foradd_episode) via POST to the same endpoint URL. - Server returns
202 Acceptedfor the POST request. - Server processes the
add_episoderequest (including calls tographiti-coreand Neo4j). - Server potentially sends
tools/resultor other notifications via the/ssestream. - Data corresponding to the "OpenAI Baseline Test" episode appears in Neo4j.
- Temporary debug logs from
graphiti_core/utils/bulk_utils.pyappear in server output.
Actual Behavior
- Steps 1-5 occur as expected according to client logs.
-
Server Error 1: When processing the
initializePOST request, the server logs apydantic_core._pydantic_core.ValidationError: 23 validation errors for ClientRequest. The traceback indicates the validation occurs inmcp/shared/session.pyin the_receive_loopand fails because theinitializepayload (aServerRequesttype) is being validated against theClientRequestschema union. - Steps 6-8 occur as expected according to client logs (client receives
initializeresult on/sse, sendstools/callPOST, server returns202 Accepted). -
Server Error 2: When processing the
tools/callPOST request, the server logs aRuntimeError: Received request before initialization was complete. This is likely because the previousValidationErrorprevented the server session from correctly transitioning to an initialized state. - The
add_episodelogic does not execute. - No data is added to Neo4j.
- No temporary debug logs from
graphiti_core/utils/bulk_utils.pyappear in server output. - The client script finishes, reporting success based on receiving
202 Acceptedfor both POST requests (as per latest harness logic).
Analysis / Hypothesis
The root cause of the ValidationError appears to be a mismatch in how the mcp==1.5.0 library handles validation for POST requests received during an SSE session in this specific setup.
- Traceback suggests the
mcp.server.sse.SseServerTransport.handle_post_messagefunction receives the POST request on the/messages/...endpoint. It likely performs an initial validation/parsing against a generic message type (e.g.,JSONRPCMessage). - This parsed object seems to be passed to the
mcp.shared.session.ServerSession._receive_loop. - The
_receive_loop, however, expects to perform validation itself using the specificServerRequestschema union (which includesInitializeRequest,CallToolRequest, etc.). - When
_receive_loopattempts to validate the already parsed generic object against the specificServerRequestschema, aValidationErroroccurs because the structures don't match perfectly at this stage (e.g., the generic object lacks the specific fields required byInitializeRequest.params). - This validation failure prevents the server session state from being correctly updated to "initialized".
- Consequently, when the subsequent
tools/callPOST request arrives and is processed by the session loop, it triggers theRuntimeError: Received request before initialization was complete.
While the graphiti/mcp_server/graphiti_mcp_server.py script appears to use the library's public API correctly, this internal validation mismatch within the library's SSE handling for POST requests prevents the baseline script from functioning as expected with SSE transport. It's unclear if this is an inherent library bug for SSE POST handling or if there's a subtle configuration nuance missed in the baseline script that avoids this path in other working SSE implementations (like the custom Gemini script).
Conclusion / Question
The identified validation mismatch within the mcp==1.5.0 library's SSE transport layer prevents the baseline graphiti/mcp_server/graphiti_mcp_server.py script, as currently configured, from successfully processing client requests received via POST on the /messages/... endpoint.
Question for Developers: Given that other SSE implementations using this library reportedly work, what is the correct way to configure or use FastMCP and ServerSession in mcp==1.5.0 (or 1.6.0) to avoid this validation mismatch for POST requests received during an SSE session? Is there a specific configuration pattern in the server script or a nuance in the library interaction that the baseline script is missing?
attached is my test harness, maybe it will help identify the mistake I'm making.
Thanks for the detailed bug report. I'm investigating.
@CaliLuke it doesn't appear your harness is correctly waiting for the MCP connection to be established prior to using a tool.
It looks like you're using httpx_sse rather than using the MCP SSE client. Please would you try using the MCP SDK?
See: https://modelcontextprotocol.io/docs/concepts/transports#python-client
async with sse_client("http://localhost:8000/sse") as streams:
async with ClientSession(streams[0], streams[1]) as session:
await session.initialize()