List tools from DI once (#115)

* List tools from DI once

- Follow best practice to not mutate options outside of IConfigureOptions
- Long-term, we should move the repeated work from SetToolsHandler into
  an IPostConfigureOptions service or IMcpServerConnectionFactory

* Add Can_Create_Multiple_Servers_From_Options_And_List_Registered_Tools

* Flip stdin and stdout in StreamClientTransport

* s/McpToolType/McpServerToolType

* Clarify stdin and stdout refers to server process in StreamClientTransport

* fixup
This commit is contained in:
Stephen Halter 2025-03-27 04:26:14 -07:00 • committed by GitHub
commit 4a53f6f6d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -9,16 +9,16 @@ namespace ModelContextProtocol.Tests.Transport;
internal sealed class StreamClientTransport : TransportBase, IClientTransport
{
private readonly JsonSerializerOptions _jsonOptions = McpJsonUtilities.DefaultOptions;
private Task? _readTask;
private CancellationTokenSource _shutdownCts = new CancellationTokenSource();
private readonly TextReader _stdin;
private readonly TextWriter _stdout;
private readonly Task? _readTask;
private readonly CancellationTokenSource _shutdownCts = new CancellationTokenSource();
private readonly TextReader _serverStdoutReader;
private readonly TextWriter _serverStdinWriter;
public StreamClientTransport(TextReader stdin, TextWriter stdout)
public StreamClientTransport(TextWriter serverStdinWriter, TextReader serverStdoutReader)
: base(NullLoggerFactory.Instance)
{
_stdin = stdin;
_stdout = stdout;
_serverStdoutReader = serverStdoutReader;
_serverStdinWriter = serverStdinWriter;
_readTask = Task.Run(() => ReadMessagesAsync(_shutdownCts.Token), CancellationToken.None);
SetConnected(true);
}
@ -31,13 +31,13 @@ internal sealed class StreamClientTransport : TransportBase, IClientTransport
messageWithId.Id.ToString() :
"(no id)";
await _stdout.WriteLineAsync(JsonSerializer.Serialize(message)).ConfigureAwait(false);
await _stdout.FlushAsync(cancellationToken).ConfigureAwait(false);
await _serverStdinWriter.WriteLineAsync(JsonSerializer.Serialize(message)).ConfigureAwait(false);
await _serverStdinWriter.FlushAsync(cancellationToken).ConfigureAwait(false);
}
private async Task ReadMessagesAsync(CancellationToken cancellationToken)
{
while (await _stdin.ReadLineAsync(cancellationToken).ConfigureAwait(false) is string line)
while (await _serverStdoutReader.ReadLineAsync(cancellationToken).ConfigureAwait(false) is string line)
{
if (!string.IsNullOrWhiteSpace(line))
{