11using ModelContextProtocol . Protocol . Messages ;
22using ModelContextProtocol . Utils ;
3+ using ModelContextProtocol . Utils . Json ;
4+ using System . Text . Json ;
5+ using System . Text . Json . Nodes ;
6+ using System . Text . Json . Serialization . Metadata ;
37
48namespace ModelContextProtocol ;
59
610/// <summary>Provides extension methods for interacting with an <see cref="IMcpEndpoint"/>.</summary>
711public static class McpEndpointExtensions
812{
13+ /// <summary>
14+ /// Sends a JSON-RPC request and attempts to deserialize the result to <typeparamref name="TResult"/>.
15+ /// </summary>
16+ /// <typeparam name="TParameters">The type of the request parameters to serialize from.</typeparam>
17+ /// <typeparam name="TResult">The type of the result to deserialize to.</typeparam>
18+ /// <param name="endpoint">The MCP client or server instance.</param>
19+ /// <param name="method">The JSON-RPC method name to invoke.</param>
20+ /// <param name="parameters">Object representing the request parameters.</param>
21+ /// <param name="requestId">The request id for the request.</param>
22+ /// <param name="serializerOptions">The options governing request serialization.</param>
23+ /// <param name="cancellationToken">A token to cancel the operation.</param>
24+ /// <returns>A task that represents the asynchronous operation. The task result contains the deserialized result.</returns>
25+ public static Task < TResult > SendRequestAsync < TParameters , TResult > (
26+ this IMcpEndpoint endpoint ,
27+ string method ,
28+ TParameters parameters ,
29+ JsonSerializerOptions ? serializerOptions = null ,
30+ RequestId ? requestId = null ,
31+ CancellationToken cancellationToken = default )
32+ where TResult : notnull
33+ {
34+ serializerOptions ??= McpJsonUtilities . DefaultOptions ;
35+ serializerOptions . MakeReadOnly ( ) ;
36+
37+ JsonTypeInfo < TParameters > paramsTypeInfo = serializerOptions . GetTypeInfo < TParameters > ( ) ;
38+ JsonTypeInfo < TResult > resultTypeInfo = serializerOptions . GetTypeInfo < TResult > ( ) ;
39+ return SendRequestAsync ( endpoint , method , parameters , paramsTypeInfo , resultTypeInfo , requestId , cancellationToken ) ;
40+ }
41+
42+ /// <summary>
43+ /// Sends a JSON-RPC request and attempts to deserialize the result to <typeparamref name="TResult"/>.
44+ /// </summary>
45+ /// <typeparam name="TParameters">The type of the request parameters to serialize from.</typeparam>
46+ /// <typeparam name="TResult">The type of the result to deserialize to.</typeparam>
47+ /// <param name="endpoint">The MCP client or server instance.</param>
48+ /// <param name="method">The JSON-RPC method name to invoke.</param>
49+ /// <param name="parameters">Object representing the request parameters.</param>
50+ /// <param name="parametersTypeInfo">The type information for request parameter serialization.</param>
51+ /// <param name="resultTypeInfo">The type information for request parameter deserialization.</param>
52+ /// <param name="requestId">The request id for the request.</param>
53+ /// <param name="cancellationToken">A token to cancel the operation.</param>
54+ /// <returns>A task that represents the asynchronous operation. The task result contains the deserialized result.</returns>
55+ internal static async Task < TResult > SendRequestAsync < TParameters , TResult > (
56+ this IMcpEndpoint endpoint ,
57+ string method ,
58+ TParameters parameters ,
59+ JsonTypeInfo < TParameters > parametersTypeInfo ,
60+ JsonTypeInfo < TResult > resultTypeInfo ,
61+ RequestId ? requestId = null ,
62+ CancellationToken cancellationToken = default )
63+ where TResult : notnull
64+ {
65+ Throw . IfNull ( endpoint ) ;
66+ Throw . IfNullOrWhiteSpace ( method ) ;
67+ Throw . IfNull ( parametersTypeInfo ) ;
68+ Throw . IfNull ( resultTypeInfo ) ;
69+
70+ JsonRpcRequest jsonRpcRequest = new ( )
71+ {
72+ Method = method ,
73+ Params = JsonSerializer . SerializeToNode ( parameters , parametersTypeInfo ) ,
74+ } ;
75+
76+ if ( requestId is { } id )
77+ {
78+ jsonRpcRequest . Id = id ;
79+ }
80+
81+ JsonRpcResponse response = await endpoint . SendRequestAsync ( jsonRpcRequest , cancellationToken ) . ConfigureAwait ( false ) ;
82+ return JsonSerializer . Deserialize ( response . Result , resultTypeInfo ) ?? throw new JsonException ( "Unexpected JSON result in response." ) ;
83+ }
84+
85+ /// <summary>
86+ /// Sends a notification to the server with parameters.
87+ /// </summary>
88+ /// <param name="client">The client.</param>
89+ /// <param name="method">The notification method name.</param>
90+ /// <param name="cancellationToken">A token to cancel the operation.</param>
91+ public static Task SendNotificationAsync ( this IMcpEndpoint client , string method , CancellationToken cancellationToken = default )
92+ {
93+ Throw . IfNull ( client ) ;
94+ Throw . IfNullOrWhiteSpace ( method ) ;
95+ return client . SendMessageAsync ( new JsonRpcNotification { Method = method } , cancellationToken ) ;
96+ }
97+
98+ /// <summary>
99+ /// Sends a notification to the server with parameters.
100+ /// </summary>
101+ /// <param name="endpoint">The MCP client or server instance.</param>
102+ /// <param name="method">The JSON-RPC method name to invoke.</param>
103+ /// <param name="parameters">Object representing the request parameters.</param>
104+ /// <param name="serializerOptions">The options governing request serialization.</param>
105+ /// <param name="cancellationToken">A token to cancel the operation.</param>
106+ public static Task SendNotificationAsync < TParameters > (
107+ this IMcpEndpoint endpoint ,
108+ string method ,
109+ TParameters parameters ,
110+ JsonSerializerOptions ? serializerOptions = null ,
111+ CancellationToken cancellationToken = default )
112+ {
113+ serializerOptions ??= McpJsonUtilities . DefaultOptions ;
114+ serializerOptions . MakeReadOnly ( ) ;
115+
116+ JsonTypeInfo < TParameters > parametersTypeInfo = serializerOptions . GetTypeInfo < TParameters > ( ) ;
117+ return SendNotificationAsync ( endpoint , method , parameters , parametersTypeInfo , cancellationToken ) ;
118+ }
119+
120+ /// <summary>
121+ /// Sends a notification to the server with parameters.
122+ /// </summary>
123+ /// <param name="endpoint">The MCP client or server instance.</param>
124+ /// <param name="method">The JSON-RPC method name to invoke.</param>
125+ /// <param name="parameters">Object representing the request parameters.</param>
126+ /// <param name="parametersTypeInfo">The type information for request parameter serialization.</param>
127+ /// <param name="cancellationToken">A token to cancel the operation.</param>
128+ internal static Task SendNotificationAsync < TParameters > (
129+ this IMcpEndpoint endpoint ,
130+ string method ,
131+ TParameters parameters ,
132+ JsonTypeInfo < TParameters > parametersTypeInfo ,
133+ CancellationToken cancellationToken = default )
134+ {
135+ Throw . IfNull ( endpoint ) ;
136+ Throw . IfNullOrWhiteSpace ( method ) ;
137+ Throw . IfNull ( parametersTypeInfo ) ;
138+
139+ JsonNode ? parametersJson = JsonSerializer . SerializeToNode ( parameters , parametersTypeInfo ) ;
140+ return endpoint . SendMessageAsync ( new JsonRpcNotification { Method = method , Params = parametersJson } , cancellationToken ) ;
141+ }
142+
9143 /// <summary>Notifies the connected endpoint of progress.</summary>
10- /// <param name="endpoint">The endpoint issueing the notification.</param>
144+ /// <param name="endpoint">The endpoint issuing the notification.</param>
11145 /// <param name="progressToken">The <see cref="ProgressToken"/> identifying the operation.</param>
12146 /// <param name="progress">The progress update to send.</param>
13147 /// <param name="cancellationToken">A token to cancel the operation.</param>
@@ -24,11 +158,11 @@ public static Task NotifyProgressAsync(
24158 return endpoint . SendMessageAsync ( new JsonRpcNotification ( )
25159 {
26160 Method = NotificationMethods . ProgressNotification ,
27- Params = new ProgressNotification ( )
161+ Params = JsonSerializer . SerializeToNode ( new ProgressNotification
28162 {
29163 ProgressToken = progressToken ,
30164 Progress = progress ,
31- } ,
165+ } , McpJsonUtilities . JsonContext . Default . ProgressNotification ) ,
32166 } , cancellationToken ) ;
33167 }
34168}
0 commit comments