google / google/adk-java

McpTool drops structuredContent and non-text content from CallToolResult

Offen
#1,443 1 Kommentar 0 Reaktionen 1 zugewiesene Person Beansprucht von @hemasekhar-p Auf GitHub ansehen
needs review
Vorherrschende Sprache
Java
Sterne
1.7k
Forks
420
Ø Merge
4 T. 12 Std.
Gemergte PRs (30 T.)
31

Beschreibung

## 🔴 Required Information

**Describe the Bug:**

`AbstractMcpTool.wrapCallResult(...)` silently discards parts of a successful MCP `CallToolResult`.

When the result contains at least one `TextContent`, native `McpTool.runAsync(...)` returns only the legacy `text_output` map. It does not expose:

* `CallToolResult.isError` on successful results
* `CallToolResult.structuredContent`
* non-text `content` entries such as images or embedded resources
* the original ordered content list

This loss is irreversible for callers. An outer `BaseTool` decorator sees only the already-reduced map and cannot recover the discarded fields without bypassing native `McpTool` and invoking `McpSyncClient` itself.

**Steps to Reproduce:**

1. Use `com.google.adk:google-adk:1.7.1`.
2. Construct a native `McpToolset` over a streamable-HTTP MCP server.
3. Have the server advertise a zero-argument tool.
4. Return this successful `tools/call` result:

```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{"type": "text", "text": "first"},
{"type": "text", "text": "second"},
{
"type": "image",
"data": "aW1hZ2U=",
"mimeType": "image/png"
}
],
"structuredContent": {"count": 2},
"isError": false
}
}
```

5. Call the discovered native tool through `BaseTool.runAsync(...)`.

**Expected Behavior:**

Native MCP tools should preserve the complete semantic `CallToolResult`, including structured content and non-text content, without breaking callers that consume the existing `text_output` field.

A compatible resolution could be either:

1. An additive envelope that retains `text_output` unchanged while also exposing `content`, `structuredContent`, `isError`, and metadata.
2. A supported result-mapper/adapter hook on `McpToolset` or `McpTool` that receives the raw `CallToolResult` before reduction.

**Observed Behavior:**

The returned map contains only:

```text
{text_output=[{text=first}, {text=second}]}
```

`structuredContent`, image data and MIME type, the original content parts, and explicit non-error state are absent.

The loss is silent. No exception or warning indicates that valid MCP response data was discarded.

**Environment Details:**

* ADK Library Version (see maven dependency): `1.7.1`
* MCP Java SDK resolved by ADK: `1.1.2`
* MCP transport: streamable HTTP
* Java: 21

## 🟡 Optional Information

**Regression:**

No

**Additional Context:**

PR #1078 changed `wrapCallResult` to serialize the complete `CallToolResult`, but PR #1090 reverted that change to preserve backward compatibility with `text_output`.

The requested fix is therefore not to remove `text_output`. It is to preserve compatibility without silently losing the remaining MCP result fields.

This blocks replacing a custom MCP bridge with native `McpToolset`: the custom implementation currently preserves text, `structuredContent`, non-text content parts, and error state, while native `McpTool` does not.

**Minimal Reproduction Code:**

N/A. The issue can be reproduced using the MCP response above and a native `McpToolset` over a streamable-HTTP MCP server.

**How often has this issue occurred?:**

* Always (100%)

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.