11using Microsoft . Extensions . AI ;
22using Microsoft . Extensions . DependencyInjection ;
3+ using Microsoft . Extensions . Logging ;
4+ using Microsoft . Extensions . Logging . Abstractions ;
35using ModelContextProtocol . Protocol ;
46using System . ComponentModel ;
57using System . Diagnostics . CodeAnalysis ;
911namespace ModelContextProtocol . Server ;
1012
1113/// <summary>Provides an <see cref="McpServerTool"/> that's implemented via an <see cref="AIFunction"/>.</summary>
12- internal sealed class AIFunctionMcpServerTool : McpServerTool
14+ internal sealed partial class AIFunctionMcpServerTool : McpServerTool
1315{
16+ private readonly ILogger _logger ;
17+
1418 /// <summary>
1519 /// Creates an <see cref="McpServerTool"/> instance for a method, specified via a <see cref="Delegate"/> instance.
1620 /// </summary>
@@ -194,7 +198,7 @@ options.OpenWorld is not null ||
194198 }
195199 }
196200
197- return new AIFunctionMcpServerTool ( function , tool ) ;
201+ return new AIFunctionMcpServerTool ( function , tool , options ? . Services ) ;
198202 }
199203
200204 private static McpServerToolCreateOptions DeriveOptions ( MethodInfo method , McpServerToolCreateOptions ? options )
@@ -239,10 +243,11 @@ private static McpServerToolCreateOptions DeriveOptions(MethodInfo method, McpSe
239243 internal AIFunction AIFunction { get ; }
240244
241245 /// <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 )
243247 {
244248 AIFunction = function ;
245249 ProtocolTool = tool ;
250+ _logger = serviceProvider ? . GetService < ILoggerFactory > ( ) ? . CreateLogger < McpServerTool > ( ) ?? ( ILogger ) NullLogger . Instance ;
246251 }
247252
248253 /// <inheritdoc />
@@ -277,6 +282,8 @@ public override async ValueTask<CallToolResponse> InvokeAsync(
277282 }
278283 catch ( Exception e ) when ( e is not OperationCanceledException )
279284 {
285+ ToolCallError ( request . Params ? . Name ?? string . Empty , e ) ;
286+
280287 string errorMessage = e is McpException ?
281288 $ "An error occurred invoking '{ request . Params ? . Name } ': { e . Message } " :
282289 $ "An error occurred invoking '{ request . Params ? . Name } '.";
@@ -359,4 +366,7 @@ private static CallToolResponse ConvertAIContentEnumerableToCallToolResponse(IEn
359366 IsError = allErrorContent && hasAny
360367 } ;
361368 }
369+
370+ [ LoggerMessage ( Level = LogLevel . Error , Message = "\" {ToolName}\" threw an unhandled exception." ) ]
371+ private partial void ToolCallError ( string toolName , Exception exception ) ;
362372}
0 commit comments