Refactor transports to help enable graceful shutdown (#142)

- This also paves the way for better multi-session support
- We should definitely rethink names for the transport API
- For now, I kept the names similar as possible, so we can
  focus on the API shape

Co-authored-by: Stephen Toub <stoub@microsoft.com>
This commit is contained in:
Stephen Halter 2025-03-30 17:10:14 -07:00 • committed by GitHub
commit 2ab9db0878
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 2015 additions and 1847 deletions

View file

@ -3,6 +3,9 @@ using ModelContextProtocol.Hosting;
using ModelContextProtocol.Protocol.Transport;
using ModelContextProtocol.Utils;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ModelContextProtocol.Server;
namespace ModelContextProtocol;
@ -19,8 +22,18 @@ public static partial class McpServerBuilderExtensions
{
Throw.IfNull(builder);
builder.Services.AddSingleton<IServerTransport, StdioServerTransport>();
builder.Services.AddHostedService<McpServerHostedService>();
builder.Services.AddSingleton<ITransport, StdioServerTransport>();
builder.Services.AddHostedService<McpServerSingleSessionHostedService>();
builder.Services.AddSingleton(services =>
{
ITransport serverTransport = services.GetRequiredService<ITransport>();
IOptions<McpServerOptions> options = services.GetRequiredService<IOptions<McpServerOptions>>();
ILoggerFactory? loggerFactory = services.GetService<ILoggerFactory>();
return McpServerFactory.Create(serverTransport, options.Value, loggerFactory, services);
});
return builder;
}
@ -33,7 +46,7 @@ public static partial class McpServerBuilderExtensions
Throw.IfNull(builder);
builder.Services.AddSingleton<IServerTransport, HttpListenerSseServerTransport>();
builder.Services.AddHostedService<McpServerHostedService>();
builder.Services.AddHostedService<McpServerMultiSessionHostedService>();
return builder;
}
}

View file

@ -8,7 +8,7 @@ using Microsoft.Extensions.Options;
namespace ModelContextProtocol;
/// <summary>
/// Extension to host the MCP server
/// Extension to host an MCP server
/// </summary>
public static class McpServerServiceCollectionExtension
{
@ -20,15 +20,6 @@ public static class McpServerServiceCollectionExtension
/// <returns></returns>
public static IMcpServerBuilder AddMcpServer(this IServiceCollection services, Action<McpServerOptions>? configureOptions = null)
{
services.AddSingleton(services =>
{
IServerTransport serverTransport = services.GetRequiredService<IServerTransport>();
IOptions<McpServerOptions> options = services.GetRequiredService<IOptions<McpServerOptions>>();
ILoggerFactory? loggerFactory = services.GetService<ILoggerFactory>();
return McpServerFactory.Create(serverTransport, options.Value, loggerFactory, services);
});
services.AddOptions();
services.AddTransient<IConfigureOptions<McpServerOptions>, McpServerOptionsSetup>();
if (configureOptions is not null)