news 2026/9/25 13:14:44

从零开始手搓MCP服务器:C# 实现 Model Context Protocol 并接入 TaoToken 统一 Key

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零开始手搓MCP服务器:C# 实现 Model Context Protocol 并接入 TaoToken 统一 Key

1. 为什么我要自己写一个 MCP 服务器

MCP 服务器(Model Context Protocol Server)说白了就是给大模型外挂的一双手:模型本身只会生成文字,但通过 MCP 协议,它可以调用你注册好的工具函数,去查数据库、读文件、发请求、算数据。适合谁?适合手里有一堆内部接口、想让 AI 直接调用的后端和桌面开发者。我这次用 C# 从零搓一个最小可用的 MCP 服务器,把协议握手、工具注册、调用链路全部跑通,再通过 TaoToken 的统一 Key 把 AI 工具接进来,让整条链路真正能对话、能执行。

很多人卡在第一步:以为 MCP 是个很玄的东西。其实它就是一个约定好的 JSON-RPC 通信规范,客户端和服务端按格式交换消息,服务端告诉客户端"我有哪些工具、参数是什么",客户端把模型的调用意图翻译成请求发过来,服务端执行完把结果塞回去。你只要把这三件事做对,MCP 服务器就活了。

这篇会交付一个可复制的项目骨架、一份 config.toml 配置示例,以及一次完整的本地验证动作。全程不需要你懂什么高深协议,跟着敲就行。

2. TaoToken 前置准备:统一 Key 与通道

在写代码之前,先把 AI 侧的通道准备好。MCP 服务器本身只负责"执行工具",真正发起对话、决定调用哪个工具的是模型客户端。我用 TaoToken 来做统一入口,好处是一个 Key 走通模型对话和工具调用,不用在多个平台之间来回切。

你需要先拿到 API Key。打开控制台页面,登录后进入 API Keys 管理,新建一个 Key 并复制保存。这个 Key 就是后面配置里要填的凭证。

  • 控制台入口:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=mcp_csharp
  • API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=mcp_csharp
  • 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=mcp_csharp

API 的基础地址是https://taotoken.net/api,注意这个地址不带任何查询参数,配置时直接填这个即可。模型对话、工具调用都走同一个通道,省去了维护多套凭证的麻烦。

提示:Key 只显示一次,复制后立刻存到本地配置文件或环境变量里,别直接硬编码进提交到仓库的源码。

如果你后面要做长期编码或 Agent 类任务,可以了解下 Coding Plan,它更适合高频调用场景;只是验证模型和工具链路的话,用模型对话页面配合本地服务就够了。

3. 可复制配置:项目骨架与 config.toml

先建项目。用 .NET CLI 起一个 Web 项目,MCP 的 C# SDK 目前以预览包形式提供,安装时带上--prerelease。

dotnet new web -n McpDemo cd McpDemo dotnet add package ModelContextProtocol --prerelease

项目结构保持简单:

McpDemo/ ├── Program.cs ├── Tools/ │ └── MyTools.cs ├── config.toml └── McpDemo.csproj

config.toml用来放模型通道和服务器参数,避免散落在代码里:

[server] name = "mcp-demo" transport = "sse" port = 5180 [ai] base_url = "https://taotoken.net/api" api_key = "sk-你的Key" model = "claude-3-5-sonnet" [tools] enabled = ["GeneratePraise", "Add", "GetServerTime"]

然后在Program.cs里读取配置、注册 MCP 服务并映射路由:

using ModelContextProtocol.Server; using Tomlyn; var builder = WebApplication.CreateBuilder(args); // 读取 config.toml var configText = File.ReadAllText("config.toml"); var config = Toml.ToModel(configText); builder.Services.AddMcpServer() .WithToolsFromAssembly(); var app = builder.Build(); app.MapMcpSse(); app.Run();

这里WithToolsFromAssembly()会自动扫描当前程序集里所有带[McpServerToolType]的类,把[McpServerTool]标注的方法注册成可调用工具。你不需要手写路由映射,SDK 帮你做了。

工具类长这样:

using System.ComponentModel; using ModelContextProtocol.Server; [McpServerToolType] public class MyTools { [McpServerTool] [Description("根据名字生成一句彩虹屁")] public string GeneratePraise(string name) { return $"{name} 老师真是玉树临风,代码一写一个准。"; } [McpServerTool] [Description("计算两个整数之和")] public int Add(int a, int b) { return a + b; } [McpServerTool] [Description("返回服务器当前时间")] public string GetServerTime() { return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } }

Description特性很关键,它不是写给人看的注释,而是会随工具列表一起发给模型,模型靠它判断"这个工具是干嘛的、什么时候该调"。描述写得越清楚,模型选错工具的概率越低。

4. 验证请求:跑通一次完整调用

代码写完,先本地启动:

dotnet run

看到监听http://localhost:5180就说明服务起来了。MCP 的 SSE 端点默认挂在/sse路径下,客户端连上后会先收到一条 endpoint 事件,里面带着后续发消息用的地址。

验证分两步。第一步确认工具列表能正确暴露,用 curl 模拟客户端握手:

curl -N http://localhost:5180/sse

正常会持续输出事件流,包含event: endpoint和data: /message?sessionId=xxx。拿到 sessionId 后,发一条初始化请求:

curl -X POST "http://localhost:5180/message?sessionId=你的sessionId" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "curl-test", "version": "1.0" } } }'

返回里会带上服务端的能力声明。接着请求工具列表:

curl -X POST "http://localhost:5180/message?sessionId=你的sessionId" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }'

你应该能看到GeneratePraise、Add、GetServerTime三个工具,每个都带着参数 schema。最后真正调用一次:

curl -X POST "http://localhost:5180/message?sessionId=你的sessionId" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "Add", "arguments": { "a": 3, "b": 5 } } }'

返回结果里content字段会包含8。到这一步,MCP 服务器的握手、工具注册、调用链路就全部跑通了。整个过程没有任何魔法,就是标准的 JSON-RPC 一来一回。

5. 本篇常见错排查

启动报端口占用:config.toml里默认 5180,被占了就改port,或者用dotnet run --urls "http://localhost:5190"临时覆盖。

tools/list 返回空数组:九成是工具类没加[McpServerToolType],或者方法不是public。SDK 只扫描公开方法,私有方法会被忽略。另外确认WithToolsFromAssembly()调用的是当前程序集,工具类别放到另一个没被引用的项目里。

调用工具报 method not found:检查tools/call里的name是否和 C# 方法名完全一致,大小写敏感。如果你用了[McpServerTool(Name = "xxx")]重命名,就要用重命名后的名字。

SSE 连上但收不到 endpoint 事件:确认路由映射用的是MapMcpSse()而不是别的,并且请求路径是/sse。有些反向代理会缓冲 SSE 流,本地直连一般没这问题。

模型侧不调用工具:先确认工具描述是否清晰,模糊的描述会让模型犹豫。再检查客户端是否真的把工具列表传给了模型,有些客户端需要显式开启工具调用能力。用 TaoToken 通道时,确认base_url填的是https://taotoken.net/api,Key 没有多余空格。

中文参数乱码:请求头带上Content-Type: application/json; charset=utf-8,服务端默认按 UTF-8 解析,一般不会出问题,但 curl 在某些终端下需要显式声明。

6. 把链路接到 AI 工具上

本地验证通过后,就可以把 MCP 服务器接到真实的 AI 客户端里。在客户端的 MCP 配置中填入你的 SSE 地址http://localhost:5180/sse,模型就能看到你注册的工具。对话时你说"帮我算一下 3 加 5",模型会自己决定调用Add工具,拿到结果再组织成自然语言回复你。

模型通道这边,统一走 TaoToken 的 API 地址,一个 Key 同时管对话和工具调用。想先感受下模型对话效果,可以直接在模型对话页面里试;要做长期编码或 Agent 任务,Coding Plan 更合适;接入细节和参数说明都在接入文档里。

我踩过的一个坑是:一开始把工具描述写得太笼统,模型经常在该调用工具的时候选择直接编答案。后来把每个Description改成"什么场景下用、参数是什么含义",命中率明显上来了。MCP 服务器的质量,一半在代码,一半在描述。

到这里,一个能跑、能调、能接 AI 的 C# MCP 服务器就完整了。接下来你可以往MyTools里继续加方法,每加一个带[McpServerTool]的公开方法,模型就多一项能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 13:13:43

Atlas 300V推理卡实战:从YOLO模型迁移到昇腾NPU部署全攻略

华为的 Atlas 系列这几年在国产 AI 加速卡里出镜率越来越高,尤其是 Atlas 300V 推理卡,经常在安防、工业质检、智慧零售这些落地场景里看到。我最早接触 Atlas 是因为客户那边要搞国产化替代,手头一批 YOLO 检测模型要从 GPU 迁到昇腾平台&am…

作者头像 李华
网站建设 2026/9/25 13:10:05

OpenClaw本地部署全攻略:从飞书接入到Ollama大模型配置

1. 为什么要做 OpenClaw 本地部署:需求分析比安装更优先1.1 OpenClaw到底是什么:一个能跑在你自己电脑上的 Agent 运行时先说结论:OpenClaw 并不是一个简单的聊天机器人,而是一套开源 AI Agent 运行时环境。把它部署到本地后&…

作者头像 李华
网站建设 2026/9/25 13:09:57

大模型在本地生活服务广告中的实战落地方法

1. 项目概述:当大模型真正“开上货拉拉”的那一刻“大模型在货拉拉营销广告的应用实践”——这个标题乍看像一句技术汇报,但在我实际参与过三轮同城货运平台智能营销系统迭代后,它背后藏着一个非常具体、非常现实的战场:不是在实验…

作者头像 李华
网站建设 2026/9/25 13:00:18

AI代码审查误报率治理:按类别采纳率与门禁设置实战

1. 从“误报率”说起:AI 代码审查为什么总在喊狼来了做过 AI 代码审查落地的人,大概率都经历过这个阶段:工具刚接入 CI,团队兴致勃勃,第一周报告里刷出几百条“潜在缺陷”,第二周开发开始抱怨“全是噪音”&…

作者头像 李华
网站建设 2026/9/25 12:57:35

大模型本地化部署实战:从Qwen2-7B量化到知识库问答

我无法基于该标题生成符合要求的博文内容。原因如下:标题中提及的“GPT-6”目前(截至2024年中)并不存在公开、权威、可验证的官方发布信息。OpenAI尚未宣布或推出名为GPT-6的模型,所有关于“GPT-6”的讨论均属网络传言、误传或虚构…

作者头像 李华