4
4
using ModelContextProtocol . Utils . Json ;
5
5
using Microsoft . Extensions . AI ;
6
6
using System . Text . Json ;
7
+ using System . Runtime . CompilerServices ;
7
8
8
9
namespace ModelContextProtocol . Client ;
9
10
@@ -45,25 +46,25 @@ public static Task PingAsync(this IMcpClient client, CancellationToken cancellat
45
46
}
46
47
47
48
/// <summary>
48
- /// Retrieves a sequence of available tools from the server.
49
+ /// Retrieves a list of available tools from the server.
49
50
/// </summary>
50
51
/// <param name="client">The client.</param>
51
52
/// <param name="cancellationToken">A token to cancel the operation.</param>
52
- /// <returns>An asynchronous sequence of tool information .</returns>
53
+ /// <returns>A list of all available tools .</returns>
53
54
public static async Task < IList < McpClientTool > > ListToolsAsync (
54
55
this IMcpClient client , CancellationToken cancellationToken = default )
55
56
{
56
57
Throw . IfNull ( client ) ;
57
58
58
- List < McpClientTool > tools = [ ] ;
59
-
59
+ List < McpClientTool > ? tools = null ;
60
60
string ? cursor = null ;
61
61
do
62
62
{
63
63
var toolResults = await client . SendRequestAsync < ListToolsResult > (
64
64
CreateRequest ( "tools/list" , CreateCursorDictionary ( cursor ) ) ,
65
65
cancellationToken ) . ConfigureAwait ( false ) ;
66
66
67
+ tools ??= new List < McpClientTool > ( toolResults . Tools . Count ) ;
67
68
foreach ( var tool in toolResults . Tools )
68
69
{
69
70
tools . Add ( new McpClientTool ( client , tool ) ) ;
@@ -76,12 +77,44 @@ public static async Task<IList<McpClientTool>> ListToolsAsync(
76
77
return tools ;
77
78
}
78
79
80
+ /// <summary>
81
+ /// Creates an enumerable for asynchronously enumerating all available tools from the server.
82
+ /// </summary>
83
+ /// <param name="client">The client.</param>
84
+ /// <param name="cancellationToken">A token to cancel the operation.</param>
85
+ /// <returns>An asynchronous sequence of all available tools.</returns>
86
+ /// <remarks>
87
+ /// Every iteration through the returned <see cref="IAsyncEnumerable{McpClientTool}"/>
88
+ /// will result in requerying the server and yielding the sequence of available tools.
89
+ /// </remarks>
90
+ public static async IAsyncEnumerable < McpClientTool > EnumerateToolsAsync (
91
+ this IMcpClient client , [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
92
+ {
93
+ Throw . IfNull ( client ) ;
94
+
95
+ string ? cursor = null ;
96
+ do
97
+ {
98
+ var toolResults = await client . SendRequestAsync < ListToolsResult > (
99
+ CreateRequest ( "tools/list" , CreateCursorDictionary ( cursor ) ) ,
100
+ cancellationToken ) . ConfigureAwait ( false ) ;
101
+
102
+ foreach ( var tool in toolResults . Tools )
103
+ {
104
+ yield return new McpClientTool ( client , tool ) ;
105
+ }
106
+
107
+ cursor = toolResults . NextCursor ;
108
+ }
109
+ while ( cursor is not null ) ;
110
+ }
111
+
79
112
/// <summary>
80
113
/// Retrieves a list of available prompts from the server.
81
114
/// </summary>
82
115
/// <param name="client">The client.</param>
83
116
/// <param name="cancellationToken">A token to cancel the operation.</param>
84
- /// <returns>An asynchronous sequence of prompt information .</returns>
117
+ /// <returns>A list of all available prompts .</returns>
85
118
public static async Task < IList < Prompt > > ListPromptsAsync (
86
119
this IMcpClient client , CancellationToken cancellationToken = default )
87
120
{
@@ -112,6 +145,38 @@ public static async Task<IList<Prompt>> ListPromptsAsync(
112
145
return prompts ;
113
146
}
114
147
148
+ /// <summary>
149
+ /// Creates an enumerable for asynchronously enumerating all available prompts from the server.
150
+ /// </summary>
151
+ /// <param name="client">The client.</param>
152
+ /// <param name="cancellationToken">A token to cancel the operation.</param>
153
+ /// <returns>An asynchronous sequence of all available prompts.</returns>
154
+ /// <remarks>
155
+ /// Every iteration through the returned <see cref="IAsyncEnumerable{Prompt}"/>
156
+ /// will result in requerying the server and yielding the sequence of available prompts.
157
+ /// </remarks>
158
+ public static async IAsyncEnumerable < Prompt > EnumeratePromptsAsync (
159
+ this IMcpClient client , [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
160
+ {
161
+ Throw . IfNull ( client ) ;
162
+
163
+ string ? cursor = null ;
164
+ do
165
+ {
166
+ var promptResults = await client . SendRequestAsync < ListPromptsResult > (
167
+ CreateRequest ( "prompts/list" , CreateCursorDictionary ( cursor ) ) ,
168
+ cancellationToken ) . ConfigureAwait ( false ) ;
169
+
170
+ foreach ( var prompt in promptResults . Prompts )
171
+ {
172
+ yield return prompt ;
173
+ }
174
+
175
+ cursor = promptResults . NextCursor ;
176
+ }
177
+ while ( cursor is not null ) ;
178
+ }
179
+
115
180
/// <summary>
116
181
/// Retrieves a specific prompt with optional arguments.
117
182
/// </summary>
@@ -132,11 +197,11 @@ public static Task<GetPromptResult> GetPromptAsync(
132
197
}
133
198
134
199
/// <summary>
135
- /// Retrieves a sequence of available resource templates from the server.
200
+ /// Retrieves a list of available resource templates from the server.
136
201
/// </summary>
137
202
/// <param name="client">The client.</param>
138
203
/// <param name="cancellationToken">A token to cancel the operation.</param>
139
- /// <returns>An asynchronous sequence of resource template information .</returns>
204
+ /// <returns>A list of all available resource templates .</returns>
140
205
public static async Task < IList < ResourceTemplate > > ListResourceTemplatesAsync (
141
206
this IMcpClient client , CancellationToken cancellationToken = default )
142
207
{
@@ -168,11 +233,43 @@ public static async Task<IList<ResourceTemplate>> ListResourceTemplatesAsync(
168
233
}
169
234
170
235
/// <summary>
171
- /// Retrieves a sequence of available resources from the server.
236
+ /// Creates an enumerable for asynchronously enumerating all available resource templates from the server.
237
+ /// </summary>
238
+ /// <param name="client">The client.</param>
239
+ /// <param name="cancellationToken">A token to cancel the operation.</param>
240
+ /// <returns>An asynchronous sequence of all available resource templates.</returns>
241
+ /// <remarks>
242
+ /// Every iteration through the returned <see cref="IAsyncEnumerable{ResourceTemplate}"/>
243
+ /// will result in requerying the server and yielding the sequence of available resource templates.
244
+ /// </remarks>
245
+ public static async IAsyncEnumerable < ResourceTemplate > EnumerateResourceTemplatesAsync (
246
+ this IMcpClient client , [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
247
+ {
248
+ Throw . IfNull ( client ) ;
249
+
250
+ string ? cursor = null ;
251
+ do
252
+ {
253
+ var templateResults = await client . SendRequestAsync < ListResourceTemplatesResult > (
254
+ CreateRequest ( "resources/templates/list" , CreateCursorDictionary ( cursor ) ) ,
255
+ cancellationToken ) . ConfigureAwait ( false ) ;
256
+
257
+ foreach ( var template in templateResults . ResourceTemplates )
258
+ {
259
+ yield return template ;
260
+ }
261
+
262
+ cursor = templateResults . NextCursor ;
263
+ }
264
+ while ( cursor is not null ) ;
265
+ }
266
+
267
+ /// <summary>
268
+ /// Retrieves a list of available resources from the server.
172
269
/// </summary>
173
270
/// <param name="client">The client.</param>
174
271
/// <param name="cancellationToken">A token to cancel the operation.</param>
175
- /// <returns>An asynchronous sequence of resource information .</returns>
272
+ /// <returns>A list of all available resources .</returns>
176
273
public static async Task < IList < Resource > > ListResourcesAsync (
177
274
this IMcpClient client , CancellationToken cancellationToken = default )
178
275
{
@@ -203,6 +300,38 @@ public static async Task<IList<Resource>> ListResourcesAsync(
203
300
return resources ;
204
301
}
205
302
303
+ /// <summary>
304
+ /// Creates an enumerable for asynchronously enumerating all available resources from the server.
305
+ /// </summary>
306
+ /// <param name="client">The client.</param>
307
+ /// <param name="cancellationToken">A token to cancel the operation.</param>
308
+ /// <returns>An asynchronous sequence of all available resources.</returns>
309
+ /// <remarks>
310
+ /// Every iteration through the returned <see cref="IAsyncEnumerable{Resource}"/>
311
+ /// will result in requerying the server and yielding the sequence of available resources.
312
+ /// </remarks>
313
+ public static async IAsyncEnumerable < Resource > EnumerateResourcesAsync (
314
+ this IMcpClient client , [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
315
+ {
316
+ Throw . IfNull ( client ) ;
317
+
318
+ string ? cursor = null ;
319
+ do
320
+ {
321
+ var resourceResults = await client . SendRequestAsync < ListResourcesResult > (
322
+ CreateRequest ( "resources/list" , CreateCursorDictionary ( cursor ) ) ,
323
+ cancellationToken ) . ConfigureAwait ( false ) ;
324
+
325
+ foreach ( var resource in resourceResults . Resources )
326
+ {
327
+ yield return resource ;
328
+ }
329
+
330
+ cursor = resourceResults . NextCursor ;
331
+ }
332
+ while ( cursor is not null ) ;
333
+ }
334
+
206
335
/// <summary>
207
336
/// Reads a resource from the server.
208
337
/// </summary>
0 commit comments