Skip to content

feat: supported McpServerSessionListener on SseSession events. #233

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

big-mouth-cn
Copy link

Motivation and Context

#59
#77

feat:

In the development of MCP in business systems, the SSE server usually needs to obtain client identity information, such as user information, when processing with the @tool tool. Currently, most MCP clients support passing user information through HTTP Headers, such as API KEY. However, the MCP SDK cannot pass HTTP Headers to the @tool method. Therefore, this change mainly supports this requirement.

fix:

In addition, it also fixes the issue where the keys and corresponding values of the sessions variable in WebMvcSseServerTransportProvider are inconsistent with the sessionId.

How Has This Been Tested?

with Spring-AI

McpWebFluxServerAutoConfiguration.java

@Bean
@ConditionalOnMissingBean
public WebFluxSseServerTransportProvider webFluxTransport(ObjectProvider<ObjectMapper> objectMapperProvider,
		McpServerProperties serverProperties,
		ObjectProvider<McpServerSessionListener<ServerRequest>> mcpServerSessionListeners) {
	ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new);
	WebFluxSseServerTransportProvider webFluxSseServerTransportProvider = new WebFluxSseServerTransportProvider(
			objectMapper, serverProperties.getSseMessageEndpoint(), serverProperties.getSseEndpoint());
	webFluxSseServerTransportProvider.setMcpServerSessionListener(mcpServerSessionListeners.getIfAvailable());
	return webFluxSseServerTransportProvider;
}

ToolProviderAutoConfiguration.java

@Configuration
public class ToolProviderAutoConfiguration {

    public static final Map<String, HttpHeaders> sessionHeaders = new ConcurrentHashMap<>();

    @Bean
    public ToolCallbackProvider toolCallbackProvider(WeatherToolProvider weatherToolProvider) {
        return MethodToolCallbackProvider.builder().toolObjects(weatherToolProvider).build();
    }

    @Bean
    public McpServerSessionListener<ServerRequest> mcpServerSessionListener() {
        return new McpServerSessionListener<>() {

            @Override
            public void onConnection(McpServerSession session, ServerRequest request) {
                HttpHeaders httpHeaders = request.headers().asHttpHeaders();
                sessionHeaders.put(session.getId(), httpHeaders);
            }

            @Override
            public void onMessage(McpServerSession session, ServerRequest request) {
            }
        };
    }
}

WeatherToolProvider.java

@Service
public class WeatherToolProvider {

    @Tool(name = "query_weather", description = "查询天气信息。")
    public String queryWeather(String city,
                               ToolContext toolContext) {
        Object o = toolContext.getContext().get("exchange");
        if (o instanceof McpSyncServerExchange) {
            String sessionId = ((McpSyncServerExchange) o).getSessionId();
            log.info("sessionId: {}", sessionId);

            HttpHeaders httpHeaders = ToolProviderAutoConfiguration.sessionHeaders.get(sessionId);
            log.info("httpHeaders: {}", httpHeaders);
        }

        return "今天晴转多云,18-26°C,东南风3-4级。";
    }
}

Breaking Changes

No need, add an interface, implementation is not necessary.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

After the change is merged, I will submit the auto configure code for spring-ai.

big-mouth-cn and others added 5 commits May 12, 2025 16:01
…ver, it supports handling business logic by implementing the McpServerSessionListener interface. Common scenarios include saving the mapping relationship between sessionId and Http Headers when establishing a connection, making it convenient to retrieve through sessionId during @tool calls.

fix:Resolve the issue of inconsistent sessionId between the keys of WebMvc sessions and the corresponding value object McpServerSession.
# Conflicts:
#	mcp/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java
@big-mouth-cn
Copy link
Author

Hi maintainers, this PR is ready to be merged but needs a workflow and code approval from someone with write access. Could someone please help review and approve it? Thanks! 🙏

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant