使用C#创建一个MCP客户端
前言
网上使用Python创建一个MCP客户端的教程已经有很多了,而使用C#创建一个MCP客户端的教程还很少。
为什么要创建一个MCP客户端呢?
创建了一个MCP客户端之后,你就可以使用别人写好的一些MCP服务了。
效果展示
为了方便大家复现,我没有使用WPF/Avalonia之类的做界面。只是一个简单的控制台程序,可以很容易看懂。

接入了fetch_mcp可以实现获取网页内容了,使用的模型只要具有tool use能力的应该都可以。
我使用的是Qwen/Qwen2.5-72B-Instruct。
开始实践
主要使用的包如下所示:

首先获取MCP服务器:
private static async Task<IMcpClient> GetMcpClientAsync()
{
DotEnv.Load();
var envVars = DotEnv.Read();
McpClientOptions options = new()
{
ClientInfo = new() { Name = "SimpleToolsConsole", Version = "1.0.0" }
};
var config = new McpServerConfig
{
Id = "test",
Name = "Test",
TransportType = TransportTypes.StdIo,
TransportOptions = new Dictionary<string, string>
{
["command"] = envVars["MCPCommand"],
["arguments"] = envVars["MCPArguments"],
}
};
var factory = new McpClientFactory(
new[] { config },
options,
NullLoggerFactory.Instance
);
return await factory.GetClientAsync("test");
}
写死的话就是这样写:
private static async Task<IMcpClient> GetMcpClientAsync()
{
DotEnv.Load();
var envVars = DotEnv.Read();
McpClientOptions options = new()
{
ClientInfo = new() { Name = "SimpleToolsConsole", Version = "1.0.0" }
};
var config = new McpServerConfig
{
Id = "test",
Name = "Test",
TransportType = TransportTypes.StdIo,
TransportOptions = new Dictionary<string, string>
{
["command"] = node,
["arguments"] = D:/Learning/AI-related/fetch-mcp/dist/index.js,
}
};
var factory = new McpClientFactory(
new[] { config },
options,
NullLoggerFactory.Instance
);
return await factory.GetClientAsync("test");
}
重点在:
TransportOptions = new Dictionary<string, string>
{
["command"] = node,
["arguments"] = D:/Learning/AI-related/fetch-mcp/dist/index.js,
}
用于连接你想连接的MCP服务器。
如果能正确显示你连接mcp服务器提供的工具,说明连接成功。
var listToolsResult = await client.ListToolsAsync();
var mappedTools = listToolsResult.Tools.Select(t => t.ToAITool(client)).ToList();
Console.WriteLine("Tools available:");
foreach (var tool in mappedTools)
{
Console.WriteLine(" " + tool);
}

开启一个聊天循环:
Console.WriteLine("\nMCP Client Started!");
Console.WriteLine("Type your queries or 'quit' to exit.");
ChatDemo chatDemo = new ChatDemo();
while (true)
{
try
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.Write("\nQuery: ");
string query = Console.ReadLine()?.Trim() ?? string.Empty;
if (query.ToLower() == "quit")
break;
if (query.ToLower() == "clear")
{
Console.Clear();
chatDemo.Messages.Clear();
}
else
{
string response = await chatDemo.ProcessQueryAsync(query, mappedTools);
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine($"AI回答:{response}");
Console.ForegroundColor = ConsoleColor.White;
}
}
catch (Exception ex)
{
Console.WriteLine($"\nError: {ex.Message}");
}
}
}
处理每次询问:
public async Task<string> ProcessQueryAsync(string query, List<AITool> tools)
{
if(Messages.Count == 0)
{
Messages =
[
// Add a system message
new(ChatRole.System, "You are a helpful assistant, helping us test MCP server functionality."),
];
}
// Add a user message
Messages.Add(new(ChatRole.User, query));
var response = await ChatClient.GetResponseAsync(
Messages,
new() { Tools = tools });
Messages.AddMessages(response);
var toolUseMessage = response.Messages.Where(m => m.Role == ChatRole.Tool);
if (toolUseMessage.Count() > 0)
{
var functionMessage = response.Messages.Where(m => m.Text == "").First();
var functionCall = (FunctionCallContent)functionMessage.Contents[1];
Console.ForegroundColor = ConsoleColor.Green;
string arguments = "";
foreach (var arg in functionCall.Arguments)
{
arguments += $"{arg.Key}:{arg.Value};";
}
Console.WriteLine($"调用函数名:{functionCall.Name};参数信息:{arguments}");
foreach (var message in toolUseMessage)
{
var functionResultContent = (FunctionResultContent)message.Contents[0];
Console.WriteLine($"调用工具结果:{functionResultContent.Result}");
}
Console.ForegroundColor = ConsoleColor.White;
}
else
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("本次没有调用工具");
Console.ForegroundColor = ConsoleColor.White;
}
return response.Text;
}
代码已经放到GitHub,地址:https://github.com/Ming-jiayou/mcp_demo。
将.env-example修改为.env应该就可以运行,如果报错,设置成嵌入的资源即可。
.env配置示例:
API_KEY=sk-xxx
BaseURL=https://api.siliconflow.cn/v1
ModelID=Qwen/Qwen2.5-72B-Instruct
MCPCommand=node
MCPArguments=D:/Learning/AI-related/fetch-mcp/dist/index.js
最后
对C#使用MCP感兴趣的朋友可以关注这个项目:https://github.com/PederHP/mcpdotnet。
有问题欢迎一起交流学习。
使用C#创建一个MCP客户端的更多相关文章
- [Swift通天遁地]四、网络和线程-(13)创建一个Socket客户端
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- cxf的使用及安全校验-02创建简单的客户端接口
上一篇文章中,我们已经讲了如果简单的创建一个webservice接口 http://www.cnblogs.com/snowstar123/p/3395568.html 现在我们创建一个简单客户端接口 ...
- [Swift通天遁地]四、网络和线程-(14)创建一个Socket服务端
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- kubenetes创建一个pod应用
Pod是可以创建和管理Kubernetes计算的最小可部署单元.一个Pod代表着集群中运行的一个进程.每个pod都有一个唯一的ip. 一个pod类似一个豌豆荚,包含一个或多个容器(通常是docker) ...
- 搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 (1)
搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 原文地址(英文):http://www.networkcomms.net/creating ...
- 一个关于如何创建类似于QQ客户端聊天窗口的模拟小项目
对于不久之前学习到的一个有关的类似于QQ聊天框的模拟项目,对其中涉及到的知识在这里做一下总结. 首先,你要先创建一个客户端聊天框(取名为:ChatClient,它是你创建的类),这个类继承了Frame ...
- 管理员技术(四): 配置NTP网络时间客户端、 创建一个备份包、 配置用户和组账号、配置一个cron任务
一. 配置NTP网络时间客户端 目标: 本例要求配置虚拟机 server0,能够自动校对系统时间.相关信息如下: 1> NTP服务器位于 classroom.example.com ...
- 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用
由于ASP.NET Web API具有与ASP.NET MVC类似的编程方式,再加上目前市面上专门介绍ASP.NET Web API 的书籍少之又少(我们看到的相关内容往往是某本介绍ASP.NET M ...
- ASP.NET Core管道深度剖析(2):创建一个“迷你版”的管道来模拟真实管道请求处理流程
从<ASP.NET Core管道深度剖析(1):采用管道处理HTTP请求>我们知道ASP.NET Core请求处理管道由一个服务器和一组有序的中间件组成,所以从总体设计来讲是非常简单的,但 ...
- Step by Step 创建一个 Web Service
原创地址:http://www.cnblogs.com/jfzhu/p/4022139.html 转载请注明出处 (一)创建Web Service 创建第一个项目,类型选择ASP.NET Empty ...
随机推荐
- Qt编写地图综合应用13-获取边界点
一.前言 获取边界点一般和行政区划搭配起来使用,比如用户输入一个省市的名称,然后自动定位到该省市,然后对该轮廓获取所有边界点集合输出到js文件,最后供离线使用,获取边界点还有一个功能就是获取当前区域内 ...
- C#反序列化时,反射类型“XXX”时出错,提示:InvalidOperationException
C#反序列化时,反射类型"XXX"时出错,提示:InvalidOperationException的原因是因为: 一个类必须至少有一个空的默认构造函数,才能由XmlSerializ ...
- 使用Matlab进行图像分类
Classify images Instructions are in the task pane to the left. Complete and submit each task one at ...
- Docker Desktop 使用笔记
一.Docker Desktop是什么? Docker Desktop是适用于Windows的Docker桌面,是Docker设计用于在Windows 10上运行.它是一个本地 Windows 应用程 ...
- Spring Security 基于JWT的单点登陆(SSO)开发及原理解析
JDK1.8Spring boot 2.xSpring Security 5.x 单点登录(Single Sign On),简称为SSO,是目前比较流行的企业业务整合的解决方案之一. SSO的定义是在 ...
- HBase-3rowkey的设计
HBase表热点 1 什么是热点 检索habse的记录首先要通过row key来定位数据行. 当大量的client访问hbase集群的一个或少数几个节点,造成少数region server的读/写请求 ...
- w3cschool-微信小程序开发文档-框架
https://www.w3cschool.cn/weixinapp/1g7f1q8l.html MINA文件结构 文件结构 MINA程序包含一个描述整体程序的app和多个描述各自页面的page. 一 ...
- JVM:java虚拟机栈
- 寻找AI新势力!“天翼云息壤杯”高校AI大赛火热报名中!
各位高校开发者们, AI舞台已就位,你准备好了吗? 为加快落实"人工智能+"行动,中国电信集团有限公司充分发挥央企在人工智能领域主力军作用,联合华为技术有限公司共同举办" ...
- DC/DC layout建议
DCDC电路的重要性不言而喻,不合理的PCB Layout会造成芯片性能变差,甚至损坏芯片.如:线性度下降.带载能力下降.工作不稳定.EMI辐射增加.输出噪声增加等. 环路面积最小原则 DC/DC电路 ...