|
|
@@ -1,145 +1,145 @@
|
|
|
-////#r "nuget: ModelContextProtocol, *-*"
|
|
|
-////#r "nuget: Microsoft.Extensions.DependencyInjection"
|
|
|
-////#r "nuget: Microsoft.Extensions.Hosting"
|
|
|
-
|
|
|
-//using Microsoft.Extensions.DependencyInjection;
|
|
|
-//using Microsoft.Extensions.Hosting;
|
|
|
-//using Microsoft.Extensions.Logging;
|
|
|
-//using ModelContextProtocol;
|
|
|
-//using ModelContextProtocol.Client;
|
|
|
-//using ModelContextProtocol.Server;
|
|
|
-//using ModelContextProtocol.Protocol;
|
|
|
-//using System;
|
|
|
-//using System.Collections.Generic;
|
|
|
-//using System.Threading.Tasks;
|
|
|
-
|
|
|
-//using System.IO.Pipelines;
|
|
|
-//using System.Reflection;
|
|
|
-//using System.Threading.Channels;
|
|
|
-
|
|
|
-///// <summary>
|
|
|
-///// Model Context Protocol (MCP) 相关的帮助方法
|
|
|
-///// 统一管理 MCP 相关的 NuGet 包版本和常用功能
|
|
|
-///// </summary>
|
|
|
-//public static class McpHelper
|
|
|
-//{
|
|
|
-// /// <summary>
|
|
|
-// /// 使用反射从指定类型中提取所有 MCP 工具
|
|
|
-// /// </summary>
|
|
|
-// public static List<McpServerTool> GetToolsForType<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(
|
|
|
-// System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] T>()
|
|
|
-// {
|
|
|
-// var tools = new List<McpServerTool>();
|
|
|
-// var toolType = typeof(T);
|
|
|
-
|
|
|
-// // 获取所有标记了 McpServerToolAttribute 的公共静态方法
|
|
|
-// var methods = toolType.GetMethods(BindingFlags.Public | BindingFlags.Static)
|
|
|
-// .Where(m => m.GetCustomAttributes(typeof(McpServerToolAttribute), false).Any());
|
|
|
-
|
|
|
-// foreach (var method in methods)
|
|
|
-// {
|
|
|
-// try
|
|
|
-// {
|
|
|
-// var tool = McpServerTool.Create(method, target: null, new McpServerToolCreateOptions());
|
|
|
-// tools.Add(tool);
|
|
|
-// }
|
|
|
-// catch (Exception ex)
|
|
|
-// {
|
|
|
-// throw new InvalidOperationException($"添加工具失败 {toolType.Name}.{method.Name}: {ex.Message}", ex);
|
|
|
-// }
|
|
|
-// }
|
|
|
-
|
|
|
-// return tools;
|
|
|
-// }
|
|
|
-
|
|
|
-// /// <summary>
|
|
|
-// /// 创建并初始化 InMemory Transport 的 Server 和 Client
|
|
|
-// /// </summary>
|
|
|
-// /// <param name="tools">要注册的工具集合</param>
|
|
|
-// /// <param name="serverOptions">Server 配置选项(可选)</param>
|
|
|
-// /// <param name="loggerFactory">日志工厂(可选)</param>
|
|
|
-// /// <returns>返回已连接的 Client 和运行中的 Server</returns>
|
|
|
-// public static async Task<(McpClient Client, McpServer Server)> CreateInMemoryClientAndServerAsync(
|
|
|
-// List<McpServerTool> tools,
|
|
|
-// McpServerOptions? serverOptions = null,
|
|
|
-// McpClientOptions? clientOptions = null,
|
|
|
-// ILoggerFactory? loggerFactory = null)
|
|
|
-// {
|
|
|
-// // 步骤 1:创建两个 Pipe(双向管道)
|
|
|
-// Pipe clientToServerPipe = new();
|
|
|
-// Pipe serverToClientPipe = new();
|
|
|
-
|
|
|
-// // 步骤 2:创建 Server,使用 StreamServerTransport
|
|
|
-// var serverTransport = new StreamServerTransport(
|
|
|
-// clientToServerPipe.Reader.AsStream(),
|
|
|
-// serverToClientPipe.Writer.AsStream());
|
|
|
-
|
|
|
-// var toolCollection = new McpServerPrimitiveCollection<McpServerTool>();
|
|
|
-
|
|
|
-// tools.ForEach(toolCollection.Add);
|
|
|
-
|
|
|
-// var options = serverOptions ?? new McpServerOptions();
|
|
|
-// options.ToolCollection = toolCollection;
|
|
|
-
|
|
|
-// var server = McpServer.Create(serverTransport, options);
|
|
|
-
|
|
|
-// // 步骤 3:启动 Server(后台运行)
|
|
|
-// _ = server.RunAsync();
|
|
|
-
|
|
|
-// // 步骤 4:创建 Client,使用 StreamClientTransport
|
|
|
-// var client = await McpClient.CreateAsync(
|
|
|
-// new StreamClientTransport(
|
|
|
-// clientToServerPipe.Writer.AsStream(),
|
|
|
-// serverToClientPipe.Reader.AsStream()),
|
|
|
-// clientOptions: clientOptions,
|
|
|
-// loggerFactory: loggerFactory);
|
|
|
-
|
|
|
-// return (client, server);
|
|
|
-// }
|
|
|
-
|
|
|
-//}
|
|
|
-
|
|
|
-
|
|
|
-//public static class InMemoryMcpClientServerBuilder
|
|
|
-//{
|
|
|
-// private static readonly Pipe ClientToServerPipe = new();
|
|
|
-// private static readonly Pipe ServerToClientPipe = new();
|
|
|
-
|
|
|
-// public static IMcpServerBuilder CreateMcpServerBuilder(Action<McpServerOptions>? options = null)
|
|
|
-// {
|
|
|
-// ServiceCollection sc = new();
|
|
|
-// sc.AddLogging();
|
|
|
-// var builder = sc.AddMcpServer(options)
|
|
|
-// .WithStreamServerTransport(ClientToServerPipe.Reader.AsStream(), ServerToClientPipe.Writer.AsStream());
|
|
|
-
|
|
|
-// return builder;
|
|
|
-// }
|
|
|
-
|
|
|
-// public static Task StartMcpServer(IMcpServerBuilder mcpServerBuilder)
|
|
|
-// {
|
|
|
-// var serviceProvider = mcpServerBuilder.Services.BuildServiceProvider();
|
|
|
-
|
|
|
-// var server = serviceProvider.GetRequiredService<McpServer>();
|
|
|
-
|
|
|
-// return server.RunAsync();
|
|
|
-// }
|
|
|
-
|
|
|
-
|
|
|
-// public static async Task<McpClient> CreateMcpClientForServer(McpClientOptions? clientOptions = null)
|
|
|
-// {
|
|
|
-// var loggerFactory = LoggerFactory.Create(loggingBuilder =>
|
|
|
-// {
|
|
|
-// loggingBuilder.AddConsole();
|
|
|
-// });
|
|
|
-
|
|
|
-// return await McpClient.CreateAsync(
|
|
|
-// new StreamClientTransport(
|
|
|
-// serverInput: ClientToServerPipe.Writer.AsStream(),
|
|
|
-// ServerToClientPipe.Reader.AsStream(),
|
|
|
-// loggerFactory),
|
|
|
-// clientOptions: clientOptions,
|
|
|
-// loggerFactory: loggerFactory);
|
|
|
-// }
|
|
|
-//}
|
|
|
+//#r "nuget: ModelContextProtocol, *-*"
|
|
|
+//#r "nuget: Microsoft.Extensions.DependencyInjection"
|
|
|
+//#r "nuget: Microsoft.Extensions.Hosting"
|
|
|
+
|
|
|
+using Microsoft.Extensions.DependencyInjection;
|
|
|
+using Microsoft.Extensions.Hosting;
|
|
|
+using Microsoft.Extensions.Logging;
|
|
|
+using ModelContextProtocol;
|
|
|
+using ModelContextProtocol.Client;
|
|
|
+using ModelContextProtocol.Server;
|
|
|
+using ModelContextProtocol.Protocol;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Threading.Tasks;
|
|
|
+
|
|
|
+using System.IO.Pipelines;
|
|
|
+using System.Reflection;
|
|
|
+using System.Threading.Channels;
|
|
|
+
|
|
|
+/// <summary>
|
|
|
+/// Model Context Protocol (MCP) 相关的帮助方法
|
|
|
+/// 统一管理 MCP 相关的 NuGet 包版本和常用功能
|
|
|
+/// </summary>
|
|
|
+public static class McpHelper
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// 使用反射从指定类型中提取所有 MCP 工具
|
|
|
+ /// </summary>
|
|
|
+ public static List<McpServerTool> GetToolsForType<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(
|
|
|
+ System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] T>()
|
|
|
+ {
|
|
|
+ var tools = new List<McpServerTool>();
|
|
|
+ var toolType = typeof(T);
|
|
|
+
|
|
|
+ // 获取所有标记了 McpServerToolAttribute 的公共静态方法
|
|
|
+ var methods = toolType.GetMethods(BindingFlags.Public | BindingFlags.Static)
|
|
|
+ .Where(m => m.GetCustomAttributes(typeof(McpServerToolAttribute), false).Any());
|
|
|
+
|
|
|
+ foreach (var method in methods)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var tool = McpServerTool.Create(method, target: null, new McpServerToolCreateOptions());
|
|
|
+ tools.Add(tool);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ throw new InvalidOperationException($"添加工具失败 {toolType.Name}.{method.Name}: {ex.Message}", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return tools;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 创建并初始化 InMemory Transport 的 Server 和 Client
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="tools">要注册的工具集合</param>
|
|
|
+ /// <param name="serverOptions">Server 配置选项(可选)</param>
|
|
|
+ /// <param name="loggerFactory">日志工厂(可选)</param>
|
|
|
+ /// <returns>返回已连接的 Client 和运行中的 Server</returns>
|
|
|
+ public static async Task<(McpClient Client, McpServer Server)> CreateInMemoryClientAndServerAsync(
|
|
|
+ List<McpServerTool> tools,
|
|
|
+ McpServerOptions? serverOptions = null,
|
|
|
+ McpClientOptions? clientOptions = null,
|
|
|
+ ILoggerFactory? loggerFactory = null)
|
|
|
+ {
|
|
|
+ // 步骤 1:创建两个 Pipe(双向管道)
|
|
|
+ Pipe clientToServerPipe = new();
|
|
|
+ Pipe serverToClientPipe = new();
|
|
|
+
|
|
|
+ // 步骤 2:创建 Server,使用 StreamServerTransport
|
|
|
+ var serverTransport = new StreamServerTransport(
|
|
|
+ clientToServerPipe.Reader.AsStream(),
|
|
|
+ serverToClientPipe.Writer.AsStream());
|
|
|
+
|
|
|
+ var toolCollection = new McpServerPrimitiveCollection<McpServerTool>();
|
|
|
+
|
|
|
+ tools.ForEach(toolCollection.Add);
|
|
|
+
|
|
|
+ var options = serverOptions ?? new McpServerOptions();
|
|
|
+ options.ToolCollection = toolCollection;
|
|
|
+
|
|
|
+ var server = McpServer.Create(serverTransport, options);
|
|
|
+
|
|
|
+ // 步骤 3:启动 Server(后台运行)
|
|
|
+ _ = server.RunAsync();
|
|
|
+
|
|
|
+ // 步骤 4:创建 Client,使用 StreamClientTransport
|
|
|
+ var client = await McpClient.CreateAsync(
|
|
|
+ new StreamClientTransport(
|
|
|
+ clientToServerPipe.Writer.AsStream(),
|
|
|
+ serverToClientPipe.Reader.AsStream()),
|
|
|
+ clientOptions: clientOptions,
|
|
|
+ loggerFactory: loggerFactory);
|
|
|
+
|
|
|
+ return (client, server);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+public static class InMemoryMcpClientServerBuilder
|
|
|
+{
|
|
|
+ private static readonly Pipe ClientToServerPipe = new();
|
|
|
+ private static readonly Pipe ServerToClientPipe = new();
|
|
|
+
|
|
|
+ public static IMcpServerBuilder CreateMcpServerBuilder(Action<McpServerOptions>? options = null)
|
|
|
+ {
|
|
|
+ ServiceCollection sc = new();
|
|
|
+ sc.AddLogging();
|
|
|
+ var builder = sc.AddMcpServer(options)
|
|
|
+ .WithStreamServerTransport(ClientToServerPipe.Reader.AsStream(), ServerToClientPipe.Writer.AsStream());
|
|
|
+
|
|
|
+ return builder;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Task StartMcpServer(IMcpServerBuilder mcpServerBuilder)
|
|
|
+ {
|
|
|
+ var serviceProvider = mcpServerBuilder.Services.BuildServiceProvider();
|
|
|
+
|
|
|
+ var server = serviceProvider.GetRequiredService<McpServer>();
|
|
|
+
|
|
|
+ return server.RunAsync();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static async Task<McpClient> CreateMcpClientForServer(McpClientOptions? clientOptions = null)
|
|
|
+ {
|
|
|
+ var loggerFactory = LoggerFactory.Create(loggingBuilder =>
|
|
|
+ {
|
|
|
+ loggingBuilder.AddConsole();
|
|
|
+ });
|
|
|
+
|
|
|
+ return await McpClient.CreateAsync(
|
|
|
+ new StreamClientTransport(
|
|
|
+ serverInput: ClientToServerPipe.Writer.AsStream(),
|
|
|
+ ServerToClientPipe.Reader.AsStream(),
|
|
|
+ loggerFactory),
|
|
|
+ clientOptions: clientOptions,
|
|
|
+ loggerFactory: loggerFactory);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
|