1
1
using Microsoft . Extensions . AI ;
2
2
using Microsoft . Extensions . DependencyInjection ;
3
+ using Microsoft . Extensions . Logging ;
4
+ using Microsoft . Extensions . Logging . Abstractions ;
3
5
using ModelContextProtocol . Protocol ;
4
6
using System . ComponentModel ;
5
7
using System . Diagnostics . CodeAnalysis ;
@@ -11,6 +13,8 @@ namespace ModelContextProtocol.Server;
11
13
/// <summary>Provides an <see cref="McpServerTool"/> that's implemented via an <see cref="AIFunction"/>.</summary>
12
14
internal sealed class AIFunctionMcpServerTool : McpServerTool
13
15
{
16
+ private readonly ILogger _logger ;
17
+
14
18
/// <summary>
15
19
/// Creates an <see cref="McpServerTool"/> instance for a method, specified via a <see cref="Delegate"/> instance.
16
20
/// </summary>
@@ -19,7 +23,7 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
19
23
McpServerToolCreateOptions ? options )
20
24
{
21
25
Throw . IfNull ( method ) ;
22
-
26
+
23
27
options = DeriveOptions ( method . Method , options ) ;
24
28
25
29
return Create ( method . Method , method . Target , options ) ;
@@ -172,7 +176,7 @@ private static AIFunctionFactoryOptions CreateAIFunctionFactoryOptions(
172
176
{
173
177
Name = options ? . Name ?? function . Name ,
174
178
Description = options ? . Description ?? function . Description ,
175
- InputSchema = function . JsonSchema ,
179
+ InputSchema = function . JsonSchema ,
176
180
} ;
177
181
178
182
if ( options is not null )
@@ -194,7 +198,7 @@ options.OpenWorld is not null ||
194
198
}
195
199
}
196
200
197
- return new AIFunctionMcpServerTool ( function , tool ) ;
201
+ return new AIFunctionMcpServerTool ( function , tool , options ? . Services ) ;
198
202
}
199
203
200
204
private static McpServerToolCreateOptions DeriveOptions ( MethodInfo method , McpServerToolCreateOptions ? options )
@@ -239,10 +243,11 @@ private static McpServerToolCreateOptions DeriveOptions(MethodInfo method, McpSe
239
243
internal AIFunction AIFunction { get ; }
240
244
241
245
/// <summary>Initializes a new instance of the <see cref="McpServerTool"/> class.</summary>
242
- private AIFunctionMcpServerTool ( AIFunction function , Tool tool )
246
+ private AIFunctionMcpServerTool ( AIFunction function , Tool tool , IServiceProvider ? serviceProvider )
243
247
{
244
248
AIFunction = function ;
245
249
ProtocolTool = tool ;
250
+ _logger = serviceProvider ? . GetService < ILoggerFactory > ( ) ? . CreateLogger < AIFunctionMcpServerTool > ( ) ?? ( ILogger ) NullLogger . Instance ;
246
251
}
247
252
248
253
/// <inheritdoc />
@@ -277,6 +282,9 @@ public override async ValueTask<CallToolResponse> InvokeAsync(
277
282
}
278
283
catch ( Exception e ) when ( e is not OperationCanceledException )
279
284
{
285
+ _logger . LogError ( e , "Error invoking AIFunction tool '{ToolName}' with arguments '{Args}'." ,
286
+ request . Params ? . Name , string . Join ( "," , request . Params ? . Arguments ? . Keys ?? Array . Empty < string > ( ) ) ) ;
287
+
280
288
string errorMessage = e is McpException ?
281
289
$ "An error occurred invoking '{ request . Params ? . Name } ': { e . Message } " :
282
290
$ "An error occurred invoking '{ request . Params ? . Name } '.";
@@ -300,29 +308,29 @@ public override async ValueTask<CallToolResponse> InvokeAsync(
300
308
{
301
309
Content = [ ]
302
310
} ,
303
-
311
+
304
312
string text => new ( )
305
313
{
306
314
Content = [ new ( ) { Text = text , Type = "text" } ]
307
315
} ,
308
-
316
+
309
317
Content content => new ( )
310
318
{
311
319
Content = [ content ]
312
320
} ,
313
-
321
+
314
322
IEnumerable < string > texts => new ( )
315
323
{
316
324
Content = [ .. texts . Select ( x => new Content ( ) { Type = "text" , Text = x ?? string . Empty } ) ]
317
325
} ,
318
-
326
+
319
327
IEnumerable < AIContent > contentItems => ConvertAIContentEnumerableToCallToolResponse ( contentItems ) ,
320
-
328
+
321
329
IEnumerable < Content > contents => new ( )
322
330
{
323
331
Content = [ .. contents ]
324
332
} ,
325
-
333
+
326
334
CallToolResponse callToolResponse => callToolResponse ,
327
335
328
336
_ => new ( )
0 commit comments