C# 从零开发 MCP Client 基础教程(一)
C# 从零开发 MCP 工具基础教程
1. 前期准备
1.1 MCP (Model Context Protocol) 是什么?
MCP 简介
MCP (Model Context Protocol) 是一个开放协议,用于标准化应用程序如何向大语言模型 (LLM) 提供上下文信息。可以将 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 为设备连接各种外设和配件提供标准化方式一样,MCP 为 AI 模型连接不同的数据源和工具提供了标准化的方式。
简单来说,大语言模型就像是我们的大脑,但仅有“大脑”并不足以完成所有任务。过去,我们通常通过人工与 AI 模型的对话,手动指令 AI 完成任务,模型输出结果后,我们还需自行分析整理。这无疑大大增加了我们的时间成本。而现在,借助 MCP 工具,模型就像是有了“手脚”,能够根据我们的命令调用不同的工具去执行任务,而 MCP 协议就是模型和这些工具之间的桥梁。
为什么模型能调用不同的工具呢?这得益于大模型已支持 Function Call(函数调用)功能。简单来说,Function Call 允许模型解析用户请求,并生成调用外部函数所需的参数,从而实现更复杂的任务处理。
Function Call 原理
- 语义理解:模型解析用户输入,判定是否需要调用函数。
- 函数匹配:从预定义的工具库中选择合适的工具(例如查询天气、数学计算等)。
- 参数生成:将用户描述转换为函数所需的参数格式(如
Fetch {Url:{地址}})。 - 执行与整合:调用外部工具获取结果,并生成自然语言答复。**
1.2 MCP 能够干什么
- 实时数据获取:例如查询天气、股票等动态信息(大模型自身知识库为静态的)。
- 自然语言执行 SQL:通过连接数据库查询本地数据并进行数据分析。
- 私域知识扩展:通过本地知识库、知识图谱等私有数据源解决特定领域问题。
2. 如何使用 C# 接入 MCP Tools?
2.1 准备工作
首先,我们需要选择要使用的 AI 模型。这里我们使用的是硅基流动的 Qwen/QwQ-32B 模型。如果你没有硅基流动账号,可以注册一个国内账号,默认官方会赠送 2000 万 Tokens 的额度。注册完成后,你可以选择你需要的模型(例如 Qwen/QwQ-32B)。请确保所选模型支持 Function Call。大家可以使用我的邀请链接硅基流动官网 进行注册,注册完成之后我们就可以进入到硅基流动的主页面,我们可以在模型广场中选择我们将要用到的模型,我选用的是 Qwen/QwQ-32B,如下图,选用的模型需要具备FunctionCall 函数调用的能力

2.2 创建控制台项目
在 Visual Studio 2022 中,创建一个控制台应用项目(例如 MCPClient)。然后,安装所需的 NuGet 包:

dotnet add package ModelContextProtocol --prerelease
接下来我们可以用Github 上面的案例代码测试一下Mcp Client 工具的调用:
//创建MCp Client 连接到对应的MCp Server 工具
#region 适用于 0.1.0-preview.4 版本
var client = await McpClientFactory.CreateAsync(new()
{
Id = "everything",
Name = "Everything",
TransportType = TransportTypes.StdIo,
TransportOptions = new()
{
["command"] = "npx",
["arguments"] = "-y @modelcontextprotocol/server-everything",
}
});
#endregion
#region 适用于 0.1.0-preview.9 版本
var clientTransport = new StdioClientTransport(
new StdioClientTransportOptions
{
Name = "Everything",
Command = "npx",
Arguments = ["-y", "@modelcontextprotocol/server-everything"],
}
);
var client = await McpClientFactory.CreateAsync(clientTransport);
#endregion
//打印 MCP 服务器上可用的工具列表
foreach (var tool in await client.ListToolsAsync())
{
Console.WriteLine($"{tool.Name} ({tool.Description})");
}
// 执行一个工具,这里执行 的是 刚才打印可以使用 的 echo 函数,他的主要作用是调用它,他会返回你调用的message
var result = await client.CallToolAsync(
"echo",
new Dictionary<string, object?>() { ["message"] = "Hello MCP!" },
CancellationToken.None);
// echo always returns one and only one text content object
Console.WriteLine(result.Content.First(c => c.Type == "text").Text);
执行结果如下:
2.3 进行工具调用
在测试了基本的 MCP Client 调用后,接下来我们可以实现一个实际的功能:通过 MCP Client 获取任意网页的信息并让 AI 模型进行总结。你可以通过访问 官方服务器工具列表 寻找合适的工具。比如,Fetch 工具可以用来提取网页内容并将其转换为 Markdown 格式。
我们可以点击进入到 官方服务器工具列表中查询我们想要调用的工具,这里我们使用的是Fetch 工具,进入链接我们可以查询对应工具的详细说明


接下来我们可以看一下他的配置,它这里推荐的是通过uvx 调用,所以我也打算采用这和个方式模拟,大家也可以使用python 自行安装运行 进行调用,uvx 需要安装uvx 环境,如果不会安装可以参考https://docs.cherry-ai.com/advanced-basic/mcp文档 并下载对应的 uvx 包 ,这里因为我本身电脑已经安装了Cherry Studio ,已经配置好了 对应的环境,就不做演示了,我的uvx 路径是: C:\Users{用户名}.cherrystudio\bin,先记住这个路径,等会要用
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
}
}
开始编写MCP Client 代码
因为要使用刚刚我们不准备的模型并连接到 fetch 工具执行我们想要检索的网页
我们需要安装一些方便我们接入大模型的nuget 包
dotnet add package Microsoft.Extensions.AI --prerelease
dotnet add package Microsoft.Extensions.AI.Abstractions --prerelease
dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease
安装完成后,我们开始编写我们的代码
using Microsoft.Extensions.AI;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Transport;
using OpenAI;
using System.ClientModel;
//创建McpClient 客户端
#region 适用于 0.1.0-preview.4 版本
var client = await McpClientFactory.CreateAsync(new()
{
Id = "fetch",
Name = "Fetch",
TransportType = TransportTypes.StdIo,
TransportOptions = new()
{
["command"] = @"C:\Users\你的用户名\.cherrystudio\bin\uvx.exe",
["arguments"] = "mcp-server-fetch",
}
});
#endregion
#region 适用于 0.1.0-preview.9 版本
var clientTransport = new StdioClientTransport(
new StdioClientTransportOptions
{
Name = "Fetch",
Command = @"C:\Users\liufx\.cherrystudio\bin\uvx.exe",
Arguments = ["mcp-server-fetch"],
}
);
var client = await McpClientFactory.CreateAsync(clientTransport);
#endregion
var tools = await client.ListToolsAsync();
//打印服务器上可用的工具列表
foreach (var tool in tools)
{
Console.WriteLine($"{tool.Name} ({tool.Description})");
}
//创建密钥
var apiKeyCredential = new ApiKeyCredential("你的密钥");
//配置OpenAPI 客户端 选项配置
var aiClientOptions = new OpenAIClientOptions();
aiClientOptions.Endpoint = new Uri("https://api.siliconflow.cn");
#region 适用于 9.3.0-preview.1.25161.3
var aiClient = new OpenAIClient(apiKeyCredential, aiClientOptions)
.AsChatClient("Qwen/QwQ-32B");
//创建ChatClient 客户端
var chatClient = new ChatClientBuilder(aiClient)
.UseFunctionInvocation()
.Build();
#endregion
#region 适用于 9.4.0-preview.1.25207.5
// 创建 OpenAI 客户端,并指定使用的模型
IChatClient chatClient = new OpenAI.Chat.ChatClient(
"Qwen/QwQ-32B",
apiKeyCredential,
aiClientOptions
)
.AsIChatClient()
.AsBuilder()
.UseFunctionInvocation()
.Build();
#endregion
//创建消息
IList<ChatMessage> Messages = [
new(ChatRole.System, "你是一个很有帮助的助手,帮助我们测试MCP服务器的功能"),
new(ChatRole.User, "现在,我有一个网页需要你帮我分析一下,网页的地址是:https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.html"),
];
//通过大模型调用fetch工具
var response = await chatClient.GetResponseAsync(
Messages,
new() { Tools = [.. tools] });
//获取工具使用的消息
var toolUseMessage = response.Messages.Where(m => m.Role == ChatRole.Tool);
if (response.Messages[0].Contents.Count > 1)
{
var functionCall = (FunctionCallContent)response.Messages[0].Contents[1];
}
调试结果如下:


这样我们就完成了对Fetch 工具 的基本调用了,是不是很简单就可以了,perfect!!!
3.小结
本文介绍了MCP的基本概念和工作模式,然后演示了如何通过 C# SDK创建 MCP Client 对 MCP 工具的调用。由于篇幅过长,后面我会再看情况写一篇关于MCP 服务 的Demo ,并演示MCP Client 对我们自己开发的MCP Server 的调用
如果你也是.NET程序员希望参与AI应用的开发,那就快快了解和使用基于Microsoft.Extensioins.AI + MCP C# SDK 的生态组件库吧。

浙公网安备 33010602011771号