Skip to content

Commit 189474f

Browse files
committed
Clean up logging
1 parent 9c124b1 commit 189474f

12 files changed

+401
-570
lines changed

src/ModelContextProtocol.AspNetCore/StreamableHttpHandler.cs

+10-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using ModelContextProtocol.Server;
1010
using ModelContextProtocol.Utils.Json;
1111
using System.Collections.Concurrent;
12+
using System.Diagnostics;
1213
using System.Security.Cryptography;
1314

1415
namespace ModelContextProtocol.AspNetCore;
@@ -61,18 +62,19 @@ public async Task HandleSseRequestAsync(HttpContext context)
6162
var httpMcpSession = new HttpMcpSession(transport, context.User);
6263
if (!_sessions.TryAdd(sessionId, httpMcpSession))
6364
{
64-
throw new Exception($"Unreachable given good entropy! Session with ID '{sessionId}' has already been created.");
65-
}
66-
67-
var mcpServerOptions = mcpServerOptionsSnapshot.Value;
68-
if (httpMcpServerOptions.Value.ConfigureSessionOptions is { } configureSessionOptions)
69-
{
70-
mcpServerOptions = mcpServerOptionsFactory.Create(Options.DefaultName);
71-
await configureSessionOptions(context, mcpServerOptions, cancellationToken);
65+
Debug.Fail("Unreachable given good entropy!");
66+
throw new InvalidOperationException($"Session with ID '{sessionId}' has already been created.");
7267
}
7368

7469
try
7570
{
71+
var mcpServerOptions = mcpServerOptionsSnapshot.Value;
72+
if (httpMcpServerOptions.Value.ConfigureSessionOptions is { } configureSessionOptions)
73+
{
74+
mcpServerOptions = mcpServerOptionsFactory.Create(Options.DefaultName);
75+
await configureSessionOptions(context, mcpServerOptions, cancellationToken);
76+
}
77+
7678
var transportTask = transport.RunAsync(cancellationToken);
7779

7880
try

src/ModelContextProtocol/Client/McpClient.cs

+22-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.Extensions.Logging;
2-
using ModelContextProtocol.Logging;
32
using ModelContextProtocol.Protocol.Messages;
43
using ModelContextProtocol.Protocol.Transport;
54
using ModelContextProtocol.Protocol.Types;
@@ -10,7 +9,7 @@
109
namespace ModelContextProtocol.Client;
1110

1211
/// <inheritdoc/>
13-
internal sealed class McpClient : McpEndpoint, IMcpClient
12+
internal sealed partial class McpClient : McpEndpoint, IMcpClient
1413
{
1514
private static Implementation DefaultImplementation { get; } = new()
1615
{
@@ -133,9 +132,12 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default)
133132
cancellationToken: initializationCts.Token).ConfigureAwait(false);
134133

135134
// Store server information
136-
_logger.ServerCapabilitiesReceived(EndpointName,
137-
capabilities: JsonSerializer.Serialize(initializeResponse.Capabilities, McpJsonUtilities.JsonContext.Default.ServerCapabilities),
138-
serverInfo: JsonSerializer.Serialize(initializeResponse.ServerInfo, McpJsonUtilities.JsonContext.Default.Implementation));
135+
if (_logger.IsEnabled(LogLevel.Information))
136+
{
137+
LogServerCapabilitiesReceived(EndpointName,
138+
capabilities: JsonSerializer.Serialize(initializeResponse.Capabilities, McpJsonUtilities.JsonContext.Default.ServerCapabilities),
139+
serverInfo: JsonSerializer.Serialize(initializeResponse.ServerInfo, McpJsonUtilities.JsonContext.Default.Implementation));
140+
}
139141

140142
_serverCapabilities = initializeResponse.Capabilities;
141143
_serverInfo = initializeResponse.ServerInfo;
@@ -144,7 +146,7 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default)
144146
// Validate protocol version
145147
if (initializeResponse.ProtocolVersion != _options.ProtocolVersion)
146148
{
147-
_logger.ServerProtocolVersionMismatch(EndpointName, _options.ProtocolVersion, initializeResponse.ProtocolVersion);
149+
LogServerProtocolVersionMismatch(EndpointName, _options.ProtocolVersion, initializeResponse.ProtocolVersion);
148150
throw new McpException($"Server protocol version mismatch. Expected {_options.ProtocolVersion}, got {initializeResponse.ProtocolVersion}");
149151
}
150152

@@ -155,13 +157,13 @@ await SendMessageAsync(
155157
}
156158
catch (OperationCanceledException oce) when (initializationCts.IsCancellationRequested)
157159
{
158-
_logger.ClientInitializationTimeout(EndpointName);
160+
LogClientInitializationTimeout(EndpointName);
159161
throw new McpException("Initialization timed out", oce);
160162
}
161163
}
162164
catch (Exception e)
163165
{
164-
_logger.ClientInitializationError(EndpointName, e);
166+
LogClientInitializationError(EndpointName, e);
165167
await DisposeAsync().ConfigureAwait(false);
166168
throw;
167169
}
@@ -188,4 +190,16 @@ public override async ValueTask DisposeUnsynchronizedAsync()
188190
}
189191
}
190192
}
193+
194+
[LoggerMessage(Level = LogLevel.Information, Message = "{EndpointName} client received server '{ServerInfo}' capabilities: '{Capabilities}'.")]
195+
private partial void LogServerCapabilitiesReceived(string endpointName, string capabilities, string serverInfo);
196+
197+
[LoggerMessage(Level = LogLevel.Error, Message = "{EndpointName} client initialization error.")]
198+
private partial void LogClientInitializationError(string endpointName, Exception exception);
199+
200+
[LoggerMessage(Level = LogLevel.Error, Message = "{EndpointName} client initialization timed out.")]
201+
private partial void LogClientInitializationTimeout(string endpointName);
202+
203+
[LoggerMessage(Level = LogLevel.Error, Message = "{EndpointName} client protocol version mismatch with server. Expected '{Expected}', received '{Received}'.")]
204+
private partial void LogServerProtocolVersionMismatch(string endpointName, string expected, string received);
191205
}

src/ModelContextProtocol/Client/McpClientFactory.cs

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
using ModelContextProtocol.Logging;
21
using ModelContextProtocol.Protocol.Transport;
32
using ModelContextProtocol.Utils;
43
using Microsoft.Extensions.Logging;
5-
using Microsoft.Extensions.Logging.Abstractions;
64

75
namespace ModelContextProtocol.Client;
86

@@ -14,7 +12,7 @@ namespace ModelContextProtocol.Client;
1412
/// that connect to MCP servers. It handles the creation and connection
1513
/// of appropriate implementations through the supplied transport.
1614
/// </remarks>
17-
public static class McpClientFactory
15+
public static partial class McpClientFactory
1816
{
1917
/// <summary>Creates an <see cref="IMcpClient"/>, connecting it to the specified server.</summary>
2018
/// <param name="clientTransport">The transport instance used to communicate with the server.</param>
@@ -35,21 +33,24 @@ public static async Task<IMcpClient> CreateAsync(
3533
{
3634
Throw.IfNull(clientTransport);
3735

38-
string endpointName = clientTransport.Name;
39-
var logger = loggerFactory?.CreateLogger(typeof(McpClientFactory)) ?? NullLogger.Instance;
40-
logger.CreatingClient(endpointName);
41-
4236
McpClient client = new(clientTransport, clientOptions, loggerFactory);
4337
try
4438
{
4539
await client.ConnectAsync(cancellationToken).ConfigureAwait(false);
46-
logger.ClientCreated(endpointName);
47-
return client;
40+
if (loggerFactory?.CreateLogger(typeof(McpClientFactory)) is ILogger logger)
41+
{
42+
logger.LogClientCreated(client.EndpointName);
43+
}
4844
}
4945
catch
5046
{
5147
await client.DisposeAsync().ConfigureAwait(false);
5248
throw;
5349
}
50+
51+
return client;
5452
}
53+
54+
[LoggerMessage(Level = LogLevel.Information, Message = "{EndpointName} client created and connected.")]
55+
private static partial void LogClientCreated(this ILogger logger, string endpointName);
5556
}

0 commit comments

Comments
 (0)