Server support (stdio) (#19)

* Server support (stdio)
* TestServer project
* Refactored McpClient class to extract shared endpoint logic (with McpServer) to a base class, McpJsonRpcEndpoint.
* Improved xmldoc comments for protocol types, mirroring specification schema comments.
* Update README.MD
This commit is contained in:
Peder Holdgaard Pedersen 2025-02-08 16:21:26 +01:00 • committed by GitHub
commit 8fe797e1f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,6 @@
using System.Threading.Channels;
using Microsoft.Extensions.Logging;
using McpDotNet.Logging;
using McpDotNet.Protocol.Messages;
namespace McpDotNet.Protocol.Transport;
@ -6,15 +8,16 @@ namespace McpDotNet.Protocol.Transport;
/// <summary>
/// Base class for implementing MCP transports with common functionality.
/// </summary>
public abstract class TransportBase : IMcpTransport
public abstract class TransportBase : ITransport
{
private readonly Channel<IJsonRpcMessage> _messageChannel;
private readonly ILogger<TransportBase> _logger;
private bool _isConnected;
/// <summary>
/// Initializes a new instance of the <see cref="TransportBase"/> class.
/// </summary>
protected TransportBase()
protected TransportBase(ILoggerFactory loggerFactory)
{
// Unbounded channel to prevent blocking on writes
_messageChannel = Channel.CreateUnbounded<IJsonRpcMessage>(new UnboundedChannelOptions
@ -22,6 +25,7 @@ public abstract class TransportBase : IMcpTransport
SingleReader = true,
SingleWriter = true,
});
_logger = loggerFactory.CreateLogger<TransportBase>();
}
/// <inheritdoc/>
@ -30,9 +34,6 @@ public abstract class TransportBase : IMcpTransport
/// <inheritdoc/>
public ChannelReader<IJsonRpcMessage> MessageReader => _messageChannel.Reader;
/// <inheritdoc/>
public abstract Task ConnectAsync(CancellationToken cancellationToken = default);
/// <inheritdoc/>
public abstract Task SendMessageAsync(IJsonRpcMessage message, CancellationToken cancellationToken = default);
@ -51,7 +52,9 @@ public abstract class TransportBase : IMcpTransport
throw new McpTransportException("Transport is not connected");
}
_logger.TransportWritingMessageToChannel(message);
await _messageChannel.Writer.WriteAsync(message, cancellationToken);
_logger.TransportMessageWrittenToChannel();
}
/// <summary>