Skip to content

ToolContext from MCP Client is lost in Spring AI MCP Server #4773

@JamesSmith888

Description

@JamesSmith888

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:

  1. the existing MCP exchange context (TOOL_CONTEXT_MCP_EXCHANGE_KEY), and
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions