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.TestFramework" Version="3.1.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="ModelContextProtocol" Version="0.1.0-preview.5" />
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="0.1.0-preview.5" />
<PackageVersion Include="ModelContextProtocol" Version="0.1.0-preview.8" />
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="0.1.0-preview.8" />
</ItemGroup>
<ItemGroup>
<PackageVersion Include="BotSharp.Core" Version="$(BotSharpVersion)" />

View file

@ -12,22 +12,21 @@ public class McpServerConfigModel
/// </summary>
public string Name { get; set; } = null!;
/// <summary>
/// The type of transport to use.
/// </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 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<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.Settings;
using Microsoft.Extensions.Configuration;
using ModelContextProtocol;
using ModelContextProtocol.Client;
namespace BotSharp.Core.MCP;
@ -21,7 +20,7 @@ public static class BotSharpMcpExtensions
{
services.AddScoped<IMcpService, McpService>();
var settings = config.GetSection("MCP").Get<McpSettings>();
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<IFunctionCallback>(provider =>
{

View file

@ -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<IMcpClient> 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()

View file

@ -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
});
}
}

View file

@ -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<McpServerConfig> McpServerConfigs { get; set; } = new();
public List<McpServerConfigModel> McpServerConfigs { get; set; } = [];
}

View file

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

View file

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

View file

@ -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!";
}