From 7470953a8e278bf75a0370549232d834e7adcc6e Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Tue, 15 Apr 2025 11:28:37 -0500 Subject: [PATCH] refine mcp --- .../Functions/IFunctionCallback.cs | 1 + .../MCP/Models/McpServerOptionModel.cs | 19 ++++++++++++++++ .../MCP/Services/IMcpService.cs | 2 +- .../BotSharp.Abstraction/Models/IdName.cs | 5 +++++ .../BotSharpMCPExtensions.cs | 2 +- .../Functions/McpToolAdapter.cs | 9 +++++++- .../BotSharp.Core.MCP/Services/McpService.cs | 22 ++++++++++++++----- .../Controllers/McpController.cs | 2 +- .../Tools/PizzaPrices.cs | 5 +++-- .../Tools/PlaceOrder.cs | 7 +++--- 10 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/MCP/Models/McpServerOptionModel.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Functions/IFunctionCallback.cs b/src/Infrastructure/BotSharp.Abstraction/Functions/IFunctionCallback.cs index b842b5b6..2019a057 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Functions/IFunctionCallback.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Functions/IFunctionCallback.cs @@ -2,6 +2,7 @@ namespace BotSharp.Abstraction.Functions; public interface IFunctionCallback { + string Provider => "Botsharp"; string Name { get; } /// diff --git a/src/Infrastructure/BotSharp.Abstraction/MCP/Models/McpServerOptionModel.cs b/src/Infrastructure/BotSharp.Abstraction/MCP/Models/McpServerOptionModel.cs new file mode 100644 index 00000000..964203c9 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/MCP/Models/McpServerOptionModel.cs @@ -0,0 +1,19 @@ +namespace BotSharp.Abstraction.MCP.Models; + +public class McpServerOptionModel : IdName +{ + public IEnumerable Tools { get; set; } = []; + + public McpServerOptionModel() : base() + { + + } + + public McpServerOptionModel( + string id, + string name, + IEnumerable tools) : base(id, name) + { + Tools = tools ?? []; + } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/MCP/Services/IMcpService.cs b/src/Infrastructure/BotSharp.Abstraction/MCP/Services/IMcpService.cs index 7f054699..71952dac 100644 --- a/src/Infrastructure/BotSharp.Abstraction/MCP/Services/IMcpService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/MCP/Services/IMcpService.cs @@ -2,5 +2,5 @@ namespace BotSharp.Abstraction.MCP.Services; public interface IMcpService { - IEnumerable GetServerConfigs() => []; + IEnumerable GetServerConfigs() => []; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Models/IdName.cs b/src/Infrastructure/BotSharp.Abstraction/Models/IdName.cs index e5f7d8b5..107c7dd8 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Models/IdName.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Models/IdName.cs @@ -8,6 +8,11 @@ public class IdName [JsonPropertyName("name")] public string Name { get; set; } = default!; + public IdName() + { + + } + public IdName(string id, string name) { Id = id; diff --git a/src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs b/src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs index c5c61f05..38522fa9 100644 --- a/src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs +++ b/src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs @@ -52,7 +52,7 @@ public static class BotSharpMcpExtensions services.AddScoped(provider => { - var funcTool = new McpToolAdapter(provider, tool, clientManager); + var funcTool = new McpToolAdapter(provider, server.Name, tool, clientManager); return funcTool; }); } diff --git a/src/Infrastructure/BotSharp.Core.MCP/Functions/McpToolAdapter.cs b/src/Infrastructure/BotSharp.Core.MCP/Functions/McpToolAdapter.cs index 2d4fdc70..ad027219 100644 --- a/src/Infrastructure/BotSharp.Core.MCP/Functions/McpToolAdapter.cs +++ b/src/Infrastructure/BotSharp.Core.MCP/Functions/McpToolAdapter.cs @@ -6,17 +6,24 @@ namespace BotSharp.Core.MCP.Functions; public class McpToolAdapter : IFunctionCallback { + private readonly string _provider; private readonly McpClientTool _tool; private readonly McpClientManager _clientManager; private readonly IServiceProvider _services; - public McpToolAdapter(IServiceProvider services, McpClientTool tool, McpClientManager client) + public McpToolAdapter( + IServiceProvider services, + string serverName, + McpClientTool tool, + McpClientManager client) { _services = services ?? throw new ArgumentNullException(nameof(services)); _tool = tool ?? throw new ArgumentNullException(nameof(tool)); _clientManager = client ?? throw new ArgumentNullException(nameof(client)); + _provider = serverName; } + public string Provider => _provider; public string Name => _tool.Name; public async Task Execute(RoleDialogModel message) diff --git a/src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs b/src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs index df34b9d1..bbc2c3f4 100644 --- a/src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs +++ b/src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs @@ -16,14 +16,26 @@ public class McpService : IMcpService _logger = logger; } - public IEnumerable GetServerConfigs() + public IEnumerable GetServerConfigs() { + var options = new List(); var settings = _services.GetRequiredService(); var configs = settings?.McpServerConfigs ?? []; - return configs.Select(x => new McpServerConfigModel + + foreach (var config in configs) { - Id = x.Id, - Name = x.Name - }); + var tools = _services.GetServices() + .Where(x => x.Provider == config.Name) + .Select(x => x.Name); + + options.Add(new McpServerOptionModel + { + Id = config.Id, + Name = config.Name, + Tools = tools + }); + } + + return options; } } diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/McpController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/McpController.cs index 0524f0fb..7b74a37e 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/McpController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/McpController.cs @@ -13,7 +13,7 @@ public class McpController : ControllerBase } [HttpGet("/mcp/server-configs")] - public IEnumerable GetMcpServerConfigs() + public IEnumerable GetMcpServerConfigs() { var mcp = _services.GetRequiredService(); return mcp.GetServerConfigs(); diff --git a/tests/BotSharp.PizzaBot.MCPServer/Tools/PizzaPrices.cs b/tests/BotSharp.PizzaBot.MCPServer/Tools/PizzaPrices.cs index e8aa677c..326f217d 100644 --- a/tests/BotSharp.PizzaBot.MCPServer/Tools/PizzaPrices.cs +++ b/tests/BotSharp.PizzaBot.MCPServer/Tools/PizzaPrices.cs @@ -1,3 +1,4 @@ +using ModelContextProtocol; using ModelContextProtocol.Server; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -16,11 +17,11 @@ public static class PizzaPrices { if (pizza_type is null) { - throw new McpServerException("Missing required argument 'pizza_type'"); + throw new McpException("Missing required argument 'pizza_type'"); } if (quantity <= 0) { - throw new McpServerException("Missing required argument 'quantity'"); + throw new McpException("Missing required argument 'quantity'"); } double unit_price = 0; if (pizza_type.ToString() == "Pepperoni Pizza") diff --git a/tests/BotSharp.PizzaBot.MCPServer/Tools/PlaceOrder.cs b/tests/BotSharp.PizzaBot.MCPServer/Tools/PlaceOrder.cs index d6b82bd7..541c992c 100644 --- a/tests/BotSharp.PizzaBot.MCPServer/Tools/PlaceOrder.cs +++ b/tests/BotSharp.PizzaBot.MCPServer/Tools/PlaceOrder.cs @@ -1,3 +1,4 @@ +using ModelContextProtocol; using ModelContextProtocol.Server; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -15,15 +16,15 @@ public static class PlaceOrder { if (pizza_type is null) { - throw new McpServerException("Missing required argument 'pizza_type'"); + throw new McpException("Missing required argument 'pizza_type'"); } if (quantity <= 0) { - throw new McpServerException("Missing required argument 'quantity'"); + throw new McpException("Missing required argument 'quantity'"); } if (unit_price < 0) { - throw new McpServerException("Missing required argument 'unit_price'"); + throw new McpException("Missing required argument 'unit_price'"); } return "The order number is P123-01: {order_number = \"P123-01\" }";