This is a dumb issue; but it hit me and it took a day to figure out what was wrong with my MCP Server.
I went deep and even started wondering if there was some kind of regression w/ OpenAI because things worked fine in local testing with PostMan.
TL;DR;, don't have the same sse-endpoint and sse-message-endpoint values.
Expected Behavior This should fail startup validation.
ai:
mcp:
server:
name: "example-mcp"
sse-message-endpoint: /sse
sse-endpoint: /sse
This should ALSO fail validation.
ai:
mcp:
server:
name: "example-mcp"
sse-message-endpoint: /sse
Current Behavior
If one just defines the spring.ai.mcp.server.sse message-endpoint as, "/sse" the server will start-up fine, and SOME MCP-Clients will work while others won't.
Because this is actually a breaking issue where the MCP clients will get back HTTP 400 status codes about the SessionID not being present it's really confusing to debug. Adding validation here will help prevent others from wasting time with a configuration whoopsie.
Context
I discovered that the OpenAI MCP-Client version 1.0.0 appears to not be sending a Session ID in its subsequent requests resulting in HTTP Status Code 400 errors.
In order to be compatible with other MCP-Server implementations at my org I thought I needed to support the Stateless transport. That transport already exists at WebMvcStatelessServerTransport.java so that seemed reasonable. That was a red herring.
Sample request payload from OpenAI's MCP-Client:
{
"jsonrpc": "2.0",
"method": "initialize",
"id": 1,
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {
"name": "openai-mcp",
"version": "1.0.0"
}
}
}
Note that sessionId parameter is missing resulting in a 400 status code
{"cause":null,"stackTrace":[{"classLoaderName":null,"moduleName":null,"moduleVersion":null,"methodName":"handleMessage","fileName":"WebMvcSseServerTransportProvider.java","lineNumber":359,"className":"io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider","nativeMethod":false}
....
"localizedMessage":"Session ID missing in message endpoint"}