spring-projects / spring-projects/spring-ai
transportContext is the default empty context McpTransportContext.EMPTY because WebMvcStreamableServerTransportProvider.Builder.contextExtractor is not set
@mehrdadbozorgmehr is already working on this.
Since Oct 23, 2025.
- Dominant language
- Java
- Stars
- 9.5k
- Forks
- 2.9k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 6
Description
when i use ToolContext in tool method i always get a null value from transportContext , and i found that the McpTransportContext.EMPTY has set by default in WebMvcStreamableServerTransportProvider Builder class
issue description
WebMvcStreamableServerTransportProvider initialized in McpServerStreamableHttpWebMvcAutoConfiguration like this :
public WebMvcStreamableServerTransportProvider webMvcStreamableServerTransportProvider(
ObjectProvider<ObjectMapper> objectMapperProvider, McpServerStreamableHttpProperties serverProperties) {
ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new);
return WebMvcStreamableServerTransportProvider.builder()
.jsonMapper(new JacksonMcpJsonMapper(objectMapper))
.mcpEndpoint(serverProperties.getMcpEndpoint())
.keepAliveInterval(serverProperties.getKeepAliveInterval())
.disallowDelete(serverProperties.isDisallowDelete())
.build();
}
but whitout setting contextExtractor , this leads to a default empty McpTransportContext set in WebMvcStreamableServerTransportProvider
Environment
spring-ai-bom version is 1.1.0-M1
modelcontextprotocol java-sdk version is 0.12.1
public static class Builder {
// default empty McpTransportContext
private McpTransportContextExtractor<ServerRequest> contextExtractor = (serverRequest) -> McpTransportContext.EMPTY;
.......
}
Steps to reproduce
- set a header named 'xxxx' with value '123456' for streamable request
- get header value from ToolContext.transportContext
Expected behavior
i expect to get the value 123456 of header 'xxxx' from transportContext but a null actually
Can I Add the ContextExtractor Setting in the WebMvcStreamableServerTransportProvider initialize just like this :
@Bean
@ConditionalOnMissingBean
public WebMvcStreamableServerTransportProvider webMvcStreamableServerTransportProvider(
ObjectProvider<ObjectMapper> objectMapperProvider, McpServerStreamableHttpProperties serverProperties) {
ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new);
// begin
McpTransportContextExtractor<ServerRequest> contextExtractor = (serverRequest) -> {
Map<String, Object> headersMap = new HashMap<>();
HttpServletRequest httpServletRequest = serverRequest.servletRequest();
Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerVal = httpServletRequest.getHeader(headerName);
headersMap.put(headerName, headerVal);
}
return McpTransportContext.create(headersMap);
};
// end
return WebMvcStreamableServerTransportProvider.builder()
.jsonMapper(new JacksonMcpJsonMapper(objectMapper))
.mcpEndpoint(serverProperties.getMcpEndpoint())
.keepAliveInterval(serverProperties.getKeepAliveInterval())
.disallowDelete(serverProperties.isDisallowDelete())
.contextExtractor(contextExtractor ) // set customize contextExtractor
.build();
}
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.
Assessment
This issue has not been assessed yet.