使用MCP C# SDK开发MCP Server + Client
<p>大家好,我是Edison。</p><p>近日被MCP刷屏了,刚好看到张队发了一篇文章提到MCP的官方C# SDK发布了预览版,于是手痒痒尝了一下鲜,写了一个DEMO分享给大家。</p>
<h1><strong>MCP是什么鬼?</strong></h1>
<p>MCP,全称是“<span>模型上下文协议”(Model Context Protocol),是Anthropic开源的一个标准协议。打个比方,它就像是AI世界的“USB-C”接口。你知道USB-C吧?一根线就能连接手机、电脑、充电器,超级方便。MCP的作用也差不多,它让AI模型(比如Anthropic的Claude)可以轻松地跟外部的数据源和工具连接起来,比如数据库、文件系统、API等等。</span>以前,如果想让AI访问你的数据库或者调用某个工具,得专门写一堆代码,特别麻烦。现在有了MCP,就像是插上USB-C线那么简单,AI模型通过这个标准协议就能直接获取数据或执行操作,不用每次都重新开发连接方式。这样,开发AI应用就变得更快、更省事了。</p>
<p><img src="https://img2024.cnblogs.com/blog/381412/202504/381412-20250402183435149-1506223674.png" alt="" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<h1><strong>MCP是如何工作的?</strong></h1>
<p>MCP是一个典型的C/S架构模式,即客户端 和 服务端,它们之间采用一种标准的消息格式(JSON-RPC)进行通信,大模型可以通过这些消息进行:</p>
<p>(1)获取数据:例如通过SQL从DB中查询订单数据;</p>
<p>(2)执行操作:例如通过API调用发个消息通知;</p>
<p>(3)理解指令:例如通过一些提示词模板,LLM可以知道如何使用数据和工具;</p>
<p><img src="https://img2024.cnblogs.com/blog/381412/202504/381412-20250402183456343-1757362096.png" alt="" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<p>简单来说,MCP就是AI的“万能接口”。有了它,AI模型就能像插上USB-C线一样,轻松连接到各种外部数据源和工具,变得更聪明、更实用。不管是开发者还是普通用户,都能通过MCP让AI干更多事,而且过程简单又安全。未来随着MCP的普及,我们可能会看到更多能干实事儿的AI应用冒出来!</p>
<h1><strong><span data-pm-slice="0 0 []">创建一个MCP Server</span></strong></h1>
<p>这里我们使用MCP C# SDK来实现,使用标准的IO传输方式。</p>
<p>(1)创建一个.NET 8.0控制台应用,假设命名为:EDT.McpServer.ConsoleHost</p>
<p>(2)安装MCP SDK</p>
<div class="cnblogs_code">
<pre>ModelContextProtocol <span style="color: rgba(128, 0, 128, 1)">0.1</span>.<span style="color: rgba(128, 0, 128, 1)">0</span>-preview.<span style="color: rgba(128, 0, 128, 1)">4</span></pre>
</div>
<p>(3)创建一个Tools目录,然后添加一个TimeTool.cs</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ModelContextProtocol.Server;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.ComponentModel;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> EDT.McpServer.Tools.ConsoleHost;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> TimeTool
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">string</span> GetCurrentTime(<span style="color: rgba(0, 0, 255, 1)">string</span> city) =><span style="color: rgba(0, 0, 0, 1)">
$</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">It is {DateTime.Now.Hour}:{DateTime.Now.Minute} in {city}.</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<p>这个TimeTool就是我们定义的基于MCP的Tool,可以看到基于SDK提供的Attribute,可以方便地将其指定为MCP Server Tools。</p>
<p>(3)修改Program.cs设置为启动MCP Server</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Microsoft.Extensions.Hosting;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Microsoft.Extensions.DependencyInjection;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> EDT.McpServer.Tools.ConsoleHost;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
{
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Starting MCP Server...</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> builder = Host.CreateEmptyApplicationBuilder(settings: <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
</span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> builder.Build().RunAsync();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception ex)
{
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Host terminated unexpectedly : {ex.Message}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<p>同样,也是很方便地就完成了MCP Server的创建,重点关注WithToolsFromAssembly这个扩展方法,它会扫描程序集中添加了McpServerTool标签的类进行注册。</p>
<p>这时我们已经完成了MCP Server的创建,可以把它启动起来了。</p>
<p>但是,要完成今天的目标,连接起来测试,我们还得实现一个Client来调用Server。</p>
<h1><span data-pm-slice="0 0 []">创建一个MCP Client</span></h1>
<p>(1)创建一个.NET 8.0控制台应用,假设命名为:EDT.McpServer.Client</p>
<p>(2)安装MCP SDK</p>
<div class="cnblogs_code">
<pre>ModelContextProtocol <span style="color: rgba(128, 0, 128, 1)">0.1</span>.<span style="color: rgba(128, 0, 128, 1)">0</span>-preview.<span style="color: rgba(128, 0, 128, 1)">4</span></pre>
</div>
<p>(3)修改Program.cs,实现以下步骤:</p>
<p><strong><span><span>创建MCP Client:</span></span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">await</span> <span style="color: rgba(0, 0, 255, 1)">using</span> <span style="color: rgba(0, 0, 255, 1)">var</span> mcpClient = <span style="color: rgba(0, 0, 255, 1)">await</span> McpClientFactory.CreateAsync(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">()
{
Id </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">time</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
Name </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Time MCP Server</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
TransportType </span>=<span style="color: rgba(0, 0, 0, 1)"> TransportTypes.StdIo,
TransportOptions </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">()
{
[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">command</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = <span style="color: rgba(128, 0, 0, 1)">@"</span><span style="color: rgba(128, 0, 0, 1)">..\..\..\..\EDT.McpServer\bin\Debug\net8.0\EDT.McpServer.exe</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
}
});</span></pre>
</div>
<p><span><span>需要注意的是:这里我们MCP Server使用的是标准IO传输方式,因此指定TransportType为StdIo,同时指定command为MCP Server应用程序所在的exe的目录位置。当然,这里的这种方式有点不是很规范,但你只需要了解它是需要访问MCP Server的程序地址就行了。</span></span></p>
<p><strong>列出可用的Tools:</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> tools = <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> mcpClient.ListToolsAsync();
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> tool <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> tools)
{
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{tool.Name} ({tool.Description})</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
}</span></pre>
</div>
<p><span><span><strong>直接执行Tool:</strong>(一般情况下不会这样用,而是在LLM中来调用)</span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> result = <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> mcpClient.CallToolAsync(
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">GetCurrentTime</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 0, 255, 1)">new</span> Dictionary<<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">object</span>?>() { [<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">city</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Chengdu</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> },
CancellationToken.None);
Console.WriteLine(result.Content.First(c </span>=> c.Type == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text</span><span style="color: rgba(128, 0, 0, 1)">"</span>).Text);</pre>
</div>
<p><strong>通过LLM来调用Tool:</strong><span><span>这里基于Microsoft.Extensions.AI核心库来实现的,你也可以用Semantic Kernel库来做这个事,都行!</span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> apiKeyCredential = <span style="color: rgba(0, 0, 255, 1)">new</span> ApiKeyCredential(config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LLM:ApiKey</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> aiClientOptions = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> OpenAIClientOptions();
aiClientOptions.Endpoint </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Uri(config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LLM:EndPoint</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> aiClient = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> OpenAIClient(apiKeyCredential, aiClientOptions)
.AsChatClient(config[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LLM:ModelId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> chatClient = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ChatClientBuilder(aiClient)
.UseFunctionInvocation()
.Build();
IList</span><ChatMessage> chatHistory =<span style="color: rgba(0, 0, 0, 1)">
[
</span><span style="color: rgba(0, 0, 255, 1)">new</span>(ChatRole.System, <span style="color: rgba(128, 0, 0, 1)">"""
</span> You are a helpful assistant delivering time <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> one sentence
</span><span style="color: rgba(0, 0, 255, 1)">in</span> a <span style="color: rgba(0, 0, 255, 1)">short</span> format, like <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">It is 10:08 in Paris, France.</span><span style="color: rgba(128, 0, 0, 1)">'</span>
<span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">),</span>
<span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Core Part: Get AI Tools from MCP Server</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> mcpTools = <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> mcpClient.ListToolsAsync();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> chatOptions = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ChatOptions()
{
Tools </span>=<span style="color: rgba(0, 0, 0, 1)"> [..mcpTools]
};
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Prompt the user for a question.</span>
Console.ForegroundColor =<span style="color: rgba(0, 0, 0, 1)"> ConsoleColor.Green;
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Assistant> How can I assist you today?</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Read the user question.</span>
Console.ForegroundColor =<span style="color: rgba(0, 0, 0, 1)"> ConsoleColor.White;
Console.Write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">User> </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> question =<span style="color: rgba(0, 0, 0, 1)"> Console.ReadLine();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Exit the application if the user didn't type anything.</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 255, 1)">string</span>.IsNullOrWhiteSpace(question) && question.ToUpper() == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">EXIT</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
chatHistory.Add(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ChatMessage(ChatRole.User, question));
Console.ForegroundColor </span>=<span style="color: rgba(0, 0, 0, 1)"> ConsoleColor.Green;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> response = <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> chatClient.GetResponseAsync(chatHistory, chatOptions);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> content =<span style="color: rgba(0, 0, 0, 1)"> response.ToString();
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Assistant> {content}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
chatHistory.Add(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ChatMessage(ChatRole.Assistant, content));
Console.WriteLine();
}</span></pre>
</div>
<p>最后的效果如下图所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/381412/202504/381412-20250402183942788-646118419.png" alt="" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<h1><span data-pm-slice="0 0 []">创建一个基于ASP.NET的MCP Server</span></h1>
<p>除了使用标准的IO协议,我们还可以实现一个基于ASP.NET Core的MCP SSE Server,顾名思义它就是使用SSE传输方式。</p>
<p>(1)创建一个.NET 8.0 ASP.NET WebAPI应用,假设命名为:EDT.McpServer.WebHost</p>
<p>(2)安装MCP SDK</p>
<div class="cnblogs_code">
<pre>ModelContextProtocol <span style="color: rgba(128, 0, 128, 1)">0.1</span>.<span style="color: rgba(128, 0, 128, 1)">0</span>-preview.<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">
ModelContextProtocol.AspNetCore </span><span style="color: rgba(128, 0, 128, 1)">0.1</span>.<span style="color: rgba(128, 0, 128, 1)">0</span>-preview.<span style="color: rgba(128, 0, 128, 1)">4</span></pre>
</div>
<p>(3)<span data-pm-slice="0 0 []">创建一个Tools目录,然后添加一个TimeTool.cs</span></p>
<p>这里和上面的一样,不再赘述。</p>
<p>(4)修改Program.cs完成MCP Server配置:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> EDT.McpServer.WebHost.Tools;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ModelContextProtocol.AspNetCore;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
{
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Starting MCP Server...</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> builder =<span style="color: rgba(0, 0, 0, 1)"> WebApplication.CreateBuilder(args);
builder.Services.AddMcpServer().WithToolsFromAssembly();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> builder.Build();
app.UseHttpsRedirection();
app.MapGet(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">"</span>, () => <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Hello MCP Server!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
app.MapMcp();
app.Run();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception ex)
{
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Host terminated unexpectedly : {ex.Message}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<p>可以看到,就是这么简单,通过MapMcp实现了/sse端点的映射。后续MCP Client要连接的就是这个/sse的端点。</p>
<p>(5)<span>这时,你就可以把这个ASP.NET WebAPI应用启动起来,假设我们这里是 <span>https://localhost:8443<span>,你就可以通过下面的一点点修改,让之前的这个MCP Client连接上这个MCP Server:</span></span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">await</span> <span style="color: rgba(0, 0, 255, 1)">using</span> <span style="color: rgba(0, 0, 255, 1)">var</span> mcpClient = <span style="color: rgba(0, 0, 255, 1)">await</span> McpClientFactory.CreateAsync(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">()
{
Id </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">time</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
Name </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Time MCP Server</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
TransportType </span>=<span style="color: rgba(0, 0, 0, 1)"> TransportTypes.Sse,
Location </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://localhost:8443/sse</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
});</span></pre>
</div>
<p><span data-pm-slice="0 0 []"><span><span>可以看到,仅仅修改TransportType为SSE,然后指定Server的BaseUrl即可。</span></span></span></p>
<p><span data-pm-slice="0 0 []"><span><span>OK,让我们再来运行一下Client看看能否再次成功调用Tool:</span></span></span></p>
<p><img src="https://img2024.cnblogs.com/blog/381412/202504/381412-20250402184939974-758201474.png" alt="" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<p><span data-pm-slice="0 0 []"><span><span>看来这次使用SSE传输方式也能调用成功了!Perfect!</span></span></span></p>
<h1><span data-pm-slice="0 0 []"><span><span><span><span>小结</span></span></span></span></span></h1>
<p><span data-pm-slice="0 0 []"><span><span>本文介绍了MCP的基本概念和工作模式,然后演示了如何通过MCP C# SDK创建MCP Server和Client,以及基于ASP.NET WebAPI创建SSE Server,相信会对你有所帮助。</span></span></span></p>
<p><span data-pm-slice="0 0 []"><span><span>如果你也是.NET程序员希望参与AI应用的开发,那就快快了解和使用基于Microsoft.Extensioins.AI + MCP C# SDK 的生态组件库吧。</span></span></span></p>
<h1><span><span><span><span><span>示例源码</span></span></span></span></span></h1>
<p><span><span>GitHub:点此查看<span><span><br></span></span></span></span></p>
<h1><span><span><strong>参考内容</strong></span></span></h1>
<p>MCP C# SDK Samples 《MCP C# Sample Demos》</p>
<h1><span><span>推荐内容</span></span></h1>
<p><span><span>Microsoft Learn</span></span></p>
<p><span><span>eShopSupport</span></span></p>
<p><span><span>devblogs</span></span></p>
<p> </p>
<p style="text-align: center"><img src="https://images.cnblogs.com/cnblogs_com/edisonchou/1647700/o_200902144330EdisonTalk-Footer.jpg" alt="" style="width: 65%; border: 1px solid rgba(221, 221, 221, 1); border-radius: 3px; box-shadow: 0 4px 8px rgba(3, 27, 78, 0.12)"></p>
<div id="Copyright">
<p>作者:周旭龙</p>
<p>出处:https://edisonchou.cnblogs.com</p>
<p>本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。</p>
</div>
</div>
<div id="MySignature" role="contentinfo">
<div align="center"><img border="0" src="http://service.t.sina.com.cn/widget/qmd/2068032061/d643d182/10.png"></div><br><br>
来源:https://www.cnblogs.com/edisontalk/p/-/introduction-to-mcp-csharp-sdk
頁:
[1]