Skip to content

Commit c8b87d0

Browse files
author
Tarek Mahmoud Sayed
committed
Change cache-miss log to Warning, gate to HTTP transport only
Log a Warning (instead of Debug) when a tools/call request has no cached tool definition, but only for StreamableHttpClientSessionTransport where Mcp-Param-* headers are relevant. Pipe/stdio transports do not emit this warning since headers do not apply. Added tests: - Pipe transport: cache miss does NOT log a warning - HTTP transport: cache miss DOES log a warning
1 parent 495f48a commit c8b87d0

3 files changed

Lines changed: 26 additions & 2 deletions

File tree

src/ModelContextProtocol.Core/Client/McpClientImpl.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ request.Params is System.Text.Json.Nodes.JsonObject paramsObj &&
733733
request.Context.Items ??= new Dictionary<string, object?>();
734734
request.Context.Items[McpHttpHeaders.ToolContextKey] = tool;
735735
}
736-
else
736+
else if (_transport is StreamableHttpClientSessionTransport)
737737
{
738738
LogToolCacheMiss(toolName);
739739
}
@@ -793,7 +793,7 @@ public override async ValueTask DisposeAsync()
793793
[LoggerMessage(Level = LogLevel.Information, Message = "{EndpointName} client resumed existing session.")]
794794
private partial void LogClientSessionResumed(string endpointName);
795795

796-
[LoggerMessage(Level = LogLevel.Debug, Message = "Tool '{ToolName}' not found in cache during tools/call. Mcp-Param-* headers will not be sent. Call AddKnownTools or ListToolsAsync to populate the cache.")]
796+
[LoggerMessage(Level = LogLevel.Warning, Message = "Tool '{ToolName}' not found in cache during tools/call. Mcp-Param-* headers will not be sent. Call AddKnownTools or ListToolsAsync to populate the cache.")]
797797
private partial void LogToolCacheMiss(string toolName);
798798

799799
[LoggerMessage(Level = LogLevel.Warning, Message = "Tool '{ToolName}' excluded from tools/list: {Reason}")]

tests/ModelContextProtocol.AspNetCore.Tests/AddKnownToolsHeaderTests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ public async Task CallToolWithoutRegisterOrList_DoesNotSendMcpParamHeaders()
195195
Assert.Single(_capturedHeaders);
196196
var headers = _capturedHeaders.Values.First();
197197
Assert.Empty(headers);
198+
199+
// Verify that a cache miss warning IS logged for HTTP transport
200+
Assert.Contains(MockLoggerProvider.LogMessages, log =>
201+
log.LogLevel == Microsoft.Extensions.Logging.LogLevel.Warning &&
202+
log.Message.Contains("not found in cache during tools/call"));
198203
}
199204

200205
[Fact]

tests/ModelContextProtocol.Tests/Client/McpClientAddKnownToolsTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,4 +408,23 @@ public async Task AddKnownTools_NullElementInMiddle_NothingRegistered()
408408
var tools = await client.ListToolsAsync(cancellationToken: TestContext.Current.CancellationToken);
409409
Assert.Equal(2, tools.Count);
410410
}
411+
412+
[Fact]
413+
public async Task CallToolWithoutCache_PipeTransport_DoesNotLogWarning()
414+
{
415+
// Arrange — pipe transport should NOT log a cache miss warning
416+
await using var client = await CreateMcpClientForServer();
417+
418+
// Act — call a server tool without populating cache via ListToolsAsync
419+
var result = await client.CallToolAsync(
420+
ServerToolName,
421+
new Dictionary<string, object?> { ["input"] = "test" },
422+
cancellationToken: TestContext.Current.CancellationToken);
423+
424+
// Assert — call succeeds and no cache miss warning is logged (pipe transport, not HTTP)
425+
Assert.NotNull(result);
426+
Assert.DoesNotContain(MockLoggerProvider.LogMessages, log =>
427+
log.LogLevel == Microsoft.Extensions.Logging.LogLevel.Warning &&
428+
log.Message.Contains("not found in cache during tools/call"));
429+
}
411430
}

0 commit comments

Comments
 (0)