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

(cherry picked from commit 7acc0157df)
This commit is contained in:
ryan-crabbe-berri 2026-06-26 17:42:05 -07:00 committed by Yuneng Jiang
parent b216c4d80d
commit 20d4dcc4ed
No known key found for this signature in database
2 changed files with 48 additions and 2 deletions

View file

@ -555,7 +555,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(
@ -664,7 +664,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

@ -543,5 +543,51 @@ class TestExecuteSessionOperationSurfacesTransportError:
assert result == "done"
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__])