Please read this first
Describe the bug
MCPUtil.invoke_mcp_tool() suppresses debug logging when DONT_LOG_TOOL_DATA is enabled, but it still includes the raw malformed input_json in the raised ModelBehaviorError.
Current code in src/agents/mcp/util.py:
try:
json_data: dict[str, Any] = json.loads(input_json) if input_json else {}
except Exception as e:
if _debug.DONT_LOG_TOOL_DATA:
logger.debug(f"Invalid JSON input for tool {tool.name}")
else:
logger.debug(f"Invalid JSON input for tool {tool.name}: {input_json}")
raise ModelBehaviorError(
f"Invalid JSON input for tool {tool.name}: {input_json}"
) from e
That means malformed MCP tool arguments can still leak secrets through exception strings even when the runtime is explicitly configured not to log tool data.
This is especially risky because MCP inputs often carry tokens, cookies, internal URLs, file paths, or user data, and exception strings frequently end up in application logs, traces, and alerting systems.
Debug information
- Agents SDK version:
main at f2fb9ffb (also reproducible from the local editable build reporting 0.15.1)
- Python version: Python 3.12
Repro steps
Minimal reproducer:
import asyncio
from agents.mcp.server import MCPServer
from agents.mcp.util import MCPUtil
from mcp import Tool as MCPTool
class FakeServer(MCPServer):
@property
def name(self) -> str:
return "fake"
async def connect(self):
return None
async def cleanup(self):
return None
async def list_tools(self, run_context=None, agent=None):
return []
async def list_prompts(self, run_context=None, agent=None):
return []
async def get_prompt(self, name: str, arguments=None):
raise NotImplementedError
async def call_tool(self, tool_name, arguments, meta=None):
raise NotImplementedError
async def main() -> None:
server = FakeServer()
tool = MCPTool(name="test_tool", inputSchema={})
try:
await MCPUtil.invoke_mcp_tool(
server,
tool,
None,
'{"secret":"SECRET_TOKEN_123"',
)
except Exception as exc:
print(type(exc).__name__)
print(str(exc))
asyncio.run(main())
Current output:
ModelBehaviorError
Invalid JSON input for tool test_tool: {"secret":"SECRET_TOKEN_123"
Suggested regression coverage:
- Enable the no-tool-data logging mode.
- Pass malformed JSON containing a sentinel secret.
- Assert that both logs and the raised exception string omit the raw payload.
Expected behavior
When DONT_LOG_TOOL_DATA is enabled, malformed MCP input should be redacted consistently across both logging and exceptions.
For example, the raised error should look more like:
Invalid JSON input for tool test_tool
instead of embedding the raw input payload.
Please read this first
Describe the bug
MCPUtil.invoke_mcp_tool()suppresses debug logging whenDONT_LOG_TOOL_DATAis enabled, but it still includes the raw malformedinput_jsonin the raisedModelBehaviorError.Current code in
src/agents/mcp/util.py:That means malformed MCP tool arguments can still leak secrets through exception strings even when the runtime is explicitly configured not to log tool data.
This is especially risky because MCP inputs often carry tokens, cookies, internal URLs, file paths, or user data, and exception strings frequently end up in application logs, traces, and alerting systems.
Debug information
mainatf2fb9ffb(also reproducible from the local editable build reporting0.15.1)Repro steps
Minimal reproducer:
Current output:
Suggested regression coverage:
Expected behavior
When
DONT_LOG_TOOL_DATAis enabled, malformed MCP input should be redacted consistently across both logging and exceptions.For example, the raised error should look more like:
instead of embedding the raw input payload.