upgrade mcp

This commit is contained in:
Jicheng Lu 2025-04-15 00:25:03 -05:00
parent 71ea333eae
commit 8acdbb7ba4
9 changed files with 60 additions and 40 deletions

View file

@ -111,10 +111,10 @@
<PackageVersion Include="MSTest.TestAdapter" Version="3.1.1" /> <PackageVersion Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageVersion Include="MSTest.TestFramework" Version="3.1.1" /> <PackageVersion Include="MSTest.TestFramework" Version="3.1.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" /> <PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> <PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Shouldly" Version="4.3.0" /> <PackageVersion Include="Shouldly" Version="4.3.0" />
<PackageVersion Include="ModelContextProtocol" Version="0.1.0-preview.5" /> <PackageVersion Include="ModelContextProtocol" Version="0.1.0-preview.8" />
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="0.1.0-preview.5" /> <PackageVersion Include="ModelContextProtocol.AspNetCore" Version="0.1.0-preview.8" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageVersion Include="BotSharp.Core" Version="$(BotSharpVersion)" /> <PackageVersion Include="BotSharp.Core" Version="$(BotSharpVersion)" />

View file

@ -12,22 +12,21 @@ public class McpServerConfigModel
/// </summary> /// </summary>
public string Name { get; set; } = null!; public string Name { get; set; } = null!;
/// <summary> public McpSseServerConfig? SseConfig { get; set; }
/// The type of transport to use. public McpStdioServerConfig? StdioConfig { get; set; }
/// </summary>
[JsonPropertyName("transport_type")]
public string TransportType { get; set; } = null!;
/// <summary>
/// For stdio transport: path to the executable
/// For HTTP transport: base URL of the server
/// </summary>
public string? Location { get; set; }
/// <summary>
/// Additional transport-specific configuration.
/// </summary>
[JsonPropertyName("transport_options")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Dictionary<string, string>? TransportOptions { get; set; }
} }
public class McpSseServerConfig
{
public string EndPoint { get; set; } = null!;
public TimeSpan ConnectionTimeout { get; init; } = TimeSpan.FromSeconds(30);
public Dictionary<string, string>? AdditionalHeaders { get; set; }
}
public class McpStdioServerConfig
{
public string Command { get; set; } = null!;
public IList<string>? Arguments { get; set; }
public Dictionary<string, string>? EnvironmentVariables { get; set; }
public TimeSpan ShutdownTimeout { get; set; } = TimeSpan.FromSeconds(5);
}

View file

@ -4,7 +4,6 @@ using BotSharp.Core.MCP.Managers;
using BotSharp.Core.MCP.Services; using BotSharp.Core.MCP.Services;
using BotSharp.Core.MCP.Settings; using BotSharp.Core.MCP.Settings;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using ModelContextProtocol;
using ModelContextProtocol.Client; using ModelContextProtocol.Client;
namespace BotSharp.Core.MCP; namespace BotSharp.Core.MCP;
@ -21,7 +20,7 @@ public static class BotSharpMcpExtensions
{ {
services.AddScoped<IMcpService, McpService>(); services.AddScoped<IMcpService, McpService>();
var settings = config.GetSection("MCP").Get<McpSettings>(); var settings = config.GetSection("MCP").Get<McpSettings>();
services.AddScoped(provider => { return settings; }); services.AddScoped(provider => settings);
if (settings != null && settings.Enabled && !settings.McpServerConfigs.IsNullOrEmpty()) if (settings != null && settings.Enabled && !settings.McpServerConfigs.IsNullOrEmpty())
{ {
@ -42,14 +41,14 @@ public static class BotSharpMcpExtensions
return services; 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 client = await clientManager.GetMcpClientAsync(server.Id);
var tools = await client.ListToolsAsync(); var tools = await client.ListToolsAsync();
foreach (var tool in tools) foreach (var tool in tools)
{ {
services.AddScoped(provider => { return tool; }); services.AddScoped(provider => tool);
services.AddScoped<IFunctionCallback>(provider => services.AddScoped<IFunctionCallback>(provider =>
{ {

View file

@ -1,5 +1,6 @@
using BotSharp.Core.MCP.Settings; using BotSharp.Core.MCP.Settings;
using ModelContextProtocol.Client; using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Transport;
namespace BotSharp.Core.MCP.Managers; namespace BotSharp.Core.MCP.Managers;
@ -14,9 +15,33 @@ public class McpClientManager : IDisposable
public async Task<IMcpClient> GetMcpClientAsync(string serverId) public async Task<IMcpClient> GetMcpClientAsync(string serverId)
{ {
return await McpClientFactory.CreateAsync( var config = _mcpSettings.McpServerConfigs.Where(x => x.Id == serverId).FirstOrDefault();
_mcpSettings.McpServerConfigs.Where(x=> x.Name == serverId).First(),
_mcpSettings.McpClientOptions); 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() public void Dispose()

View file

@ -23,10 +23,7 @@ public class McpService : IMcpService
return configs.Select(x => new McpServerConfigModel return configs.Select(x => new McpServerConfigModel
{ {
Id = x.Id, Id = x.Id,
Name = x.Name, Name = x.Name
TransportType = x.TransportType,
TransportOptions = x.TransportOptions,
Location = x.Location
}); });
} }
} }

View file

@ -1,5 +1,4 @@
using ModelContextProtocol.Client; using ModelContextProtocol.Client;
using ModelContextProtocol;
namespace BotSharp.Core.MCP.Settings; namespace BotSharp.Core.MCP.Settings;
@ -7,6 +6,6 @@ public class McpSettings
{ {
public bool Enabled { get; set; } = true; public bool Enabled { get; set; } = true;
public McpClientOptions McpClientOptions { get; set; } public McpClientOptions McpClientOptions { get; set; }
public List<McpServerConfig> McpServerConfigs { get; set; } = new(); public List<McpServerConfigModel> McpServerConfigs { get; set; } = [];
} }

View file

@ -218,9 +218,9 @@
{ {
"Id": "PizzaServer", "Id": "PizzaServer",
"Name": "PizzaServer", "Name": "PizzaServer",
"TransportType": "sse", "SseConfig": {
"TransportOptions": [], "Endpoint": "http://localhost:58905/sse"
"Location": "http://localhost:58905/sse" }
} }
] ]
}, },

View file

@ -2,7 +2,7 @@
"profiles": { "profiles": {
"BotSharp.PizzaBot.MCPServer": { "BotSharp.PizzaBot.MCPServer": {
"commandName": "Project", "commandName": "Project",
"launchBrowser": true, "launchBrowser": false,
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
}, },

View file

@ -1,3 +1,4 @@
using ModelContextProtocol;
using ModelContextProtocol.Server; using ModelContextProtocol.Server;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
@ -14,11 +15,11 @@ public static class MakePayment
{ {
if (order_number is null) 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) 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!"; return "Payment proceed successfully. Thank you for your business. Have a great day!";
} }