mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-12 23:01:41 +00:00
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:
parent
b216c4d80d
commit
20d4dcc4ed
2 changed files with 48 additions and 2 deletions
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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__])
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue