Skip to content

fix(tools): omit oversized MCP output schemas from Gemini declarations - #7708

Open
sun04222 wants to merge 2 commits into
google:mainfrom
sun04222:fix/mcp-output-schema-budget
Open

sun04222 wants to merge 2 commits into
google:mainfrom
sun04222:fix/mcp-output-schema-budget

Conversation

@sun04222

Copy link
Copy Markdown

Link to Issue or Description of Change

Problem:

When JSON_SCHEMA_FOR_FUNC_DECL is on (the default), McpTool._build_declaration() forwards the MCP server's outputSchema to Gemini verbatim as FunctionDeclaration.response_json_schema, with no size limit. Gemini counts a schema as if every $ref were inlined, so Google Cloud's proto-derived MCP servers (logging, monitoring, cloudtrace, clouderrorreporting) push an 18-tool request past the 1,048,576-token input limit — those servers cannot be used with ADK as-is.

Solution:

Mirror the existing LiteLLM path: McpTool._build_declaration() now measures the serialized output schema and omits response_json_schema when it exceeds the same 1024-character budget the LiteLLM path already uses (_MAX_TOOL_DESCRIPTION_LENGTH). The drop is logged at warning level.

I deliberately kept this to the size cap (the smallest change that unblocks the reported servers). A per-toolset opt-out can follow as a separate change if maintainers would like one.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Added to TestMCPToolWithJsonSchema in tests/unittests/tools/mcp_tool/test_mcp_tool.py:

  • test_get_declaration_drops_oversized_output_schema — a ~2.4k-character output schema is omitted from the declaration while parameters_json_schema is preserved.
  • test_get_declaration_logs_when_dropping_oversized_output_schema — the drop is logged at warning level.
  • test_get_declaration_keeps_output_schema_within_budget — a within-budget schema is still sent.

pytest tests/unittests/tools/mcp_tool/ -q → 453 passed, 1 skipped, 0 failed (the full mcp_tool test directory on Python 3.12 / Windows, package installed editable from this branch; includes the 3 new tests). pyink --check passes for both touched files with the repo's pyink 25.12 config.

Manual End-to-End (E2E) Tests:

Not run against the Gemini API directly (needs a Vertex AI project). The repro in #7690 verifies the fix end to end: with this change, _get_declaration() on the Google Cloud logging/monitoring MCP servers returns response_json_schema=None for every tool whose serialized schema exceeds 1024 characters (all of the >7k-character entries in the issue's table), so the 18-tool generate_content request stays well under the input limit.

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

The 1024-character budget intentionally matches the LiteLLM path's existing _MAX_TOOL_DESCRIPTION_LENGTH, so both model paths now apply the same policy to MCP output schemas. Formatting verified with the repo's pyink==25.12 config (line-length 80, 2-space indentation).

MCP defines `outputSchema` for client-side validation of structured
results, but the Gemini path forwarded it verbatim as
`FunctionDeclaration.response_json_schema` with no size limit. Gemini
prices a schema as if every `$ref` were inlined, so proto-derived
schemas (e.g. Google Cloud's logging/monitoring MCP servers) can push
a single declaration past the model's input limit.

Mirror the LiteLLM path: omit `response_json_schema` when the
serialized schema exceeds the same 1024-character budget used there
(`_MAX_TOOL_DESCRIPTION_LENGTH`), and log a warning. Schemas within
the budget are sent unchanged.

Fixes google#7690
@google-cla

google-cla Bot commented Oct 24, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP outputSchema is sent to Gemini unbounded, exceeding the token limit

2 participants