fix(mcp): stop logging tool-call input in MCP client (#31393)

The MCP client logged the full tool arguments (and prompt arguments) at INFO on every call, so caller input such as user queries, model names, and instructions landed in the proxy application logs and any downstream log aggregator

Log only the tool or prompt name and drop the arguments from these INFO lines
This commit is contained in:
ryan-crabbe-berri 2026-06-26 17:42:05 -07:00 committed by GitHub
parent 01efcc1b74
commit 7acc0157df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 2 deletions

View file

@ -563,7 +563,7 @@ class MCPClient:
Call an MCP Tool.
"""
verbose_logger.info(
f"MCP client calling tool '{call_tool_request_params.name}' with arguments: {call_tool_request_params.arguments}"
f"MCP client calling tool '{call_tool_request_params.name}'"
)
async def on_progress(
@ -672,7 +672,7 @@ class MCPClient:
) -> GetPromptResult:
"""Fetch a prompt definition from the MCP server."""
verbose_logger.info(
f"MCP client fetching prompt '{get_prompt_request_params.name}' with arguments: {get_prompt_request_params.arguments}"
f"MCP client fetching prompt '{get_prompt_request_params.name}'"
)
async def _get_prompt_operation(session: ClientSession):

View file

@ -582,5 +582,51 @@ class TestMCPClientResolvedAuth:
await http_client.aclose()
def _all_logged_messages(mock_logger):
return " ".join(
str(call.args[0])
for level in ("info", "debug", "warning", "error", "exception")
for call in getattr(mock_logger, level).call_args_list
if call.args
)
@pytest.mark.asyncio
async def test_call_tool_does_not_log_arguments():
from mcp.types import CallToolRequestParams
secret = "ssn-123-45-6789"
client = MCPClient(server_url="http://test-server")
client.run_with_session = AsyncMock(return_value=MagicMock())
params = CallToolRequestParams(
name="search_tool", arguments={"input": secret, "model": "gpt-5-mini"}
)
with patch.object(mcp_client_module, "verbose_logger") as mock_logger:
await client.call_tool(params)
logged = _all_logged_messages(mock_logger)
assert "search_tool" in logged
assert secret not in logged
assert "gpt-5-mini" not in logged
@pytest.mark.asyncio
async def test_get_prompt_does_not_log_arguments():
from mcp.types import GetPromptRequestParams
secret = "ssn-987-65-4321"
client = MCPClient(server_url="http://test-server")
client.run_with_session = AsyncMock(return_value=MagicMock())
params = GetPromptRequestParams(name="my_prompt", arguments={"input": secret})
with patch.object(mcp_client_module, "verbose_logger") as mock_logger:
await client.get_prompt(params)
logged = _all_logged_messages(mock_logger)
assert "my_prompt" in logged
assert secret not in logged
if __name__ == "__main__":
pytest.main([__file__])