diff --git a/McpStudy.McpClient/Program.cs b/McpStudy.McpClient/Program.cs index 73652c2..3ba0aa0 100644 --- a/McpStudy.McpClient/Program.cs +++ b/McpStudy.McpClient/Program.cs @@ -7,12 +7,15 @@ internal class Program await CallStdioAsync(); + //请务必在调用前,启动SseServer服务 + await RequestSseServerAsync(); + await Task.CompletedTask; } /// /// 使用Mcp客户端,直接调用Stdio类型的MCP服务 - /// + /// 真实项目或生产环境,请使用 `Microsoft.Extensions.AI`、`Microsoft.SemanticKernel`等AI库,进行调用; /// /// static async Task CallStdioAsync() @@ -54,6 +57,52 @@ internal class Program Console.WriteLine($"调用完成{System.Environment.NewLine}"); + Console.WriteLine("调用 Studio 类型的MCP服务结束!"); + } + + // + /// 使用Mcp客户端,直接调用SSE类型的MCP服务 + /// 真实项目或生产环境,请使用 `Microsoft.Extensions.AI`、`Microsoft.SemanticKernel`等AI库,进行调用; + /// + /// + static async Task RequestSseServerAsync() + { + Console.WriteLine($"开始调用 SSE类型的MCP服务......{System.Environment.NewLine}"); + + var sseClientTransportOptions = new SseClientTransportOptions() + { + Endpoint = new Uri("http://localhost:5027/sse"), + }; + var sseClientTransport = new SseClientTransport(sseClientTransportOptions); + + + Console.WriteLine("创建客户端......"); + IMcpClient client = await McpClientFactory.CreateAsync(sseClientTransport); + Console.WriteLine($"创建客户端完成{System.Environment.NewLine}"); + + Console.WriteLine("列举MCP服务中,可用的工具......"); + foreach (McpClientTool tool in await client.ListToolsAsync()) + { + Console.WriteLine($"工具名称:{tool.Name}, 工具描述:({tool.Description})"); + } + Console.WriteLine($"列举完成{System.Environment.NewLine}"); + + + Console.WriteLine("调用Echo工具......"); + CallToolResult result = await client.CallToolAsync + ( + toolName: "Echo", + arguments: new Dictionary() { ["message"] = "Hello MCP!" }, + cancellationToken: CancellationToken.None + ); + + Console.Write("Echo工具结果:"); + var content = result.Content.First(c => c.Type == "text") as TextContentBlock; + Console.WriteLine(content?.Text); + + Console.WriteLine($"调用完成{System.Environment.NewLine}"); + + Console.WriteLine("调用 Studio 类型的MCP服务结束!"); } } diff --git a/McpStudy.McpClient/说明.md b/McpStudy.McpClient/说明.md new file mode 100644 index 0000000..7156b2b --- /dev/null +++ b/McpStudy.McpClient/说明.md @@ -0,0 +1,19 @@ +客户端调用MCP服务 +============== +# 调用Stdio类型的MCP服务 + +## 调用本质:客户端在内部使用命令行(Windows下为cmd.exe),调用MCP服务控制台程序的可执行文件。 + +windows下,类似于 +```cmd +cmd.exe /c "D://目录/McpServer.exe" +``` +## 注意事项 +1. .NET 开发的Stio程序,客户端调用时:一种是,执行命令换成cmd,参数为 Studio类型的mcp服务程序可执行文件(带路径),另一种是,执行命令为 Dotnet,参数为 Dotnet的命令及参数(dotnet 路径/mcpServer.dll或者dotnet run --project xxx.csproj) +2. 调用服务后,很可能MCP服务进程没有自动退出,还驻留在系统进程中,造成后续调用失败;特别是在开发与调试阶段,这种情况更常见。调用失败时,一定要先检查MCP服务进程是否还在运行,如果还在运行,先结束进程。 +3. 可以使用`MCP C# SDK`中,提供的 `IMcpClient` 直接调用MCP服务相关功能(连接、列举工具、调用工具等); 方便开发与调试,但不建议在生产环境中使用; +4. 生产环境,使用 `Microsoft.Extensions.AI`、`Microsoft.SemanticKernel`等AI库,进行调用; + +# 调用SSE类型的MCP服务 +## 调用本质:客户端发送http请求,MCP服务程序响应内容;只不过服务端使用SSE,数据交换使用Json Patch格式。这一切源于MCP协议。 +## 注意事项: \ No newline at end of file diff --git a/McpStudy.McpServerStdio/说明.md b/McpStudy.McpServerStdio/说明.md new file mode 100644 index 0000000..0351773 --- /dev/null +++ b/McpStudy.McpServerStdio/说明.md @@ -0,0 +1,13 @@ +Stdio类型的MCP服务 +================ +## 调用本质:客户端在内部使用命令行(Windows下为cmd.exe),调用MCP服务控制台程序的可执行文件。 + +windows下,类似于 +```cmd +cmd.exe /c "D://目录/McpServer.exe" +``` +## 注意事项 +1. .NET 开发的Stio程序,客户端调用时:一种是,执行命令换成cmd,参数为 Studio类型的mcp服务程序可执行文件(带路径),另一种是,执行命令为 Dotnet,参数为 Dotnet的命令及参数(dotnet 路径/mcpServer.dll或者dotnet run --project xxx.csproj) +2. 调用服务后,很可能MCP服务进程没有自动退出,还驻留在系统进程中,造成后续调用失败;特别是在开发与调试阶段,这种情况更常见。调用失败时,一定要先检查MCP服务进程是否还在运行,如果还在运行,先结束进程。 +3. 可以使用`MCP C# SDK`中,提供的 `IMcpClient` 直接调用MCP服务相关功能(连接、列举工具、调用工具等); 方便开发与调试,但不建议在生产环境中使用; +4. 生产环境,使用 `Microsoft.Extensions.AI`、`Microsoft.SemanticKernel`等AI库,进行调用; \ No newline at end of file