Simvasia

Simulation Testing for AI Agents
How It WorksBlog
© 2026 Simvasia. All rights reserved.
Version 1.0.24
←Back to Blog

Google's ADK Bug Report: Finding and Patching a Bug With Reserved Keywords

January 8, 2026•Neeraj Chandra
Google ADKTwilio MCPADK BugSimulation Testing

This is Part 2 of a series on building agents with Google's Agent Development Kit (ADK). See here for Part 1.

We were testing our AI agent built with Google's Agent Development Kit (ADK) when we discovered a critical bug. The agent was calling MCP tools with the wrong parameter names—and failing silently.

This bug happens when an MCP tool has a parameter that's a Python reserved keyword (like from, class, or import). ADK automatically renames these parameters to avoid syntax errors, but never tells the MCP server about the change.

Here's what we found, why it matters, and how to fix it.

The Bug: Silent Parameter Renaming

TL;DR: Google's ADK renames Python reserved keywords in MCP tool parameters (e.g., from → from1_) to avoid syntax errors. But it sends the renamed parameters to the MCP server, which expects the original names. The result? Silent failures where your agent thinks it called the tool correctly, but the server rejects the request.

The Scenario

We built a Weather-to-SMS agent that:

  1. Converts a location name to latitude/longitude (geocoding MCP)
  2. Fetches weather for those coordinates (weather MCP)
  3. Sends an SMS with the weather summary (Twilio MCP)

The Twilio MCP's send_message tool expects these parameters:

@mcp.tool()
def send_message(from: str, to: str, body: str, media_url: str = None) -> dict:
    """Send an SMS message via Twilio"""
    # from = sender's phone number
    # to = recipient's phone number
    # body = message content
    # media_url = optional URL for MMS media attachment
    ...
Twilio MCP connector in Simvasia with input parameters

Notice the problem? from is a Python reserved keyword. You can't use it as a variable name without causing syntax errors.

What ADK Does

Google's ADK detects reserved keywords and automatically renames them. In this case:

  • from → from1_
  • class → class_
  • import → import_

This prevents Python syntax errors when the agent calls the tool. So far, so good.

The Problem

ADK sends the renamed parameters to the MCP server:

What ADK Sends:
{
  "method": "tools/call",
  "params": {
    "name": "send_message",
    "arguments": {
      "from1_": "9876543210",  // ❌ Wrong parameter name
      "to": "012345679",
      "body": "Weather in DC: 2.1°C and clear"
    }
  }
}

But the MCP server expects:

What the Server Expects:
{
  "method": "tools/call",
  "params": {
    "name": "send_message",
    "arguments": {
      "from": "9876543210",  // ✅ Correct parameter name
      "to": "012345679",
      "body": "Weather in DC: 2.1°C and clear"
    }
  }
}

The server doesn't recognize from1_ as a valid parameter. It either:

  • Rejects the request with an error
  • Uses a default value (if the parameter is optional)
  • Silently fails

Your agent has no idea anything went wrong.

Why This is Critical

This isn't a theoretical edge case. It affects any MCP tool with reserved keyword parameters:

  • Messaging APIs: Twilio, SendGrid, Slack (all use from)
  • Email APIs: Gmail, Outlook (use from, to, subject)
  • File operations: Tools using import, class, type
  • Any API mirroring Python syntax: for, if, while, etc.

Without systematic testing, you won't discover this until:

  • Your agent deploys to production and fails
  • Users report that messages aren't being sent
  • You manually inspect the tool calls (which most developers never do)

How We Discovered It

We were testing our agent with Simvasia, which lets you create mocks of MCP servers to test agents without side effects.

While inspecting the actual tool calls being made, we noticed:

functionCall:
  id: "adk-fbd8152b-4a41-47bc-abd9-2ec30de4688b"
  args:
    body: "The current weather in Washington, DC is 2.1°C and clear."
    from1_: "9876543210"  // ❌ This should be "from"
    to: "012345679"
  name: "send_message"

The parameter was from1_ instead of from. The Twilio MCP server rejected the request for missing the required input parameter from.

This is exactly why you need systematic testing. Without mocking and inspecting tool calls, we would never have caught this bug before production.

The Solution: Using before_tool_callback

ADK provides a powerful hook called before_tool_callback that's called just before a tool executes. We can use this to intercept and remap the parameters before they're sent to the MCP server:

from google.adk.tools.base_tool import BaseTool
from google.adk.tools.tool_context import ToolContext
from typing import Any, Dict, Optional

def parameter_remapping_callback(
    tool: BaseTool, args: Dict[str, Any], tool_context: ToolContext
) -> Optional[Dict]:
    """
    Before tool callback that remaps reserved keyword parameters.
    ADK renames 'from' -> 'from1_' to avoid Python keyword conflicts.
    This callback remaps it back to 'from' before calling the MCP server.
    """
    # Check if this is the send_message tool that needs parameter remapping
    if tool.name == "send_message" and "from1_" in args:
        print(f"[Callback] Detected 'from1_' parameter. Remapping to 'from'.")
        print(f"[Callback] Original args: {args}")

        # Remap from1_ back to from
        args["from"] = args.pop("from1_")

        print(f"[Callback] Remapped args: {args}")

    # Return None to proceed with (potentially modified) args
    return None

How to Use It

Pass the callback function to your agent via the before_tool_callback parameter:

from google.adk.agents import Agent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPServerParams

sms_agent = Agent(
    model="gemini-2.5-flash",
    name="sms_agent",
    tools=[
        McpToolset(
            connection_params=StreamableHTTPServerParams(
                url="https://www.simvasia.com/sandbox/simvasia/twilio_mcp/",
                headers={"X-Sandbox-Token": "SIMVASIA_TOKEN"},
            ),
        ),
    ],
    # Use before_tool_callback to remap 'from1_' back to 'from'
    before_tool_callback=parameter_remapping_callback,
)

Result: The callback intercepts the tool call, detects from1_, remaps it to from, and then the MCP server receives the correct parameter. The tool call succeeds! ✅

Common Reserved Keywords to Watch For

If your MCP tools use any of these Python reserved keywords as parameter names, you'll need to remap them:

Python Reserved Keywords (35 total):
False      await      else       import     pass
None       break      except     in         raise
True       class      finally    is         return
and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield

ADK will rename these to avoid syntax errors:

  • from → from1_
  • class → class_
  • import → import_
  • for → for_
  • if → if_

Use ParameterRemappingToolset with the appropriate mapping to fix it.

Key Takeaways

  • ADK silently renames reserved keywords: from becomes from1_, breaking MCP calls
  • This affects real-world APIs: Twilio, SendGrid, Gmail, Slack, and more
  • Testing reveals the bug: Without inspecting tool calls, you won't find it until production
  • Use before_tool_callback: ADK's hook to intercept and fix parameter names before MCP calls
  • Systematic testing is critical: Mocking tools like Simvasia let you catch these issues early

Next Steps

ADK should:

  • Restore original parameters for external operations (handle reserved keywords specially internally)
  • Warn developers when renaming happens
  • Provide a built-in parameter mapping mechanism
  • Document this behavior clearly

Until Google fixes this, use before_tool_callback as a workaround.

The difference between an agent that works in demos and one that works in production is catching bugs like this before they matter.


Discovered while building reliable AI agents with Simvasia. Questions? Reach out on Threads, Twitter, or GitHub.

←Back to All Posts