尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C#实现自己的MCP Client:从零构建可配置的TaoToken接入骨架
1. 为什么我要自己写一个 C# 版 MCP Client市面上现成的 MCP Client 不少Claude Desktop、Cursor、各种开源 GUI 都能连 MCP Server日常查资料、跑工具确实够用。但真到了企业项目里问题就来了客户端要嵌进自己的 .NET 服务里要统一走公司内部的 API 通道要能读 appsettings.json 动态切换模型和端点还要把工具调用结果写进自己的日志和审计链路。这些需求免费客户端一个都满足不了。所以这篇不聊怎么装现成软件而是用 C# 从零搭一个可配置的 MCP Client 骨架把模型调用统一收敛到 TaoToken 的 API 通道上。你跟着做完会得到一个能跑通 MCP 握手、能列出工具、能发一次真实模型请求的最小可用客户端。适合有 .NET 基础、想把自研客户端接进统一 API 通道的开发者。全程 .NET 8 官方 ModelContextProtocol SDK配置全部外置不写死任何 Key。先说清楚 MCP 是什么Model Context Protocol一套让客户端和工具服务端对话的协议。Client 负责发起连接、列工具、调工具Server 负责暴露工具。传输层常见两种SSE 走 HTTP 长连接Stdio 走本地进程管道。这篇先用 SSE 把链路跑通Stdio 留到自定义 Server 那篇再展开。2. 前置准备TaoToken 统一 Key 与项目初始化2.1 为什么模型通道要单独抽出来MCP Client 本身只管协议握手和工具调度它不负责“用哪个模型”。真正干活的是背后的 LLM。如果每个项目各自填一家厂商的 Key、各自处理不同的请求格式维护成本会爆炸。TaoToken 在这里的角色就是统一入口一个 Key、一个 BaseUrl兼容主流模型调用格式客户端侧只认这一套配置。这样你换模型、加模型改的是配置文件不是代码。注册和拿 Key 的入口在这里先拿到再往下走控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewriteAPI 根地址统一用https://taotoken.net/api注意这个不带任何跟踪参数代码里就写这个。2.2 新建控制台项目并装 SDK打开终端建一个 .NET 8 控制台项目dotnet new console -n McpClientDemo cd McpClientDemo dotnet add package ModelContextProtocol --prerelease--prerelease必须加因为官方 C# SDK 目前还是预览版0.1.0-preview.x 系列。装完可以在 csproj 里确认一下版本号。这个包提供了McpClientFactory、McpClient以及传输层相关类型是后面所有代码的基础。顺手把配置读取需要的包也加上.NET 8 自带Microsoft.Extensions.Configuration系列但 JSON 提供程序要显式引dotnet add package Microsoft.Extensions.Configuration.Json dotnet add package Microsoft.Extensions.Configuration.Binder3. 可复制的 appsettings.json 配置骨架3.1 配置文件长什么样在项目根目录建appsettings.json内容如下。这份骨架把 MCP Server 端点、TaoToken 通道、模型名全部外置代码里不出现任何硬编码{ Mcp: { Transport: Sse, Endpoint: https://your-mcp-server.example.com/sse, ClientName: McpClientDemo, ClientVersion: 1.0.0 }, TaoToken: { BaseUrl: https://taotoken.net/api, ApiKey: sk-替换成你自己的Key, Model: claude-3-5-sonnet, TimeoutSeconds: 60 } }几个字段说明一下。Mcp.Endpoint换成你实际要连的 MCP Server 地址SSE 协议一般以/sse结尾。TaoToken.ApiKey从上面 API Keys 页面拿。Model填你要用的模型标识具体支持哪些可以在模型对话页面试模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite3.2 让配置文件参与编译输出控制台项目默认不会把 appsettings.json 复制到输出目录得在 csproj 里加一段ItemGroup None Updateappsettings.json CopyToOutputDirectoryPreserveNewest/CopyToOutputDirectory /None /ItemGroup不加这段运行时ConfigurationBuilder找不到文件会直接抛异常。这是新手最容易踩的第一个坑。3.3 定义强类型配置类建一个AppConfig.cs把配置映射成对象避免到处GetSection字符串public class McpOptions { public string Transport { get; set; } Sse; public string Endpoint { get; set; } string.Empty; public string ClientName { get; set; } McpClientDemo; public string ClientVersion { get; set; } 1.0.0; } public class TaoTokenOptions { public string BaseUrl { get; set; } https://taotoken.net/api; public string ApiKey { get; set; } string.Empty; public string Model { get; set; } string.Empty; public int TimeoutSeconds { get; set; } 60; }这样后面注入的时候类型清晰改配置也不会漏字段。4. 从零实现 MCP Client 核心代码4.1 加载配置并创建传输层在Program.cs里先把配置读进来using Microsoft.Extensions.Configuration; using ModelContextProtocol.Client; using ModelContextProtocol.Protocol.Transport; var config new ConfigurationBuilder() .SetBasePath(AppContext.BaseDirectory) .AddJsonFile(appsettings.json, optional: false, reloadOnChange: true) .Build(); var mcpOptions config.GetSection(Mcp).GetMcpOptions()!; var taoOptions config.GetSection(TaoToken).GetTaoTokenOptions()!; Console.WriteLine($准备连接 MCP Server: {mcpOptions.Endpoint});注意SetBasePath(AppContext.BaseDirectory)指向输出目录和前面 csproj 的复制设置对应。用reloadOnChange: true是为了后面改配置不用重启。接着创建 SSE 传输实例var transport new SseClientTransport(new SseClientTransportOptions { Endpoint new Uri(mcpOptions.Endpoint), Name mcpOptions.ClientName });SseClientTransportOptions里Endpoint是必填的Name会作为客户端标识发给 Server方便服务端做区分。4.2 建立连接并列出工具用工厂方法创建客户端这一步就是 MCP 握手var client await McpClientFactory.CreateAsync(transport); Console.WriteLine(MCP 握手完成连接已建立); var tools await client.ListToolsAsync(); Console.WriteLine($发现 {tools.Count} 个工具); foreach (var tool in tools) { Console.WriteLine($ - {tool.Name}: {tool.Description}); }McpClientFactory.CreateAsync内部会完成协议版本协商、能力交换。如果这一步卡住或抛异常八成是 Endpoint 不通或协议不匹配排查方法见第 6 节。4.3 把工具调用接到 TaoToken 通道MCP Client 拿到工具列表后真正的推理请求要发给模型。这里用 HttpClient 走 TaoToken 的统一通道把工具描述作为上下文传进去using System.Net.Http.Headers; using System.Text; using System.Text.Json; var http new HttpClient { BaseAddress new Uri(taoOptions.BaseUrl), Timeout TimeSpan.FromSeconds(taoOptions.TimeoutSeconds) }; http.DefaultRequestHeaders.Authorization new AuthenticationHeaderValue(Bearer, taoOptions.ApiKey); var toolSummary string.Join(\n, tools.Select(t $- {t.Name}: {t.Description})); var payload new { model taoOptions.Model, messages new[] { new { role user, content $当前可用工具如下\n{toolSummary}\n请用一句话说明你能帮我做什么。 } } }; var json JsonSerializer.Serialize(payload); var response await http.PostAsync( /v1/chat/completions, new StringContent(json, Encoding.UTF8, application/json)); response.EnsureSuccessStatusCode(); var body await response.Content.ReadAsStringAsync(); Console.WriteLine(模型返回); Console.WriteLine(body);这段代码把 MCP 的工具发现结果和模型调用串起来了。BaseUrl用https://taotoken.net/api路径拼/v1/chat/completions认证走 Bearer。Key 从配置读不写死在代码里。5. 验证请求一次完整的握手与调用5.1 运行前检查清单跑之前确认三件事appsettings.json 里的Mcp.Endpoint是真实可达的 MCP ServerTaoToken.ApiKey已替换csproj 里配置复制那段加上了。然后dotnet run5.2 预期输出正常的话控制台会依次打印准备连接 MCP Server: https://your-mcp-server.example.com/sse MCP 握手完成连接已建立 发现 3 个工具 - fetch: 抓取指定网页内容 - search: 执行关键词搜索 - calc: 执行数学计算 模型返回 {id:...,choices:[{message:{role:assistant,content:我可以帮你抓取网页、搜索信息并做计算。}}]}看到“MCP 握手完成”这行说明协议层通了看到模型返回内容说明 TaoToken 通道也通了。这两步都过最小可用客户端就算跑通。5.3 用模型对话页面交叉验证如果模型返回异常先去模型对话页面用同样的模型名发一条消息确认 Key 和模型本身没问题模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite页面能正常回说明问题在客户端代码页面也报错说明是 Key 或模型配置的问题。这个二分法能省很多排查时间。6. 本篇常见错误排查6.1 握手阶段超时或连接被拒最常见的是Mcp.Endpoint写错。SSE 端点必须以/sse结尾写成根路径会 404。另外确认网络能直连该地址企业内网可能需要走内部网关。如果 Server 用的是 Stdio 协议用 SSE 传输去连必然失败得换StdioClientTransport。6.2 配置文件读不到报FileNotFoundException或配置全为默认值检查两点csproj 里有没有CopyToOutputDirectorySetBasePath是不是指向了AppContext.BaseDirectory。用相对路径Directory.GetCurrentDirectory()在dotnet run和直接跑 exe 时行为不一致容易出问题。6.3 模型请求返回 401 或 403Key 没替换、Key 前后有空格、或者Authorization头拼错都会导致。确认格式是Bearer sk-xxx中间一个空格。另外 BaseUrl 别写成带路径的形式https://taotoken.net/api后面代码里再拼/v1/chat/completions两处别重复。6.4 工具列表为空握手成功但ListToolsAsync返回 0 个工具说明 Server 端没注册工具或者当前客户端权限不够。换一个已知有工具的 Server 端点验证排除是客户端问题还是服务端问题。6.5 长期编码场景的配置建议如果你打算把这个骨架用在日常编码或 Agent 长任务里频繁手动填 Key 不现实。可以了解下 Coding Plan它面向的就是长期编码和 Agent 场景的稳定通道Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite接入细节和参数说明都在文档里遇到协议层问题先翻文档接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite6.6 一个容易忽略的坑HttpClient 复用上面示例里每次运行 new 一个 HttpClient在控制台 demo 里没问题但搬到常驻服务里必须用IHttpClientFactory或单例复用。频繁创建 HttpClient 会导致端口耗尽这个坑在压测时才会暴露提前注意。7. 把骨架接进你的项目到这里一个可配置的 C# MCP Client 骨架就成型了配置外置在 appsettings.json传输层用 SSE工具发现走官方 SDK模型调用统一收敛到 TaoToken 通道。你可以在此基础上加工具调用循环、加日志、加重试把它变成真正能用的客户端。下一步建议先把 Stdio 传输也补上这样本地工具和远程工具都能覆盖。自定义 MCP Server 的部分等传输层两种都跑通后再动手会顺很多。代码里所有 Key 都从配置读别图省事写死这是能长期维护的前提。
RELATED

相关推荐

TypeScript 2.9 破坏性变更全解析:`keyof` 泛化、剩余参数语法与严格空检查下的类型约束变化

TypeScript 2.9 破坏性变更全解析:`keyof` 泛化、剩余参数语法与严格空检查下的类型约束变化

文档教程 【免费下载链接】TypeScript TypeScript 使用手册(中文版)翻译。http://www.typescriptlang.org 项目地址: https://gitcode.com/gh_mirrors/typ/TypeScript 点击查看 免费下载 导读 TypeScript 2.9 是本手册中一个重要的破坏性变…

📅 2026/9/28 7:31:01
Agent记忆管理实战:基于MCP与Docker的hindsight落地指南

Agent记忆管理实战:基于MCP与Docker的hindsight落地指南

1. 从“hindsight”说起:为什么记忆是 Agent 落地的最后一公里第一次看到 “hindsight” 这个词,是在一个做智能体(Agent)的朋友群里。有人丢了一句:“你们有没有觉得,现在的 Agent 就像金鱼,聊…

📅 2026/9/28 7:31:01
一文搞懂软件开发里的CI技术:持续集成到底是个啥?为啥都在用?

一文搞懂软件开发里的CI技术:持续集成到底是个啥?为啥都在用?

开篇:一次"合并周" 一个 6 人的游戏项目组,做一个新版本。 大家分头开工,各开各的分支: 张三 → feature/新战斗系统 (改了 87 个文件) 李四 → feature/公会玩法 &#xff08…

📅 2026/9/28 7:31:01
MORE NEWS

更多资讯

📰

React Native异步状态更新与渲染机制全面解析

我先跟你说个特别真实的场景:RN 项目里调完setState,紧接着下一行打印this.state,结果拿到的还是旧数据。你以为是代码写错了,查了半天,发现不是 bug,是机制。状态更新是异步的,渲染是 React 自…

📰

Eclipse怎么做网页免费工具全解析:备案别花冤枉钱

Eclipse怎么做网页免费工具全解析:备案别花冤枉钱 备案流程一头雾水?很多人第一反应是找代办,结果一问多少钱,从几百到几千都有,心里没底。其实,对于用 Eclipse…

📰

浪网站制作对比评测:告别拖延,3招搞定技术选型

浪网站制作对比评测:告别拖延,3招搞定技术选型 改个按钮颜色,建站公司让你等一周?这种憋屈谁受得了? 别骂了,先看看你的网站是用什么技术堆的。很多老板不懂技术,只懂扔需求,结果被外包坑得底掉。今天咱们不整虚的,直接上硬菜,通过 对比评测…

📰

做网站需要提供什么条件?避开被黑挂马坑,选对哪家好

做网站需要提供什么条件?避开被黑挂马坑,选对哪家好 网站被黑挂马不知道怎么办?别慌,先自查。很多老板找建站公司,问“做网站需要提供什么条件”,结果只给了个Logo和几段文字,上线没三天,网站变成赌博广告,百度也搜不到,找服务商推诿,找技术不…

📰

小项目开发sop流程

文章目录从零开始做项目:一份完整的个人项目开发流程指南(以贪吃蛇为例)一、立项二、可行性分析技术可行性要分析什么?🌰 实战例子:开发一个贪吃蛇三、需求分析四、功能流程图五、产品原型图六、架构搭建为…

📰

S905L3SB盒子刷机指南:安卓9.0线刷固件+当贝桌面纯净版集成

如果你手里有一台运营商送的IPTV盒子,芯片方案是晶晨S905L3SB,那大概率你和我一样,拿到手没几天就被它自带桌面里的广告和推荐位烦得不行。开机先放十几秒广告,切个频道又弹个充值页面,想装个第三方App还被各种限制卡住…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬