-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
When using spring-ai-mcp (tested with 1.1.0-M3), the ToolContext values provided by the MCP client are not correctly propagated to the MCP server’s @tool method.
This causes the ToolContext parameter injected into the tool method to lose the original client context, such as tokens or metadata.
Reproduction Steps
✅
MCP Client Code
chatClient.prompt()
.toolContext(Map.of("token", request.getToken()))
.user(request.getMessage())
.stream()
.content()
.subscribe();
The client sets a token inside toolContext, expecting the MCP server to receive it.
❌
MCP Server Tool
@Tool(description = "Calculate financial statistics for a user")
public String calculateUserStatistics(Long createdByUserId, ToolContext toolContext) {
// toolContext should contain "token" from client, but it’s missing
System.out.println("Received ToolContext: " + toolContext);
...
}
On the server side, the toolContext received by the @tool method does not contain the client-provided values (e.g. "token").
Root Cause Analysis
In the class
org.springframework.ai.mcp.McpToolUtils#toSharedSyncToolSpecification
the current code creates a new ToolContext as follows:
new ToolContext(Map.of(TOOL_CONTEXT_MCP_EXCHANGE_KEY, exchangeOrContext))
However, it does not include the meta field from the CallToolRequest (which contains the client’s tool context).
So the original client-provided ToolContext is completely ignored.
Expected Behavior
The ToolContext passed into the tool callback should merge both:
- the existing MCP exchange context (TOOL_CONTEXT_MCP_EXCHANGE_KEY), and
- the meta values from CallToolRequest (coming from the MCP client).
Proposed Fix
Modify McpToolUtils#toSharedSyncToolSpecification() to merge the client context:
Map<String, Object> mergedContext = new HashMap<>();
mergedContext.put(TOOL_CONTEXT_MCP_EXCHANGE_KEY, exchangeOrContext);
if (request.meta() != null) {
mergedContext.putAll(request.meta());
}
ToolContext toolContext = new ToolContext(mergedContext);
String callResult = toolCallback.call(
ModelOptionsUtils.toJsonString(request.arguments()), toolContext);
This will ensure that any context values set on the MCP client (via .toolContext(...)) are correctly available on the server.
Environment
- Spring AI version: 1.1.0-M3
- Java version: 25
- MCP client: Spring AI MCP Client
- MCP server: Spring AI MCP Server