1
1
using System . Text . Json ;
2
+ using McpDotNet . Configuration ;
2
3
using McpDotNet . Logging ;
3
4
using McpDotNet . Protocol . Messages ;
4
5
using McpDotNet . Server ;
5
6
using McpDotNet . Utils . Json ;
6
7
using Microsoft . Extensions . Logging ;
7
8
using Microsoft . Extensions . Logging . Abstractions ;
8
9
10
+ #pragma warning disable CA2208 // Instantiate argument exceptions correctly
11
+
9
12
namespace McpDotNet . Protocol . Transport ;
10
13
11
14
/// <summary>
12
- /// Implements the MCP transport protocol over standard input/output streams.
15
+ /// Provides an implementation of the MCP transport protocol over standard input/output streams.
13
16
/// </summary>
14
17
public sealed class StdioServerTransport : TransportBase , IServerTransport
15
18
{
@@ -24,47 +27,90 @@ public sealed class StdioServerTransport : TransportBase, IServerTransport
24
27
private string EndpointName => $ "Server (stdio) ({ _serverName } )";
25
28
26
29
/// <summary>
27
- /// Initializes a new instance of the StdioServerTransport class.
30
+ /// Initializes a new instance of the <see cref="StdioServerTransport"/> class, using
31
+ /// <see cref="Console.In"/> and <see cref="Console.Out"/> for input and output streams.
28
32
/// </summary>
29
33
/// <param name="serverOptions">The server options.</param>
30
- /// <param name="loggerFactory">A logger factory for creating loggers.</param>
31
- /// <param name="inputOutputStreams">Container for the input and output streams</param>
32
- public StdioServerTransport ( McpServerOptions serverOptions , ILoggerFactory ? loggerFactory , InputOutputStreams inputOutputStreams )
33
- : this (
34
- serverOptions is not null ? serverOptions . ServerInfo . Name : throw new ArgumentNullException ( nameof ( serverOptions ) ) ,
35
- loggerFactory ,
36
- inputOutputStreams is not null ? inputOutputStreams . Output : throw new ArgumentNullException ( nameof ( inputOutputStreams ) ) ,
37
- inputOutputStreams . Input
38
- )
34
+ /// <param name="loggerFactory">Optional logger factory used for logging employed by the transport.</param>
35
+ /// <exception cref="ArgumentNullException"><paramref name="serverOptions"/> is <see langword="null"/> or contains a null name.</exception>
36
+ /// <remarks>
37
+ /// <para>
38
+ /// By default, no logging is performed. If a <paramref name="loggerFactory"/> is supplied, it must not log
39
+ /// to <see cref="Console.Out"/>, as that will interfere with the transport's output.
40
+ /// </para>
41
+ /// </remarks>
42
+ public StdioServerTransport ( McpServerOptions serverOptions , ILoggerFactory ? loggerFactory = null )
43
+ : this ( GetServerName ( serverOptions ) , loggerFactory )
39
44
{
40
45
}
41
46
42
47
/// <summary>
43
- /// Initializes a new instance of the StdioServerTransport class.
48
+ /// Initializes a new instance of the <see cref="StdioServerTransport"/> class, using
49
+ /// <see cref="Console.In"/> and <see cref="Console.Out"/> for input and output streams.
44
50
/// </summary>
45
51
/// <param name="serverName">The name of the server.</param>
46
- /// <param name="loggerFactory">A logger factory for creating loggers.</param>
47
- public StdioServerTransport ( string serverName , ILoggerFactory ? loggerFactory )
48
- : this ( serverName , loggerFactory , Console . Out , Console . In )
52
+ /// <param name="loggerFactory">Optional logger factory used for logging employed by the transport.</param>
53
+ /// <exception cref="ArgumentNullException"><paramref name="serverName"/> is <see langword="null"/>.</exception>
54
+ /// <remarks>
55
+ /// <para>
56
+ /// By default, no logging is performed. If a <paramref name="loggerFactory"/> is supplied, it must not log
57
+ /// to <see cref="Console.Out"/>, as that will interfere with the transport's output.
58
+ /// </para>
59
+ /// </remarks>
60
+ public StdioServerTransport ( string serverName , ILoggerFactory ? loggerFactory = null )
61
+ : this ( serverName ?? throw new ArgumentNullException ( nameof ( serverName ) ) , Console . In , Console . Out , loggerFactory )
49
62
{
63
+ }
50
64
65
+ /// <summary>
66
+ /// Initializes a new instance of the <see cref="StdioServerTransport"/> class using the specified
67
+ /// <paramref name="input"/> and <paramref name="output"/> streams.
68
+ /// </summary>
69
+ /// <param name="serverOptions">The server options.</param>
70
+ /// <param name="input">The reader, from which all input is read.</param>
71
+ /// <param name="output">The writer, to which all output is written.</param>
72
+ /// <param name="loggerFactory">Optional logger factory used for logging employed by the transport.</param>
73
+ /// <exception cref="ArgumentNullException"><paramref name="serverOptions"/> is <see langword="null"/> or contains a null name.</exception>
74
+ /// <exception cref="ArgumentNullException"><paramref name="input"/> is <see langword="null"/>.</exception>
75
+ /// <exception cref="ArgumentNullException"><paramref name="output"/> is <see langword="null"/>.</exception>
76
+ /// <remarks>
77
+ /// <para>
78
+ /// By default, no logging is performed. If a <paramref name="loggerFactory"/> is supplied, it must not log
79
+ /// to <see cref="Console.Out"/>, as that will interfere with the transport's output.
80
+ /// </para>
81
+ /// </remarks>
82
+ public StdioServerTransport ( McpServerOptions serverOptions , TextReader input , TextWriter output , ILoggerFactory ? loggerFactory = null )
83
+ : this ( GetServerName ( serverOptions ) , input , output , loggerFactory )
84
+ {
51
85
}
52
86
53
87
/// <summary>
54
- /// Initializes a new instance of the StdioServerTransport class.
88
+ /// Initializes a new instance of the <see cref="StdioServerTransport"/> class using the specified
89
+ /// <paramref name="input"/> and <paramref name="output"/> streams.
55
90
/// </summary>
56
91
/// <param name="serverName">The name of the server.</param>
57
- /// <param name="loggerFactory">A logger factory for creating loggers.</param>
58
- /// <param name="output">The output stream writer</param>
59
- /// <param name="input">The input stream reader</param>
60
- public StdioServerTransport ( string serverName , ILoggerFactory ? loggerFactory , TextWriter output , TextReader input )
92
+ /// <param name="input">The reader, from which all input is read.</param>
93
+ /// <param name="output">The writer, to which all output is written.</param>
94
+ /// <param name="loggerFactory">Optional logger factory used for logging employed by the transport.</param>
95
+ /// <exception cref="ArgumentNullException"><paramref name="serverName"/> is <see langword="null"/>.</exception>
96
+ /// <exception cref="ArgumentNullException"><paramref name="input"/> is <see langword="null"/>.</exception>
97
+ /// <exception cref="ArgumentNullException"><paramref name="output"/> is <see langword="null"/>.</exception>
98
+ /// <remarks>
99
+ /// <para>
100
+ /// By default, no logging is performed. If a <paramref name="loggerFactory"/> is supplied, it must not log
101
+ /// to <see cref="Console.Out"/>, as that will interfere with the transport's output.
102
+ /// </para>
103
+ /// </remarks>
104
+ public StdioServerTransport ( string serverName , TextReader input , TextWriter output , ILoggerFactory ? loggerFactory = null )
61
105
: base ( loggerFactory )
62
106
{
63
- _serverName = serverName ;
64
- _logger = loggerFactory is not null ? loggerFactory . CreateLogger < StdioClientTransport > ( ) : NullLogger . Instance ;
65
- _jsonOptions = JsonSerializerOptionsExtensions . DefaultOptions ;
107
+ _serverName = serverName ?? throw new ArgumentNullException ( nameof ( serverName ) ) ;
66
108
_input = input ?? throw new ArgumentNullException ( nameof ( input ) ) ;
67
109
_output = output ?? throw new ArgumentNullException ( nameof ( output ) ) ;
110
+
111
+ _logger = loggerFactory is not null ? loggerFactory . CreateLogger < StdioClientTransport > ( ) : NullLogger . Instance ;
112
+
113
+ _jsonOptions = JsonSerializerOptionsExtensions . DefaultOptions ;
68
114
}
69
115
70
116
/// <inheritdoc/>
@@ -224,4 +270,20 @@ private async Task CleanupAsync(CancellationToken cancellationToken)
224
270
SetConnected ( false ) ;
225
271
_logger . TransportCleanedUp ( EndpointName ) ;
226
272
}
273
+
274
+ /// <summary>Validates the <paramref name="serverOptions"/> and extracts from it the server name to use.</summary>
275
+ private static string GetServerName ( McpServerOptions serverOptions )
276
+ {
277
+ if ( serverOptions is null )
278
+ {
279
+ throw new ArgumentNullException ( nameof ( serverOptions ) ) ;
280
+ }
281
+
282
+ if ( serverOptions . ServerInfo is null )
283
+ {
284
+ throw new ArgumentNullException ( $ "{ nameof ( serverOptions ) } .{ nameof ( serverOptions . ServerInfo ) } ") ;
285
+ }
286
+
287
+ return serverOptions . ServerInfo . Name ;
288
+ }
227
289
}
0 commit comments