Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions litellm/experimental_mcp_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ async def call_tool(
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(
Expand Down Expand Up @@ -672,7 +672,7 @@ async def get_prompt(
) -> 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):
Expand Down
46 changes: 46 additions & 0 deletions tests/test_litellm/experimental_mcp_client/test_mcp_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,5 +582,51 @@ async def test_without_resolved_auth_falls_back_to_aws_auth(self):
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__])
Loading