🔴 Required Information
Describe the Bug:
An MCP tool's outputSchema never reaches the model when the agent is backed by LiteLlm. MCPTool._get_declaration() can populate response_json_schema, but _function_declaration_to_tool_param() in lite_llm.py builds the tool payload from name, description and parameters only, so the output schema is silently dropped.
The result is that the model cannot describe or rely on a tool's result shape, which is the same user-visible symptom as #2828 (fixed for the Gemini path in c8e5340, later refactored behind the JSON_SCHEMA_FOR_FUNC_DECL feature flag).
Enabling ADK_ENABLE_JSON_SCHEMA_FOR_FUNC_DECL=1 does not help on this path: the declaration is built correctly, but the LiteLLM conversion still discards it. The payload is byte-identical with the flag on and off.
Steps to Reproduce:
pip install google-adk==1.34.1
- Save the script under Minimal Reproduction Code as
adk_repro.py
- Run
python adk_repro.py
- Run
ADK_ENABLE_JSON_SCHEMA_FOR_FUNC_DECL=1 python adk_repro.py
- Compare the printed payloads — they are identical, and neither contains the output schema
Expected Behavior:
The declared output schema should reach the model on the LiteLLM path, as it does on the Gemini path. Most OpenAI-compatible providers have no dedicated field for a tool's result schema, so a reasonable approach would be to append a rendering of the schema to the tool description (which is forwarded) rather than inventing a non-standard key.
Observed Behavior:
ADK_ENABLE_JSON_SCHEMA_FOR_FUNC_DECL = 1
declaration.response is set: False
declaration.response_json_schema is set: True
Payload LiteLlm sends to the model:
{
"type": "function",
"function": {
"name": "get_widget",
"description": "Return a widget.",
"parameters": {
"type": "object",
"properties": {"service": {"type": "string"}},
"required": ["service"]
}
}
}
output schema present in payload: False
declaration.response_json_schema is set, yet nothing derived from it appears in the payload.
Environment Details:
- ADK Library Version (pip show google-adk): 1.34.1
- Desktop OS: macOS 26.6
- Python Version (python -V): 3.12
Model Information:
- Are you using LiteLLM: Yes
- Which model is being used: GPT models via a LiteLLM-compatible endpoint (not model-specific — the schema is dropped before any request is made)
🟡 Optional Information
Regression:
Partly. #2828 was fixed in c8e5340 by setting response=_to_gemini_schema(output_schema) on the FunctionDeclaration. That assignment no longer exists on main; _get_declaration() now sets either parameters alone or parameters_json_schema + response_json_schema depending on FeatureName.JSON_SCHEMA_FOR_FUNC_DECL (WIP, default_on=False). Either way _function_declaration_to_tool_param() ignores both response and response_json_schema, so the LiteLLM path has no route for it.
Additional Context:
Relevant code on main:
src/google/adk/tools/mcp_tool/mcp_tool.py — _get_declaration() sets response_json_schema=output_schema only when the feature flag is enabled.
src/google/adk/models/lite_llm.py — _function_declaration_to_tool_param() reads parameters / parameters_json_schema and returns {"type": "function", "function": {"name", "description", "parameters"}}.
src/google/adk/models/lite_llm.py — _build_function_declaration_log() does read func_decl.response, but that is logging only and does not affect the request.
grep -c response_json_schema src/google/adk/models/lite_llm.py returns 0; only google_llm.py and apigee_llm.py reference it.
Happy to send a PR if the description-appending approach sounds right, or another shape if you prefer.
Minimal Reproduction Code:
"""Minimal reproduction: an MCP tool's outputSchema never reaches a LiteLLM-backed model."""
import json
import os
from google.adk.models.lite_llm import _function_declaration_to_tool_param
from google.adk.tools.mcp_tool.mcp_tool import McpTool as AdkMcpTool
from mcp.types import Tool as McpTool
OUTPUT_SCHEMA = {
"type": "object",
"additionalProperties": False,
"required": ["status", "data"],
"properties": {
"status": {"type": "string", "enum": ["success", "error"]},
"data": {"type": "string", "description": "Preformatted text, not JSON."},
},
}
INPUT_SCHEMA = {
"type": "object",
"properties": {"service": {"type": "string"}},
"required": ["service"],
}
mcp_tool = McpTool(
name="get_widget",
description="Return a widget.",
inputSchema=INPUT_SCHEMA,
outputSchema=OUTPUT_SCHEMA,
)
tool = AdkMcpTool(mcp_tool=mcp_tool, mcp_session_manager=None)
declaration = tool._get_declaration()
flag = os.environ.get("ADK_ENABLE_JSON_SCHEMA_FOR_FUNC_DECL", "<unset>")
print(f"ADK_ENABLE_JSON_SCHEMA_FOR_FUNC_DECL = {flag}")
print(f"declaration.response is set: {declaration.response is not None}")
print(f"declaration.response_json_schema is set: {declaration.response_json_schema is not None}")
payload = _function_declaration_to_tool_param(declaration)
print("\nPayload LiteLlm sends to the model:")
print(json.dumps(payload, indent=2))
print(f"\noutput schema present in payload: {'success' in json.dumps(payload)}")
How often has this issue occurred?:
🔴 Required Information
Describe the Bug:
An MCP tool's
outputSchemanever reaches the model when the agent is backed byLiteLlm.MCPTool._get_declaration()can populateresponse_json_schema, but_function_declaration_to_tool_param()inlite_llm.pybuilds the tool payload fromname,descriptionandparametersonly, so the output schema is silently dropped.The result is that the model cannot describe or rely on a tool's result shape, which is the same user-visible symptom as #2828 (fixed for the Gemini path in c8e5340, later refactored behind the
JSON_SCHEMA_FOR_FUNC_DECLfeature flag).Enabling
ADK_ENABLE_JSON_SCHEMA_FOR_FUNC_DECL=1does not help on this path: the declaration is built correctly, but the LiteLLM conversion still discards it. The payload is byte-identical with the flag on and off.Steps to Reproduce:
pip install google-adk==1.34.1adk_repro.pypython adk_repro.pyADK_ENABLE_JSON_SCHEMA_FOR_FUNC_DECL=1 python adk_repro.pyExpected Behavior:
The declared output schema should reach the model on the LiteLLM path, as it does on the Gemini path. Most OpenAI-compatible providers have no dedicated field for a tool's result schema, so a reasonable approach would be to append a rendering of the schema to the tool
description(which is forwarded) rather than inventing a non-standard key.Observed Behavior:
declaration.response_json_schemais set, yet nothing derived from it appears in the payload.Environment Details:
Model Information:
🟡 Optional Information
Regression:
Partly. #2828 was fixed in c8e5340 by setting
response=_to_gemini_schema(output_schema)on theFunctionDeclaration. That assignment no longer exists onmain;_get_declaration()now sets eitherparametersalone orparameters_json_schema+response_json_schemadepending onFeatureName.JSON_SCHEMA_FOR_FUNC_DECL(WIP,default_on=False). Either way_function_declaration_to_tool_param()ignores bothresponseandresponse_json_schema, so the LiteLLM path has no route for it.Additional Context:
Relevant code on
main:src/google/adk/tools/mcp_tool/mcp_tool.py—_get_declaration()setsresponse_json_schema=output_schemaonly when the feature flag is enabled.src/google/adk/models/lite_llm.py—_function_declaration_to_tool_param()readsparameters/parameters_json_schemaand returns{"type": "function", "function": {"name", "description", "parameters"}}.src/google/adk/models/lite_llm.py—_build_function_declaration_log()does readfunc_decl.response, but that is logging only and does not affect the request.grep -c response_json_schema src/google/adk/models/lite_llm.pyreturns 0; onlygoogle_llm.pyandapigee_llm.pyreference it.Happy to send a PR if the description-appending approach sounds right, or another shape if you prefer.
Minimal Reproduction Code:
How often has this issue occurred?: