diff --git a/samples/microsoft.extensions.ai/tools/ToolsConsole/MEAIToolsConsole.csproj b/samples/microsoft.extensions.ai/tools/ToolsConsole/MEAIToolsConsole.csproj index 39076cf..8a2b33e 100644 --- a/samples/microsoft.extensions.ai/tools/ToolsConsole/MEAIToolsConsole.csproj +++ b/samples/microsoft.extensions.ai/tools/ToolsConsole/MEAIToolsConsole.csproj @@ -8,11 +8,12 @@ - - + + + diff --git a/samples/microsoft.extensions.ai/tools/ToolsConsole/McpAIFunction.cs b/samples/microsoft.extensions.ai/tools/ToolsConsole/McpAIFunction.cs deleted file mode 100644 index 4cd2e23..0000000 --- a/samples/microsoft.extensions.ai/tools/ToolsConsole/McpAIFunction.cs +++ /dev/null @@ -1,79 +0,0 @@ -using McpDotNet.Client; -using McpDotNet.Protocol.Types; -using Microsoft.Extensions.AI; - -namespace SimpleToolsConsole; - -public class McpAIFunction : AIFunction -{ - private readonly Tool _tool; - private readonly IMcpClient _client; - private readonly AIFunctionMetadata _metadata; - - public McpAIFunction(Tool tool, IMcpClient client) - { - _tool = tool ?? throw new ArgumentNullException(nameof(tool)); - _client = client ?? throw new ArgumentNullException(nameof(client)); - _metadata = new AIFunctionMetadata(tool.Name) - { - Description = tool.Description, - Parameters = MapFunctionParameters(tool.InputSchema), - ReturnParameter = new AIFunctionReturnParameterMetadata() - { - ParameterType = typeof(string), - } - }; - } - - public override string ToString() => _tool.Name; - - protected async override Task InvokeCoreAsync(IEnumerable> arguments, CancellationToken cancellationToken) - { - if (arguments is null) - { - throw new ArgumentNullException(nameof(arguments)); - } - - // Convert arguments to dictionary format expected by mcpdotnet - Dictionary argDict = []; - foreach (var arg in arguments) - { - if (arg.Value is not null) - { - argDict[arg.Key] = arg.Value; - } - } - - // Call the tool through mcpdotnet - var result = await _client.CallToolAsync( - _tool.Name, - argDict.Count == 0 ? [] : argDict, - cancellationToken: cancellationToken - ); - - // Extract the text content from the result - // For simplicity in this sample, we'll just concatenate all text content - return string.Join("\n", result.Content - .Where(c => c.Type == "text") - .Select(c => c.Text)); - } - - public override AIFunctionMetadata Metadata => _metadata; - - private static List MapFunctionParameters(JsonSchema? jsonSchema) - { - var properties = jsonSchema?.Properties; - if (properties == null) - { - return []; - } - HashSet requiredProperties = [.. jsonSchema!.Required ?? []]; - return properties.Select(kvp => - new AIFunctionParameterMetadata(kvp.Key) - { - Description = kvp.Value.Description, - ParameterType = McpTypeMapper.MapJsonToDotNetType(kvp.Value.Type, requiredProperties.Contains(kvp.Key)), - IsRequired = requiredProperties.Contains(kvp.Key) - }).ToList(); - } -} diff --git a/samples/microsoft.extensions.ai/tools/ToolsConsole/McpToolExtensions.cs b/samples/microsoft.extensions.ai/tools/ToolsConsole/McpToolExtensions.cs deleted file mode 100644 index dc4d9f5..0000000 --- a/samples/microsoft.extensions.ai/tools/ToolsConsole/McpToolExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using McpDotNet.Client; -using McpDotNet.Protocol.Types; -using Microsoft.Extensions.AI; - -namespace SimpleToolsConsole; - -public static class McpToolExtensions -{ - public static AITool ToAITool(this Tool tool, IMcpClient client) - => new McpAIFunction(tool, client); -} \ No newline at end of file diff --git a/samples/microsoft.extensions.ai/tools/ToolsConsole/McpTypeMapper.cs b/samples/microsoft.extensions.ai/tools/ToolsConsole/McpTypeMapper.cs deleted file mode 100644 index f1784d5..0000000 --- a/samples/microsoft.extensions.ai/tools/ToolsConsole/McpTypeMapper.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Enable nullable reference types, as we need this for dynamic mapping of JSON schema to .NET types -#nullable enable - -namespace SimpleToolsConsole; - -public static class McpTypeMapper -{ - public static Type MapJsonToDotNetType(string jsonType, bool required) - { - // For simplicity, we don't handle complex types in this sample, but use object instead - var baseType = jsonType switch - { - "string" => typeof(string), - "integer" => typeof(int), - "number" => typeof(double), - "boolean" => typeof(bool), - "array" => typeof(IEnumerable), - "object" => typeof(IDictionary), - _ => typeof(object) - }; - - // If it's a value type and not required, make it nullable - if (!required && baseType.IsValueType) - { - return typeof(Nullable<>).MakeGenericType(baseType); - } - - // Reference types are already nullable when not required - return baseType; - } -} diff --git a/samples/microsoft.extensions.ai/tools/ToolsConsole/Program.cs b/samples/microsoft.extensions.ai/tools/ToolsConsole/Program.cs index d41ca75..e1e7388 100644 --- a/samples/microsoft.extensions.ai/tools/ToolsConsole/Program.cs +++ b/samples/microsoft.extensions.ai/tools/ToolsConsole/Program.cs @@ -1,10 +1,10 @@ using McpDotNet.Client; using McpDotNet.Configuration; +using McpDotNet.Extensions.AI; using McpDotNet.Protocol.Transport; using Microsoft.Extensions.AI; using Microsoft.Extensions.Logging.Abstractions; using OpenAI; -using SimpleToolsConsole; internal class Program { @@ -81,7 +81,7 @@ internal class Program // Call the chat client Console.WriteLine("Asking GPT-4o-mini to call the Echo Tool..."); - var response = chatClient.CompleteStreamingAsync( + var response = chatClient.GetStreamingResponseAsync( messages, new() { Tools = mappedTools }); diff --git a/src/McpDotNet.Extensions.AI/McpDotNet.Extensions.AI.csproj b/src/McpDotNet.Extensions.AI/McpDotNet.Extensions.AI.csproj index 16b545f..48f2a75 100644 --- a/src/McpDotNet.Extensions.AI/McpDotNet.Extensions.AI.csproj +++ b/src/McpDotNet.Extensions.AI/McpDotNet.Extensions.AI.csproj @@ -40,12 +40,12 @@ - - + + - + diff --git a/src/mcpdotnet/mcpdotnet.csproj b/src/mcpdotnet/mcpdotnet.csproj index d568905..e5f69e6 100644 --- a/src/mcpdotnet/mcpdotnet.csproj +++ b/src/mcpdotnet/mcpdotnet.csproj @@ -38,16 +38,16 @@ - - - + + + - - - + + + diff --git a/tests/McpDotNet.Extensions.AI.Tests/IntegrationTests.cs b/tests/McpDotNet.Extensions.AI.Tests/IntegrationTests.cs index 0d3c092..752f3dd 100644 --- a/tests/McpDotNet.Extensions.AI.Tests/IntegrationTests.cs +++ b/tests/McpDotNet.Extensions.AI.Tests/IntegrationTests.cs @@ -9,7 +9,7 @@ namespace McpDotNet.Extensions.AI.Tests; [Trait("Execution", "Manual")] public class IntegrationTests { - private const string OpenAIKey = ""; // Provide your own key when running the test. Do not commit it. + private string _openAIKey = Environment.GetEnvironmentVariable("Provide your own key when running the test. Do not commit it.")!; private static McpServerConfig GetEverythingServerConfig() { @@ -51,7 +51,7 @@ public class IntegrationTests var tools = await client.ListToolsAsync(); var mappedTools = tools.Tools.Select(t => t.ToAITool(client)).ToList(); - IChatClient openaiClient = new OpenAIClient(OpenAIKey) + IChatClient openaiClient = new OpenAIClient(_openAIKey) .AsChatClient("gpt-4o-mini"); IChatClient chatClient = new ChatClientBuilder(openaiClient) @@ -79,8 +79,7 @@ public class IntegrationTests new() { Tools = mappedTools, Temperature = 0 }); // Assert - Assert.Equal(4, messages.Count); // 1 system messages, 1 user message, 1 tool message, 1 response message - Assert.Equal("Echo: Hello MCP!", response.Message.Contents[0].ToString()); + Assert.Equal("Echo: Hello MCP!", response.Text); } [Fact] @@ -88,7 +87,7 @@ public class IntegrationTests { await using var sessionScope = await McpSessionScope.CreateAsync(GetEverythingServerConfig()); - IChatClient openaiClient = new OpenAIClient(OpenAIKey) + IChatClient openaiClient = new OpenAIClient(_openAIKey) .AsChatClient("gpt-4o-mini"); IChatClient chatClient = new ChatClientBuilder(openaiClient) @@ -116,7 +115,6 @@ public class IntegrationTests new() { Tools = sessionScope.Tools, Temperature = 0 }); // Assert - Assert.Equal(4, messages.Count); // 1 system messages, 1 user message, 1 tool message, 1 response message - Assert.Equal("Echo: Hello MCP!", response.Message.Contents[0].ToString()); + Assert.Equal("Echo: Hello MCP!", response.Text); } } diff --git a/tests/McpDotNet.Extensions.AI.Tests/McpDotNet.Extensions.AI.Tests.csproj b/tests/McpDotNet.Extensions.AI.Tests/McpDotNet.Extensions.AI.Tests.csproj index d28cd15..3e21b8e 100644 --- a/tests/McpDotNet.Extensions.AI.Tests/McpDotNet.Extensions.AI.Tests.csproj +++ b/tests/McpDotNet.Extensions.AI.Tests/McpDotNet.Extensions.AI.Tests.csproj @@ -28,7 +28,7 @@ - +