spring-projects / spring-projects/spring-ai
MCP-Server -- Configuration Validation enforcement needed: The same sse-endpoint and the same sse-message-endpoint causes Session ID not found errors for some MCP Clients (OpenAI MCP-Client)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.5k
- Forks
- 2.9k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 6
Description
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"}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with WebMvcSseServerTransportProvider.java, especially the handleMessage path shown in the error, and compare it with WebMvcStatelessServerTransport.java. Trace where the MCP server's sse-endpoint and sse-message-endpoint properties are validated, then add coverage for both invalid configurations so startup rejects them.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100