From 8acdbb7ba4f8fd0a7e6cc3a2fdc7bc4983985479 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Tue, 15 Apr 2025 00:25:03 -0500 Subject: [PATCH] upgrade mcp --- Directory.Packages.props | 6 ++-- .../MCP/Models/McpServerConfigModel.cs | 35 +++++++++---------- .../BotSharpMCPExtensions.cs | 7 ++-- .../Managers/McpClientManager.cs | 31 ++++++++++++++-- .../BotSharp.Core.MCP/Services/McpService.cs | 5 +-- .../BotSharp.Core.MCP/Settings/MCPSettings.cs | 3 +- src/WebStarter/appsettings.json | 6 ++-- .../Properties/launchSettings.json | 2 +- .../Tools/MakePayment.cs | 5 +-- 9 files changed, 60 insertions(+), 40 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index b115ab6b..b179a20d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -111,10 +111,10 @@ - + - - + + diff --git a/src/Infrastructure/BotSharp.Abstraction/MCP/Models/McpServerConfigModel.cs b/src/Infrastructure/BotSharp.Abstraction/MCP/Models/McpServerConfigModel.cs index 2e0967b9..0a80bb89 100644 --- a/src/Infrastructure/BotSharp.Abstraction/MCP/Models/McpServerConfigModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/MCP/Models/McpServerConfigModel.cs @@ -12,22 +12,21 @@ public class McpServerConfigModel /// public string Name { get; set; } = null!; - /// - /// The type of transport to use. - /// - [JsonPropertyName("transport_type")] - public string TransportType { get; set; } = null!; - - /// - /// For stdio transport: path to the executable - /// For HTTP transport: base URL of the server - /// - public string? Location { get; set; } - - /// - /// Additional transport-specific configuration. - /// - [JsonPropertyName("transport_options")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public Dictionary? TransportOptions { get; set; } + public McpSseServerConfig? SseConfig { get; set; } + public McpStdioServerConfig? StdioConfig { get; set; } } + +public class McpSseServerConfig +{ + public string EndPoint { get; set; } = null!; + public TimeSpan ConnectionTimeout { get; init; } = TimeSpan.FromSeconds(30); + public Dictionary? AdditionalHeaders { get; set; } +} + +public class McpStdioServerConfig +{ + public string Command { get; set; } = null!; + public IList? Arguments { get; set; } + public Dictionary? EnvironmentVariables { get; set; } + public TimeSpan ShutdownTimeout { get; set; } = TimeSpan.FromSeconds(5); +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs b/src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs index ee065459..c5c61f05 100644 --- a/src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs +++ b/src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs @@ -4,7 +4,6 @@ using BotSharp.Core.MCP.Managers; using BotSharp.Core.MCP.Services; using BotSharp.Core.MCP.Settings; using Microsoft.Extensions.Configuration; -using ModelContextProtocol; using ModelContextProtocol.Client; namespace BotSharp.Core.MCP; @@ -21,7 +20,7 @@ public static class BotSharpMcpExtensions { services.AddScoped(); var settings = config.GetSection("MCP").Get(); - services.AddScoped(provider => { return settings; }); + services.AddScoped(provider => settings); if (settings != null && settings.Enabled && !settings.McpServerConfigs.IsNullOrEmpty()) { @@ -42,14 +41,14 @@ public static class BotSharpMcpExtensions return services; } - private static async Task RegisterFunctionCall(IServiceCollection services, McpServerConfig server, McpClientManager clientManager) + private static async Task RegisterFunctionCall(IServiceCollection services, McpServerConfigModel server, McpClientManager clientManager) { var client = await clientManager.GetMcpClientAsync(server.Id); var tools = await client.ListToolsAsync(); foreach (var tool in tools) { - services.AddScoped(provider => { return tool; }); + services.AddScoped(provider => tool); services.AddScoped(provider => { diff --git a/src/Infrastructure/BotSharp.Core.MCP/Managers/McpClientManager.cs b/src/Infrastructure/BotSharp.Core.MCP/Managers/McpClientManager.cs index c11163b3..a5441e66 100644 --- a/src/Infrastructure/BotSharp.Core.MCP/Managers/McpClientManager.cs +++ b/src/Infrastructure/BotSharp.Core.MCP/Managers/McpClientManager.cs @@ -1,5 +1,6 @@ using BotSharp.Core.MCP.Settings; using ModelContextProtocol.Client; +using ModelContextProtocol.Protocol.Transport; namespace BotSharp.Core.MCP.Managers; @@ -14,9 +15,33 @@ public class McpClientManager : IDisposable public async Task GetMcpClientAsync(string serverId) { - return await McpClientFactory.CreateAsync( - _mcpSettings.McpServerConfigs.Where(x=> x.Name == serverId).First(), - _mcpSettings.McpClientOptions); + var config = _mcpSettings.McpServerConfigs.Where(x => x.Id == serverId).FirstOrDefault(); + + IClientTransport transport; + if (config.SseConfig != null) + { + transport = new SseClientTransport(new SseClientTransportOptions + { + Name = config.Name, + Endpoint = new Uri(config.SseConfig.EndPoint) + }); + } + else if (config.StdioConfig != null) + { + transport = new StdioClientTransport(new StdioClientTransportOptions + { + Name = config.Name, + Command = config.StdioConfig.Command, + Arguments = config.StdioConfig.Arguments, + EnvironmentVariables = config.StdioConfig.EnvironmentVariables + }); + } + else + { + throw new ArgumentNullException("Invalid MCP server configuration!"); + } + + return await McpClientFactory.CreateAsync(transport, _mcpSettings.McpClientOptions); } public void Dispose() diff --git a/src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs b/src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs index 786f0857..df34b9d1 100644 --- a/src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs +++ b/src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs @@ -23,10 +23,7 @@ public class McpService : IMcpService return configs.Select(x => new McpServerConfigModel { Id = x.Id, - Name = x.Name, - TransportType = x.TransportType, - TransportOptions = x.TransportOptions, - Location = x.Location + Name = x.Name }); } } diff --git a/src/Infrastructure/BotSharp.Core.MCP/Settings/MCPSettings.cs b/src/Infrastructure/BotSharp.Core.MCP/Settings/MCPSettings.cs index cd4bfd0f..2867712f 100644 --- a/src/Infrastructure/BotSharp.Core.MCP/Settings/MCPSettings.cs +++ b/src/Infrastructure/BotSharp.Core.MCP/Settings/MCPSettings.cs @@ -1,5 +1,4 @@ using ModelContextProtocol.Client; -using ModelContextProtocol; namespace BotSharp.Core.MCP.Settings; @@ -7,6 +6,6 @@ public class McpSettings { public bool Enabled { get; set; } = true; public McpClientOptions McpClientOptions { get; set; } - public List McpServerConfigs { get; set; } = new(); + public List McpServerConfigs { get; set; } = []; } diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index 69625129..7ab6f7fd 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -218,9 +218,9 @@ { "Id": "PizzaServer", "Name": "PizzaServer", - "TransportType": "sse", - "TransportOptions": [], - "Location": "http://localhost:58905/sse" + "SseConfig": { + "Endpoint": "http://localhost:58905/sse" + } } ] }, diff --git a/tests/BotSharp.PizzaBot.MCPServer/Properties/launchSettings.json b/tests/BotSharp.PizzaBot.MCPServer/Properties/launchSettings.json index 617e672c..3333cfcd 100644 --- a/tests/BotSharp.PizzaBot.MCPServer/Properties/launchSettings.json +++ b/tests/BotSharp.PizzaBot.MCPServer/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "BotSharp.PizzaBot.MCPServer": { "commandName": "Project", - "launchBrowser": true, + "launchBrowser": false, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, diff --git a/tests/BotSharp.PizzaBot.MCPServer/Tools/MakePayment.cs b/tests/BotSharp.PizzaBot.MCPServer/Tools/MakePayment.cs index 5016f5bb..5937a489 100644 --- a/tests/BotSharp.PizzaBot.MCPServer/Tools/MakePayment.cs +++ b/tests/BotSharp.PizzaBot.MCPServer/Tools/MakePayment.cs @@ -1,3 +1,4 @@ +using ModelContextProtocol; using ModelContextProtocol.Server; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -14,11 +15,11 @@ public static class MakePayment { if (order_number is null) { - throw new McpServerException("Missing required argument 'order_number'"); + throw new McpException("Missing required argument 'order_number'"); } if (order_number is null) { - throw new McpServerException("Missing required argument 'total_amount'"); + throw new McpException("Missing required argument 'total_amount'"); } return "Payment proceed successfully. Thank you for your business. Have a great day!"; }