找回密码
 立即注册
首页 业界区 业界 使用MCP C# SDK开发MCP Server + Client

使用MCP C# SDK开发MCP Server + Client

栓州 2025-6-4 22:52:36
大家好,我是Edison。
近日被MCP刷屏了,刚好看到张队发了一篇文章提到MCP的官方C# SDK发布了预览版,于是手痒痒尝了一下鲜,写了一个DEMO分享给大家。
MCP是什么鬼?

MCP,全称是“模型上下文协议”(Model Context Protocol),是Anthropic开源的一个标准协议。打个比方,它就像是AI世界的“USB-C”接口。你知道USB-C吧?一根线就能连接手机、电脑、充电器,超级方便。MCP的作用也差不多,它让AI模型(比如Anthropic的Claude)可以轻松地跟外部的数据源和工具连接起来,比如数据库、文件系统、API等等。以前,如果想让AI访问你的数据库或者调用某个工具,得专门写一堆代码,特别麻烦。现在有了MCP,就像是插上USB-C线那么简单,AI模型通过这个标准协议就能直接获取数据或执行操作,不用每次都重新开发连接方式。这样,开发AI应用就变得更快、更省事了。
1.png

MCP是如何工作的?

MCP是一个典型的C/S架构模式,即客户端 和 服务端,它们之间采用一种标准的消息格式(JSON-RPC)进行通信,大模型可以通过这些消息进行:
(1)获取数据:例如通过SQL从DB中查询订单数据;
(2)执行操作:例如通过API调用发个消息通知;
(3)理解指令:例如通过一些提示词模板,LLM可以知道如何使用数据和工具;
2.png

简单来说,MCP就是AI的“万能接口”。有了它,AI模型就能像插上USB-C线一样,轻松连接到各种外部数据源和工具,变得更聪明、更实用。不管是开发者还是普通用户,都能通过MCP让AI干更多事,而且过程简单又安全。未来随着MCP的普及,我们可能会看到更多能干实事儿的AI应用冒出来!
创建一个MCP Server

这里我们使用MCP C# SDK来实现,使用标准的IO传输方式。
(1)创建一个.NET 8.0控制台应用,假设命名为:EDT.McpServer.ConsoleHost
(2)安装MCP SDK
  1. ModelContextProtocol 0.1.0-preview.4
复制代码
(3)创建一个Tools目录,然后添加一个TimeTool.cs
  1. using ModelContextProtocol.Server;
  2. using System.ComponentModel;
  3. namespace EDT.McpServer.Tools.ConsoleHost;
  4. [McpServerToolType]
  5. public static class TimeTool
  6. {
  7.     [McpServerTool, Description("Get the current time for a city")]
  8.     public static string GetCurrentTime(string city) =>
  9.         $"It is {DateTime.Now.Hour}:{DateTime.Now.Minute} in {city}.";
  10. }
复制代码
这个TimeTool就是我们定义的基于MCP的Tool,可以看到基于SDK提供的Attribute,可以方便地将其指定为MCP Server Tools。
(3)修改Program.cs设置为启动MCP Server
  1. using Microsoft.Extensions.Hosting;
  2. using Microsoft.Extensions.DependencyInjection;
  3. using EDT.McpServer.Tools.ConsoleHost;
  4. try
  5. {
  6.     Console.WriteLine("Starting MCP Server...");
  7.     var builder = Host.CreateEmptyApplicationBuilder(settings: null);
  8.     builder.Services
  9.         .AddMcpServer()
  10.         .WithStdioServerTransport()
  11.         .WithToolsFromAssembly();
  12.     await builder.Build().RunAsync();
  13.     return 0;
  14. }
  15. catch (Exception ex)
  16. {
  17.     Console.WriteLine($"Host terminated unexpectedly : {ex.Message}");
  18.     return 1;
  19. }
复制代码
同样,也是很方便地就完成了MCP Server的创建,重点关注WithToolsFromAssembly这个扩展方法,它会扫描程序集中添加了McpServerTool标签的类进行注册。
这时我们已经完成了MCP Server的创建,可以把它启动起来了。
但是,要完成今天的目标,连接起来测试,我们还得实现一个Client来调用Server。
创建一个MCP Client

(1)创建一个.NET 8.0控制台应用,假设命名为:EDT.McpServer.Client
(2)安装MCP SDK
  1. ModelContextProtocol 0.1.0-preview.4
复制代码
(3)修改Program.cs,实现以下步骤:
创建MCP Client:
  1. await using var mcpClient = await McpClientFactory.CreateAsync(new()
  2. {
  3.     Id = "time",
  4.     Name = "Time MCP Server",
  5.     TransportType = TransportTypes.StdIo,
  6.     TransportOptions = new()
  7.     {
  8.         ["command"] = @"..\..\..\..\EDT.McpServer\bin\Debug\net8.0\EDT.McpServer.exe"
  9.     }
  10. });
复制代码
需要注意的是:这里我们MCP Server使用的是标准IO传输方式,因此指定TransportType为StdIo,同时指定command为MCP Server应用程序所在的exe的目录位置。当然,这里的这种方式有点不是很规范,但你只需要了解它是需要访问MCP Server的程序地址就行了。
列出可用的Tools:
  1. var tools = await mcpClient.ListToolsAsync();
  2. foreach (var tool in tools)
  3. {
  4.     Console.WriteLine($"{tool.Name} ({tool.Description})");
  5. }
复制代码
直接执行Tool:(一般情况下不会这样用,而是在LLM中来调用)
  1. var result = await mcpClient.CallToolAsync(
  2.     "GetCurrentTime",
  3.     new Dictionary<string, object?>() { ["city"] = "Chengdu" },
  4.     CancellationToken.None);
  5. Console.WriteLine(result.Content.First(c => c.Type == "text").Text);
复制代码
通过LLM来调用Tool:这里基于Microsoft.Extensions.AI核心库来实现的,你也可以用Semantic Kernel库来做这个事,都行!
  1. var apiKeyCredential = new ApiKeyCredential(config["LLM:ApiKey"]);
  2. var aiClientOptions = new OpenAIClientOptions();
  3. aiClientOptions.Endpoint = new Uri(config["LLM:EndPoint"]);
  4. var aiClient = new OpenAIClient(apiKeyCredential, aiClientOptions)
  5.     .AsChatClient(config["LLM:ModelId"]);
  6. var chatClient = new ChatClientBuilder(aiClient)
  7.     .UseFunctionInvocation()
  8.     .Build();
  9. IList<ChatMessage> chatHistory =
  10. [
  11.     new(ChatRole.System, """
  12.        You are a helpful assistant delivering time in one sentence
  13.        in a short format, like 'It is 10:08 in Paris, France.'
  14.        """),
  15. ];
  16. // Core Part: Get AI Tools from MCP Server
  17. var mcpTools = await mcpClient.ListToolsAsync();
  18. var chatOptions = new ChatOptions()
  19. {
  20.     Tools = [..mcpTools]
  21. };
  22. // Prompt the user for a question.
  23. Console.ForegroundColor = ConsoleColor.Green;
  24. Console.WriteLine($"Assistant> How can I assist you today?");
  25. while (true)
  26. {
  27.     // Read the user question.
  28.     Console.ForegroundColor = ConsoleColor.White;
  29.     Console.Write("User> ");
  30.     var question = Console.ReadLine();
  31.     // Exit the application if the user didn't type anything.
  32.     if (!string.IsNullOrWhiteSpace(question) && question.ToUpper() == "EXIT")
  33.         break;
  34.     chatHistory.Add(new ChatMessage(ChatRole.User, question));
  35.     Console.ForegroundColor = ConsoleColor.Green;
  36.     var response = await chatClient.GetResponseAsync(chatHistory, chatOptions);
  37.     var content = response.ToString();
  38.     Console.WriteLine($"Assistant> {content}");
  39.     chatHistory.Add(new ChatMessage(ChatRole.Assistant, content));
  40.     Console.WriteLine();
  41. }
复制代码
最后的效果如下图所示:
3.png

创建一个基于ASP.NET的MCP Server

除了使用标准的IO协议,我们还可以实现一个基于ASP.NET Core的MCP SSE Server,顾名思义它就是使用SSE传输方式。
(1)创建一个.NET 8.0 ASP.NET WebAPI应用,假设命名为:EDT.McpServer.WebHost
(2)安装MCP SDK
  1. ModelContextProtocol 0.1.0-preview.4
  2. ModelContextProtocol.AspNetCore 0.1.0-preview.4
复制代码
(3)创建一个Tools目录,然后添加一个TimeTool.cs
这里和上面的一样,不再赘述。
(4)修改Program.cs完成MCP Server配置:
  1. using EDT.McpServer.WebHost.Tools;
  2. using ModelContextProtocol.AspNetCore;
  3. try
  4. {
  5.     Console.WriteLine("Starting MCP Server...");
  6.     var builder = WebApplication.CreateBuilder(args);
  7.     builder.Services.AddMcpServer().WithToolsFromAssembly();
  8.     var app = builder.Build();
  9.     app.UseHttpsRedirection();
  10.     app.MapGet("/", () => "Hello MCP Server!");
  11.     app.MapMcp();
  12.     app.Run();
  13.     return 0;
  14. }
  15. catch (Exception ex)
  16. {
  17.     Console.WriteLine($"Host terminated unexpectedly : {ex.Message}");
  18.     return 1;
  19. }
复制代码
可以看到,就是这么简单,通过MapMcp实现了/sse端点的映射。后续MCP Client要连接的就是这个/sse的端点。
(5)这时,你就可以把这个ASP.NET WebAPI应用启动起来,假设我们这里是 https://localhost:8443,你就可以通过下面的一点点修改,让之前的这个MCP Client连接上这个MCP Server:
  1. await using var mcpClient = await McpClientFactory.CreateAsync(new()
  2. {
  3.     Id = "time",
  4.     Name = "Time MCP Server",
  5.     TransportType = TransportTypes.Sse,
  6.     Location = "https://localhost:8443/sse"
  7. });
复制代码
可以看到,仅仅修改TransportType为SSE,然后指定Server的BaseUrl即可。
OK,让我们再来运行一下Client看看能否再次成功调用Tool:
4.png

看来这次使用SSE传输方式也能调用成功了!Perfect!
小结

本文介绍了MCP的基本概念和工作模式,然后演示了如何通过MCP C# SDK创建MCP Server和Client,以及基于ASP.NET WebAPI创建SSE Server,相信会对你有所帮助。
如果你也是.NET程序员希望参与AI应用的开发,那就快快了解和使用基于Microsoft.Extensioins.AI + MCP C# SDK 的生态组件库吧。
示例源码

GitHub:点此查看

参考内容

MCP C# SDK Samples 《MCP C# Sample Demos》
推荐内容

Microsoft Learn
eShopSupport
devblogs
 
5.jpeg

作者:周旭龙
出处:https://edisonchou.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册