Skip to content

Commit 4072013

Browse files
committed
Add the rest of the changes that were supposed to be in the last commit
- Get most of the changes that were supposed to be in the last commit - Go back to not processing messages until IMcpServer.RunAsync is called Failed test run: https://github.com/modelcontextprotocol/csharp-sdk/actions/runs/14299175970/job/40070612363?pr=225
1 parent 467a086 commit 4072013

3 files changed

Lines changed: 21 additions & 11 deletions

File tree

src/ModelContextProtocol/Client/McpClient.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default)
106106
{
107107
// Connect transport
108108
_sessionTransport = await _clientTransport.ConnectAsync(cancellationToken).ConfigureAwait(false);
109-
StartSession(_sessionTransport);
109+
InitializeSession(_sessionTransport);
110+
// We don't want the ConnectAsync token to cancel the session after we've successfully connected.
111+
// The base class handles cleaning up the session in DisposeAsync without our help.
112+
StartSession(_sessionTransport, fullSessionCancellationToken: CancellationToken.None);
110113

111114
// Perform initialization sequence
112115
using var initializationCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

src/ModelContextProtocol/Server/McpServer.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ internal sealed class McpServer : McpEndpoint, IMcpServer
1818
Version = DefaultAssemblyName.Version?.ToString() ?? "1.0.0",
1919
};
2020

21+
private readonly ITransport _sessionTransport;
22+
2123
private readonly EventHandler? _toolsChangedDelegate;
2224
private readonly EventHandler? _promptsChangedDelegate;
2325

@@ -41,6 +43,7 @@ public McpServer(ITransport transport, McpServerOptions options, ILoggerFactory?
4143

4244
options ??= new();
4345

46+
_sessionTransport = transport;
4447
ServerOptions = options;
4548
Services = serviceProvider;
4649
_endpointName = $"Server ({options.ServerInfo?.Name ?? DefaultImplementation.Name} {options.ServerInfo?.Version ?? DefaultImplementation.Version})";
@@ -81,8 +84,8 @@ public McpServer(ITransport transport, McpServerOptions options, ILoggerFactory?
8184
prompts.Changed += _promptsChangedDelegate;
8285
}
8386

84-
// And start the session.
85-
StartSession(transport);
87+
// And initialize the session.
88+
InitializeSession(transport);
8689
}
8790

8891
public ServerCapabilities? ServerCapabilities { get; set; }
@@ -112,9 +115,8 @@ public async Task RunAsync(CancellationToken cancellationToken = default)
112115

113116
try
114117
{
115-
using var _ = cancellationToken.Register(static s => ((McpServer)s!).CancelSession(), this);
116-
// The McpServer ctor always calls StartSession, so MessageProcessingTask is always set.
117-
await MessageProcessingTask!.ConfigureAwait(false);
118+
StartSession(_sessionTransport, fullSessionCancellationToken: cancellationToken);
119+
await MessageProcessingTask.ConfigureAwait(false);
118120
}
119121
finally
120122
{

src/ModelContextProtocol/Shared/McpEndpoint.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using ModelContextProtocol.Protocol.Transport;
66
using ModelContextProtocol.Server;
77
using ModelContextProtocol.Utils;
8+
using System.Diagnostics;
89
using System.Diagnostics.CodeAnalysis;
910
using System.Reflection;
1011

@@ -62,12 +63,16 @@ public IAsyncDisposable RegisterNotificationHandler(string method, Func<JsonRpcN
6263
/// </summary>
6364
protected Task? MessageProcessingTask { get; private set; }
6465

65-
[MemberNotNull(nameof(MessageProcessingTask))]
66-
protected void StartSession(ITransport sessionTransport)
66+
protected void InitializeSession(ITransport sessionTransport)
6767
{
68-
_sessionCts = new CancellationTokenSource();
6968
_session = new McpSession(this is IMcpServer, sessionTransport, EndpointName, RequestHandlers, NotificationHandlers, _logger);
70-
MessageProcessingTask = _session.ProcessMessagesAsync(_sessionCts.Token);
69+
}
70+
71+
[MemberNotNull(nameof(MessageProcessingTask))]
72+
protected void StartSession(ITransport sessionTransport, CancellationToken fullSessionCancellationToken)
73+
{
74+
_sessionCts = CancellationTokenSource.CreateLinkedTokenSource(fullSessionCancellationToken);
75+
MessageProcessingTask = GetSessionOrThrow().ProcessMessagesAsync(_sessionCts.Token);
7176
}
7277

7378
protected void CancelSession() => _sessionCts?.Cancel();
@@ -122,5 +127,5 @@ public virtual async ValueTask DisposeUnsynchronizedAsync()
122127
}
123128

124129
protected McpSession GetSessionOrThrow()
125-
=> _session ?? throw new InvalidOperationException($"This should be unreachable from public API! Call {nameof(StartSession)} before sending messages.");
130+
=> _session ?? throw new InvalidOperationException($"This should be unreachable from public API! Call {nameof(InitializeSession)} before sending messages.");
126131
}

0 commit comments

Comments
 (0)