构建你的 MCP 能力层:.NET 9 + SK 的系统方案
环境准备与基线项目(.NET 9 + SK + MCP)
目标:搭建最小可运行的 .NET 控制台,引用 SK 与 MCP,完成一次 MCP Ping 健康检查(Stdio 与 SSE/HTTP 各跑通一次),并为后续端到端示例打下基线。
1.1 创建解决方案与基线项目
# 安装 .NET 9 SDK(略)
mkdir SkMcp && cd SkMcp
dotnet new sln -n SkMcp
# 创建三个项目:
# 1) 最小可运行基线(含 Ping 冒烟测试)
# 2) MCP Server(Stdio/HTTP 两种宿主)
# 3) SK 客户端(演示“把 MCP 工具当作 SK 函数”)
mkdir -p src/SkMcp.Baseline src/SkMcp.Server src/SkMcp.SkClient tests/SkMcp.End2End
dotnet new console -n SkMcp.Baseline -o src/SkMcp.Baseline
dotnet new console -n SkMcp.Server -o src/SkMcp.Server
dotnet new console -n SkMcp.SkClient -o src/SkMcp.SkClient
dotnet new xunit -n SkMcp.End2End -o tests/SkMcp.End2End
# 解决方案引用
dotnet sln add src/*/**.csproj tests/*/**.csproj
结构建议
src/*
与tests/*
分离,后者用于 E2E 冒烟(Ping、ListTools、CallTool 回显)。- 为每个 Server 建
docs/
示例资源目录,便于 resources 流程(第 6 章)。
版本固定策略:以上
dotnet add
仅添加包名,实际生效版本由根目录Directory.Packages.props
锁定(Microsoft.SemanticKernel=1.65.0
,McpDotNet.Extensions.SemanticKernel=0.0.1-preview-04
)。构建管线中启用-p:ContinuousIntegrationBuild=true
与-warnaserror
,确保出现不兼容 API 时能第一时间在 CI 上失败而非运行期暴露问题。
版本与兼容性建议
- MCP SDK 仍在快速迭代,推荐在根目录使用
Directory.Packages.props
锁定主次版本,避免传递依赖“偷偷升级”。 McpDotNet.Extensions.SemanticKernel
与 SDK 存在配套关系:如遇 API 不匹配,优先以 MCP SDK 版本为锚回退/前进。
建议的
Directory.Packages.props
片段(版本固定)<Project>
<ItemGroup>
<PackageVersion Include="ModelContextProtocol" Version="0.3.0-preview.*" />
<PackageVersion Include="McpDotNet.Extensions.SemanticKernel" Version="0.0.1-preview-04" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.65.0" />
</ItemGroup>
</Project>
说明:构建时将严格解析到以上版本;如需升级,请同步验证扩展包与 SDK 的 API 兼容性,再做渐进发布(先预发环境,再生产灰度)。
<Project>
<ItemGroup>
<PackageVersion Include="ModelContextProtocol" Version="0.3.0-preview.*" />
<PackageVersion Include="McpDotNet.Extensions.SemanticKernel" Version="0.3.*" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.*" />
</ItemGroup>
</Project>
1.3 .env
与本地机密管理(User Secrets)
开发期:
- 使用 User Secrets +
IConfiguration
,避免把密钥写入源码; appsettings.Development.json
仅放非敏感默认值;- 机密键命名约定:
OpenAI:ApiKey
、GitHub:Token:RepoRead
等。
生产期:
- 云端使用 Key Vault/Secrets Manager + 托管标识;
- 容器仅挂载只读 Secret,不要把
.env
bake 进镜像; - 最小权限:OpenAI 仅
apiKey
;GitHub PAT 起步repo:read
、issues:read
。
1.4 MCP “Ping” 最小验证(Stdio 与 SSE/HTTP)
新增一个最小冒烟控制台(或在 Baseline 中内置):
- Stdio:通过
npx
/Node 启动本地示例 server(如 server-everything),客户端PingAsync
+ListTools
+CallTool("echo")
; - SSE/HTTP:对等流程;
- 跨平台提示(Windows 常见问题):若出现 ENOENT/找不到
npx
,请使用 Node 的绝对路径或where npx
结果; - 长连接保活:定期
PingAsync
; - E2E 测试点:
Ping
成功;ListTools
至少包含echo
;CallTool("echo", { message: "hello" })
返回包含hello
的文本内容。
关于传输:SSE 仍可用,但更推荐 Streamable HTTP(第 2.4、4.2 详述)。
MCP 概念速通与协议选型(强化到 Streamable HTTP)
2.1 核心概念
- Tools:由 MCP Server 暴露的可调用能力(读/写/搜索等)。
- Resources:可检索/读取的外部资料(文档、代码、数据),支持分页与哈希标识。
- Prompts:可复用提示模板,由 Server 声明,客户端可发现与调用。
subgraph Host[LLM Host / Orchestrator]
SK[Semantic Kernel]
Behavior[FunctionChoiceBehavior Policies]
end
subgraph MCPClient[MCP Client]
Discovery[List Tools/Resources/Prompts]
Invoke[call_tool]
end
subgraph MCPServers[MCP Servers]
S1[Server A
e.g., GitHub]
S2[Server B
Doc/FS/DB]
end
subgraph Backends[External Systems]
GH[GitHub API]
FS[File Store]
DB[Database]
end
SK-->Behavior-->Discovery-->Invoke
Invoke-->S1-->GH
Invoke-->S2-->FS
S2-->DB
autonumber
participant User as User/Agent
participant SK as SK (Kernel)
participant MCPc as MCP Client
participant MCPs as MCP Server
participant Ext as External System
User->>SK: 触发任务(含系统/用户提示)
SK->>MCPc: 列举可用工具(ListTools/Prompts/Resources)
MCPc-->>SK: 工具与参数 Schema
SK->>SK: 策略评估(白名单/置信度/成本)
SK->>MCPc: call_tool(tool, args)
MCPc->>MCPs: 执行(Streamable HTTP/SSE/Stdio)
MCPs->>Ext: 调用外部系统(幂等/超时/重试)
Ext-->>MCPs: 结果/分页数据
MCPs-->>MCPc: 流式增量内容(可包含 resource link)
MCPc-->>SK: 聚合结果
SK-->>User: 最终回答(含引用与可追溯信息)
2.4 传输协议选型
- Stdio:本地开发/快速试验,零网络依赖。
- SSE:历史方案,适合流式文本下行。
- Streamable HTTP(推荐):统一 HTTP 请求/响应 + 可选事件流,覆盖一次性结果与长任务输出;同一服务可既支持传统 HTTP,也支持事件流端点,便于渐进迁移。
迁移建议:HTTP 宿主默认启用 Streamable HTTP,保留 SSE 兼容端点若干版本。
作为 MCP Client——在 SK 中“接工具”
3.1 方式 A:用扩展包“一行接入”(Stdio & SSE/HTTP)
// Program.cs 片段
var builder = Kernel.CreateBuilder();
// ... 配置 OpenAI/AzureOpenAI 等模型
// 以 Stdio 形式连接某 MCP Server(示例:server-everything)
await builder.AddMcpFunctionsFromStdioServerAsync(
kernel:
null, // 可省略,使用 builder 内核
serverExecutablePath:
"/absolute/path/to/node", // Windows 下建议绝对路径
serverArgs: new [] { "npx", "-y", "@modelcontextprotocol/server-everything" },
namePrefix: "everything_", // 避免与其他 Server 同名工具冲突
includedPlugins: null,
includedFunctions: null,
cancellationToken: ct);
var kernel = builder.Build();
// 打印工具清单(调试)
foreach (var f in kernel.GetFunctions())
{
Console.WriteLine($"{f.PluginName}.{f.Name} -> {f.Description}");
}
// 白名单方式减少“误触发”
var behavior = FunctionChoiceBehavior.Auto(allowance: 3,
functions: kernel.GetFunctions()
.Where(f => f.Name.StartsWith("http_") || f.Name == "echo"));
实践加强
- 限流/超时:为高成本工具(如
http/get
)套一层包装,设置超时、最大返回大小(KB/MB)与调用间隔(冷却时间)。 - 系统提示:在
system
中明确“仅在需要时才调用工具,并优先使用指定白名单”。
3.2 方式 B:纯 SDK(“裸接入”)把 MCP 工具转为 SK 函数
要点:
- JSON schema → SK 参数:对
object/array
入参,优先整体 JSON 字符串透传,减少 LLM 构造复杂结构的出错率; - Content 聚合:
call_tool
返回可能包含text
与resource
链接,注意把ResourceLink
也回传给终端应用(用于可追溯)。
作为 MCP Server——用 C# 暴露你自己的工具
4.1 Stdio 版本(控制台宿主)
// Program.cs(简化)
var server = McpServerBuilder.Create("demo-server")
.WithToolsFromAssembly(typeof(Program).Assembly)
.WithResources(opts => opts.RootDirectory = "./docs")
.Build();
await server.RunStdioAsync();
建议
- 每个工具方法都接受
CancellationToken
,并在服务器级配置软超时; - 输入校验:例如
CsvFilter(string column, string op, string value)
增加列名白名单、最大行数/文件大小限制,避免 OOM; - 日志分流:业务日志走
stdout
、诊断/调试走stderr
,方便客户端区分。
Client\[Client/Browser/Agent] --> Proxy\[Reverse Proxy/Nginx]
Proxy --> Kestrel\[ASP.NET Core (Kestrel)]
Kestrel -->|/mcp (HTTP)| EndpointHTTP\[HTTP Endpoint]
Kestrel -->|/mcp/events (SSE)| EndpointSSE\[SSE/Events]
EndpointHTTP --> Tools\[Tools]
EndpointHTTP --> Resources\[Resources]
EndpointSSE --> Tools
EndpointSSE --> Resources
4.3 容器化(Dockerfile)
# 多阶段构建
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish src/SkMcp.Server/SkMcp.Server.csproj -c Release -o /out
FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
COPY --from=build /out .
# 只读挂载机密;不要复制 .env 到镜像
ENTRYPOINT ["dotnet", "SkMcp.Server.dll"]
4.4 部署与运维(systemd / Nginx / 健康检查)
- 健康检查:除 MCP 通道
Ping
外,暴露独立/healthz
区分进程活性与业务健康; - 日志与指标:结构化日志(JSON)+ Prometheus 指标(QPS、失败率、P95 时延、事件流存活数);
- 滚动升级:灰度/金丝雀,回滚策略与版本锚定。
端到端 A:开发者 GitHub 助手
5.1 选用官方 GitHub MCP Server
- 优先使用官方镜像/源码运行(Stdio 或远端 HTTP);
- 从只读权限起步(
repo:read
、issues:read
),确认调用路径稳定再逐步放开写权限; - 为
search issues
之类高频工具加冷却时间与分页上限。
5.2 在 SK 侧注册 GitHub 工具(扩展包写法)
await builder.AddMcpFunctionsFromSseServerAsync(
serverUrl: new Uri("https://your-github-mcp.example/mcp"),
namePrefix: "gh_",
includedFunctions: new [] { "search_issues", "get_repo" },
cancellationToken: ct);
端到端 B:企业知识检索助手(Resources)
6.1 Server 侧资源暴露
- 大文件/大目录务必强制分页(按字节或行数),返回
cursor/next
; - 明确
contentType
与编码,例如text/markdown; charset=utf-8
; - 返回
resourceUri
与hash/etag
,便于可追溯与缓存控制。
6.2 客户端(SK)检索与回答(ReAct 思路)
- 将“检索→调用→回答”的中间观察写入隐藏槽位或日志;
- 对用户输出统一以“三句话摘要 + 引用 URI”收尾;
- 对模型的工具选择策略使用白名单 + 置信阈值,避免“为了调用而调用”。
端到端 C:数据处理流水线(Prompts + Tools)
7.1 在 MCP Server 注册可复用 Prompt
- 将规范化的数据清洗/汇总模板以 Prompt 形式暴露,参数化日期、项目名等;
- 对 Prompt 做版本号管理(如
v2025.09
)以便回溯。
T0[触发: {date}:{project}] --> T1[检索与预清洗
(MCP: CsvClean/CsvFilter/HttpGet)]
T1 -->|失败: 重试N次→死信| DLQ[Dead Letter Queue]
T1 --> T2[聚合与特征化
(MCP: Prompt v2025.09)]
T2 --> T3[生成报告草稿
(SK: LLM with FunctionChoiceBehavior)]
T3 -->|资源引用与哈希| T4[落盘→命名含内容哈希]
T4 --> T5[发布/通知/审计]
文档化、学习路径与 FAQ(扩展)
8.1 学习路径
- 跑通第 1 章最小冒烟(Stdio + SSE/HTTP)→ 2) 第 3 章把工具接入 SK → 3) 任一端到端示例(5/6/7 章)→ 4) 生产化与安全(4.3/4.4)。
8.2 踩坑手册
- 代理与事件流:公司网关可能“截流”事件流,需在反代层
proxy_buffering off
并放宽空闲超时; - 同名工具冲突:不同 Server 暴露同名工具时,在注册时加
namePrefix
或放入不同插件命名空间; - CSV 换行混用:
\r\n
/\n
混用会导致“按行分页错位”,统一转 LF 后再分页; - Windows
npx
不可见:使用 Node 绝对路径或where npx
结果; - 模型“过度调用工具”:白名单 + 明确系统提示 + 冷却时间控制。
构建你的 MCP 能力层:.NET 9 + SK 的系统方案的更多相关文章
- 华为视频编辑服务(Video Editor Kit),助力开发者高效构建应用视频编辑能力
视频编辑服务(Video Editor Kit)是华为开放给开发者快速构建视频编辑能力的服务,提供视频导入.编辑处理.特效渲染.视频导出.媒体资源管理等一站式视频处理能力.视频编辑服务为全球开发者提供 ...
- 华为音频编辑服务(Audio Editor Kit),快速构建应用音频编辑能力
音频编辑服务(Audio Editor Kit)是华为为开发者开放的各类场景音频处理能力的集合,汇聚了华为在音乐.语音等相关音频领域的先进技术.音频编辑服务提供基础编辑.伴奏提取.空间渲染.变声降噪等 ...
- CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全
本文作者:王振威 - CODING 研发总监 CODING 创始团队成员之一,多年系统软件开发经验,擅长 Linux,Golang,Java,Ruby,Docker 等技术领域.近两年来一直在 COD ...
- 使用JDBC构建简单的数据访问层
本教程的目的是使用Java编写的分离的层去访问数据库中的表,这一层通常称为数据访问层(DAL) 使用DAL的最大好处是通过直接使用一些类似insert()和find()的方法简化了数据库的访问操作,而 ...
- 读书笔记_MVC__关于通过js构建ORM,实现Model层
最近一直在学习MVC构建富应用的WEB程序,自己一直对MVC的设计模式理解的不是十分透彻,终于在研读了github上Spine的源码之后,对构建Model层有了一点自己的理解. 本文仅为个人理解,如有 ...
- 架构设计:负载均衡层设计方案(6)——Nginx + Keepalived构建高可用的负载层
1.概述 前两遍文章中,我们一直在说后文要介绍Nginx + Keepalived的搭建方式.这篇文章开始,我们就来兑现前文的承诺,后续的两篇文章我们将介绍Nginx + Keepalived和 LV ...
- 总结之H3C汇聚层交换机认证在线人数展示系统
前情提要:意外接了老师说的一个小程序,然后计划7天(实际10天)的小项目就冒出来了. (1)时间与工程量.在和老师开始谈具体需求前,我凭感觉猜了猜完成这个小项目的时间.然后,再和老师确定需求后,再回头 ...
- H3C汇聚层交换机认证在线人数展示系统之需求说明和功能点说明
一.需求 (一)每五分钟查询一次交换机的连接情况: (二)每2.5分钟更新每栋楼的连接情况. 二.功能点 序号 功能点说明 待定 完成 未完成 完成时间 预计用时(min) 实际用时(min) 备注 ...
- 四种有能力取代Cookies的客户端Web存储方案
目前在用户的网络浏览器中保存大量数据需要遵循几大现有标准,每一种标准都拥有自己的优势.短板.独特的W3C标准化状态以及浏览器支持级别.但无论如何,这些标准的实际表现都优于广泛存在的cookies机制. ...
- 根文件系统的构建与分析(四)之瑞士军刀busybox生成系统基本命令
根文件系统的构建与分析(四) 转载请注明 http://blog.csdn.net/jianchi88 Author:Lotte 邮箱:baihaowen08@126.com ls /bin, ...
随机推荐
- 前端ast
什么是抽象语法树 抽象语法树 Abstract Syntax Tree 简称AST,是源代码语法结构的一种抽象表示. 比如 const a = 123; ,用ast可以表示为 ast json表示为 ...
- mermaid与marked结合使用
前提 两者都很强大,但是两者结合,存在问题,目前网上无解. 以下两种版都需要在index.html 即入口页面添加一个元素 <body> <div id="root&quo ...
- teamcity自动化部署
简介 用的自动化部署的工具,IntelliJ 家的产品teamcity对内存要求及高,我的1gb的内存就出现了"TeamCity服务器正在遇到内存不足的问题.内存清理花费了超过50%的时间. ...
- wordpress - 上传附件大小更改
我用的是树莓派4b,需要修改php.ini的路径是/etc/php/7.3/apache2/php.ini.根据安装的php版本来决定所在的路径. 让然了,也可以 sudo find / -name ...
- 项目捷报 | 冠捷科技泰国工厂THA MES项目成功验收!TPV国际化布局再添里程碑!
近日,盘古信息与冠捷科技(TPV)携手打造的泰国工厂MES项目(THA MES项目)圆满通过验收.这不仅标志着TPV在全球数字化制造布局中取得重大突破,更成为盘古信息赋能其"两国五城七期&q ...
- API可视化编排如何实现
企业随着前后端分离架构.微服务架构.中台战略.产业互联互通的实施必将产生大量的各种协议的API服务,API将成为企业的数字化资产且API会越来越多, API服务之间的相互调用和依赖情况也随之越来越多和 ...
- TinyEditor v4.0 alpha 版本发布:表格更强大,表情更丰富,上传体验超乎想象!
你好,我是 Kagol,个人公众号:前端开源星球. TinyEditor 是一个基于 Quill 2.0 的富文本编辑器,在 Quill 基础上扩展了丰富的模块和格式,框架无关.功能强大.开箱即用. ...
- 管理心理学 Management Psychology
管理心理学 Management Psychology 作者: 浏览量:4046 [课程编号][所属模块]专业方向课 [学分数]3学分 [适用专业]心理学 [学时数]52学时 [开设学期]秋季 [已开 ...
- 企业AI知识库的文件解析痛点-Word格式解析优化(准确率95%)-100%开源
一.前言 在大模型和RAG(检索增强生成)技术飞速发展的今天,企业AI知识库建设已成为AI落地的核心战场.而文件解析是所有参与做企业AI知识库开发者所避免不了的难题. 本文将结合我在开发TorchV ...
- Win11系统更新失败错误0x800f081f的问题
使用Windows11系统的电脑基地用户都知道,win11更新补丁漏洞是十分勤奋的,可以说每周都会更新一次,而不少用户在更新的时候却遇到一些问题,出现错误代码0x800f081f,导致更新失败.那么遇 ...