Skip to content

MCP Server and Vertex AI #2647

New issue

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

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

Already on GitHub? Sign in to your account

Closed
sidutti opened this issue Apr 5, 2025 · 5 comments
Closed

MCP Server and Vertex AI #2647

sidutti opened this issue Apr 5, 2025 · 5 comments
Assignees
Milestone

Comments

@sidutti
Copy link

sidutti commented Apr 5, 2025

Bug description
The MCP Server responds the results wrapped as List.
McpSchema.CallToolResult(List.of(new McpSchema.TextContent(callResult)), false);

When using the Vertex AI, the response is marshaled as a Struct (protobuf) which expects a MAP.

In the class VertexAiGeminiChatModel, method messageToGeminiParts when the message is ToolResponseMessage the response string is still being tried to be de-serialized as map. This throws an exception.

Environment
Spring AI Version: 1.0.0-SNAPSHOT
Java : 21

Steps to reproduce
MCP Server : Any ASYNC MCP Server
MCP Client with Vertex AI Chat Model

Expected behavior
The message when is a tool response and if it is an Array, should be mapped and the internal Map should be passed back to VertexAI

@bkowal
Copy link

bkowal commented Apr 9, 2025

I have been facing the very same issue. I'm also using Vertex AI and MCP client inside Spring AI. The response from MCP server that MCP client inside Spring AI receives seems to be correct. However, when this response is then prepared to be sent to Vertex AI, (VertexAiGeminiChatModel#jsonToStruct(String json)), only a part of the response from the MCP server is actually used. This part of the JSON response is the value of the "content" field. This value is a JSON array. A JSON array doesn't work well with VertexAiGeminiChatModel#jsonToStruct(String json) :-).

java.lang.RuntimeException: com.google.protobuf.InvalidProtocolBufferException: Expect a map object but found: [{"type":"text","text":"[{\"departureAirport\":\"AAA\",\"destinationAirport\":\"BBB\",\"departureDate\":\"2025-05-10\",\"arrivalDate\":\"2025-05-11\"}]"}]
        at org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel.jsonToStruct(VertexAiGeminiChatModel.java:380) ~[spring-ai-vertex-ai-gemini-1.0.0-M6.jar:1.0.0-M6]
        at org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel.lambda$messageToGeminiParts$1(VertexAiGeminiChatModel.java:340) ~[spring-ai-vertex-ai-gemini-1.0.0-M6.jar:1.0.0-M6]

I think, the source of this issue is:
org.springframework.ai.mcp.SyncMcpToolCallback#call:

public String call(String functionInput) {
		Map<String, Object> arguments = ModelOptionsUtils.jsonToMap(functionInput);
		CallToolResult response = this.mcpClient
			.callTool(new CallToolRequest(this.getToolDefinition().name(), arguments));
		return ModelOptionsUtils.toJsonString(response.content());
	}

The response looks more or less like this: { "content": [{...}], "isError": false }. Because ModelOptionsUtils.toJsonString(response.content()) uses content(), what is later sent to Vertex AI is [{...}].

As @sidutti wrote:
Expected behavior

The message when is a tool response and if it is an Array, should be mapped and the internal Map should be passed back to VertexAI

OR
org.springframework.ai.mcp.SyncMcpToolCallback#call should leave the original tool response as is (or should leave original response, but drop the "isError" field) instead of extracting the value of the "content" field.

@tzolov tzolov self-assigned this Apr 9, 2025
@vikasrangi
Copy link

hi Team,

I am also facing similar issue and using gemini 2.5 pro model. Any solutions for this bug in progress?

com.google.protobuf.InvalidProtocolBufferException: Expect a map object but found:

Also, similar bug is reported - #2849

@tzolov
Copy link
Contributor

tzolov commented May 2, 2025

@sidutti , thank you for reporting this issue.
Let me try to reproduce it.

@tzolov tzolov added this to the 1.0.0-RC1 milestone May 2, 2025
tzolov added a commit to tzolov/spring-ai that referenced this issue May 3, 2025
Improve the jsonToStruct method in VertexAiGeminiChatModel to handle JSON arrays
in addition to JSON objects. When a JSON array is detected, it's now properly
converted to a Protobuf Struct with an items field containing the array elements.

Resolves spring-projects#2647 , spring-projects#2849

Signed-off-by: Christian Tzolov <[email protected]>
@markpollack
Copy link
Member

please try the snapshots and reopen if it doesn't solve your issue.

@vikasrangi
Copy link

It's working. Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants