diff --git a/src/ModelContextProtocol/Client/McpClient.cs b/src/ModelContextProtocol/Client/McpClient.cs index d871af1..cf27a6b 100644 --- a/src/ModelContextProtocol/Client/McpClient.cs +++ b/src/ModelContextProtocol/Client/McpClient.cs @@ -10,7 +10,7 @@ using System.Text.Json; namespace ModelContextProtocol.Client; /// -internal sealed class McpClient : McpJsonRpcEndpoint, IMcpClient +internal sealed class McpClient : McpEndpoint, IMcpClient { private readonly IClientTransport _clientTransport; private readonly McpClientOptions _options; diff --git a/src/ModelContextProtocol/Configuration/McpServerConfig.cs b/src/ModelContextProtocol/Configuration/McpServerConfig.cs index c8d0a26..27cd39e 100644 --- a/src/ModelContextProtocol/Configuration/McpServerConfig.cs +++ b/src/ModelContextProtocol/Configuration/McpServerConfig.cs @@ -27,11 +27,6 @@ public record McpServerConfig /// public string? Location { get; set; } - /// - /// Arguments (if any) to pass to the executable. - /// - public string[]? Arguments { get; init; } - /// /// Additional transport-specific configuration. /// diff --git a/src/ModelContextProtocol/Protocol/Transport/SseResponseStreamTransport.cs b/src/ModelContextProtocol/Protocol/Transport/SseResponseStreamTransport.cs index d375aa6..359de5e 100644 --- a/src/ModelContextProtocol/Protocol/Transport/SseResponseStreamTransport.cs +++ b/src/ModelContextProtocol/Protocol/Transport/SseResponseStreamTransport.cs @@ -76,7 +76,8 @@ public sealed class SseResponseStreamTransport(Stream sseResponseStream, string throw new InvalidOperationException($"Transport is not connected. Make sure to call {nameof(RunAsync)} first."); } - await _outgoingSseChannel.Writer.WriteAsync(new SseItem(message), cancellationToken); + // Emit redundant "event: message" lines for better compatibility with other SDKs. + await _outgoingSseChannel.Writer.WriteAsync(new SseItem(message, SseParser.EventTypeDefault), cancellationToken); } /// diff --git a/src/ModelContextProtocol/Server/McpServer.cs b/src/ModelContextProtocol/Server/McpServer.cs index 80a28d3..499f2ef 100644 --- a/src/ModelContextProtocol/Server/McpServer.cs +++ b/src/ModelContextProtocol/Server/McpServer.cs @@ -9,7 +9,7 @@ using ModelContextProtocol.Utils.Json; namespace ModelContextProtocol.Server; /// -internal sealed class McpServer : McpJsonRpcEndpoint, IMcpServer +internal sealed class McpServer : McpEndpoint, IMcpServer { private readonly EventHandler? _toolsChangedDelegate; private readonly EventHandler? _promptsChangedDelegate; diff --git a/src/ModelContextProtocol/Shared/McpJsonRpcEndpoint.cs b/src/ModelContextProtocol/Shared/McpEndpoint.cs similarity index 94% rename from src/ModelContextProtocol/Shared/McpJsonRpcEndpoint.cs rename to src/ModelContextProtocol/Shared/McpEndpoint.cs index 052cc16..8b50a80 100644 --- a/src/ModelContextProtocol/Shared/McpJsonRpcEndpoint.cs +++ b/src/ModelContextProtocol/Shared/McpEndpoint.cs @@ -17,7 +17,7 @@ namespace ModelContextProtocol.Shared; /// This is especially true as a client represents a connection to one and only one server, and vice versa. /// Any multi-client or multi-server functionality should be implemented at a higher level of abstraction. /// -internal abstract class McpJsonRpcEndpoint : IAsyncDisposable +internal abstract class McpEndpoint : IAsyncDisposable { private readonly RequestHandlers _requestHandlers = []; private readonly NotificationHandlers _notificationHandlers = []; @@ -31,10 +31,10 @@ internal abstract class McpJsonRpcEndpoint : IAsyncDisposable protected readonly ILogger _logger; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The logger factory. - protected McpJsonRpcEndpoint(ILoggerFactory? loggerFactory = null) + protected McpEndpoint(ILoggerFactory? loggerFactory = null) { _logger = loggerFactory?.CreateLogger(GetType()) ?? NullLogger.Instance; } @@ -64,7 +64,7 @@ internal abstract class McpJsonRpcEndpoint : IAsyncDisposable /// /// Task that processes incoming messages from the transport. /// - protected Task? MessageProcessingTask { get; set; } + protected Task? MessageProcessingTask { get; private set; } [MemberNotNull(nameof(MessageProcessingTask))] protected void StartSession(ITransport sessionTransport) diff --git a/src/ModelContextProtocol/Shared/McpSession.cs b/src/ModelContextProtocol/Shared/McpSession.cs index 46c3279..e9aed2f 100644 --- a/src/ModelContextProtocol/Shared/McpSession.cs +++ b/src/ModelContextProtocol/Shared/McpSession.cs @@ -45,7 +45,7 @@ internal sealed class McpSession : IDisposable /// private readonly ConcurrentDictionary _handlingRequests = new(); private readonly ILogger _logger; - + private readonly string _id = Guid.NewGuid().ToString("N"); private long _nextRequestId; diff --git a/tests/ModelContextProtocol.Tests/SseServerIntegrationTests.cs b/tests/ModelContextProtocol.Tests/SseServerIntegrationTests.cs index 004e54a..b73a9c0 100644 --- a/tests/ModelContextProtocol.Tests/SseServerIntegrationTests.cs +++ b/tests/ModelContextProtocol.Tests/SseServerIntegrationTests.cs @@ -1,6 +1,8 @@ using ModelContextProtocol.Client; using ModelContextProtocol.Protocol.Types; using ModelContextProtocol.Tests.Utils; +using System.Net; +using System.Text; namespace ModelContextProtocol.Tests; @@ -30,6 +32,12 @@ public class SseServerIntegrationTests : LoggedTest, IClassFixture + new() + { + BaseAddress = new(_fixture.DefaultConfig.Location!), + }; + [Fact] public async Task ConnectAndPing_Sse_TestServer() { @@ -271,4 +279,44 @@ public class SseServerIntegrationTests : LoggedTest, IClassFixture