news 2026/10/7 2:35:31

用 .NET 构建 Streamable HTTP 的 MCP 服务器:从 dotnet run 到 MCP Inspector 全流程实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 .NET 构建 Streamable HTTP 的 MCP 服务器:从 dotnet run 到 MCP Inspector 全流程实战
  • 教程
  • 文档
  • 人工智能

【免费下载链接】mcp-for-beginners

This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.

项目地址:https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners
点击查看免费下载

本篇文章围绕本仓库「06-http-streaming」章节中的 .NET 解决方案展开,完整讲解如何基于 Model Context Protocol(MCP)的Streamable HTTP传输方式构建、启动并测试一个 .NET MCP 服务器。你将掌握从dotnet restore恢复依赖、dotnet run启动服务,到使用官方 MCP Inspector 在浏览器与 CLI 两种模式下验证工具(tools)与资源(resources)的完整实战链路,并深入理解Program.cs、Tools.cs等源码背后的实现原理。

一、背景:为什么选择 Streamable HTTP

在 MCP 生态中,传输机制(Transport)决定了客户端与服务器之间数据的交换方式。本仓库 06-http-streaming 章节 README 给出了三种主流传输的对比:

Transport状态通知支持典型用途
stdio当前是本地子进程
HTTP+SSE已弃用是遗留远程实现
Streamable HTTP当前是远程与云端服务器

其中Streamable HTTP是现代的 HTTP 流式传输方式,支持通知机制与更好的可扩展性,被推荐用于大多数生产环境和云场景;而 HTTP+SSE 已在 MCP2025-03-26中被标记为弃用,不建议新实现使用。标准传输是 stdio 与 Streamable HTTP 两种,HTTP+SSE 只出现在旧示例中。

本篇文章聚焦的 .NET 示例 正是 Streamable HTTP 的落地实现,其核心价值在于:只需要一个可复制的 .NET 工程,就能演示如何用 ASP.NET Core 承载 MCP 服务器,并通过localhost:3001/mcp端点对外提供工具调用能力。

[!WARNING] 本示例面向 MCP 规范2025-11-25的 Streamable HTTP 实现方式。在 MCP2026-07-28规范中,请求改为自包含的 POST 请求并携带MCP-Protocol-Version、Mcp-Method等头部。在新实现中使用本示例前,请先阅读 MCP 2026-07-28 规范变更说明。

二、.NET 示例工程结构一览

示例位于 03-GettingStarted/06-http-streaming/solution/dotnet/,共包含 6 个文件:

文件作用
Program.cs服务器入口,注册 MCP Server 与 HTTP 传输
Tools.cs定义 MCP 工具(AddNumbers)
server.csproj项目文件,声明ModelContextProtocol.AspNetCore依赖
server.sln解决方案文件
Properties/launchSettings.json启动配置,定义端口与启动 profile
README.md示例运行与测试说明(英文原文)

2.1 服务器入口:Program.cs

Program.cs 的核心代码如下:

using server; var builder = WebApplication.CreateBuilder(args); builder.Services .AddMcpServer() .WithHttpTransport(o => o.Stateless = true) .WithTools<Tools>(); builder.Services.AddHttpClient(); var app = builder.Build(); app.MapMcp("/mcp"); app.Run();

关键点逐一解读:

  • AddMcpServer():向依赖注入容器注册 MCP 服务器服务;
  • WithHttpTransport(o => o.Stateless = true):启用Streamable HTTP传输,并配置为无状态(Stateless)模式。无状态意味着服务器不维护跨请求的会话状态,每次请求自包含,这符合 MCP2026-07-28之后「请求自包含」的趋势,也更适合水平扩展;
  • WithTools<Tools>():把Tools类型中的 MCP 工具注册到服务器;
  • app.MapMcp("/mcp"):把 MCP 端点映射到路由/mcp,即最终的访问地址为http://localhost:3001/mcp。

2.2 工具定义:Tools.cs

Tools.cs 定义了一个最简单的加法工具:

using System.ComponentModel; using ModelContextProtocol.Server; namespace server; [McpServerToolType] public sealed class Tools { [McpServerTool, Description("Add two numbers together.")] public async Task<string> AddNumbers( [Description("The first number")] int a, [Description("The second number")] int b) { return await Task.FromResult((a + b).ToString()); } }
  • [McpServerToolType]标记该类型为 MCP 工具容器;
  • [McpServerTool]+[Description]声明工具及其人类可读描述,描述会被自动携带进工具的inputSchema,供 LLM/Agent 理解参数含义;
  • 参数a、b各自带[Description],这些注解会映射为 JSON Schema 中properties的description字段(后续在 Inspector 输出中可以直接看到);
  • 方法返回Task<string>,结果是两个整数相加的字符串。

2.3 项目文件:server.csproj

server.csproj 使用Microsoft.NET.Sdk.WebSDK,目标框架为net9.0,并启用了PublishAot(原生 AOT 发布支持)。唯一的关键依赖是官方 MCP 包:

<PackageReference Include="ModelContextProtocol.AspNetCore" Version="0.*-*" />

0.*-*是一个通配版本声明,表示采用可用的最新 0.x 预发布版本,方便跟随 MCP SDK 演进。

2.4 启动配置:launchSettings.json

Properties/launchSettings.json 定义了两种 profile:

  • http:applicationUrl为http://localhost:3001;
  • https:applicationUrl为https://localhost:7133;http://localhost:3001。

也就是说,HTTP profile 下服务监听3001 端口,这与测试阶段 MCP Inspector 的访问地址http://localhost:3001完全对应。

三、安装依赖并启动服务器

第 1 步:安装依赖

在示例目录下执行:

dotnet restore

该命令会根据server.csproj中的PackageReference从 NuGet 恢复ModelContextProtocol.AspNetCore等依赖包。

第 2 步:启动示例

dotnet run

启动成功后,服务器会通过 Streamable HTTP 传输监听http://localhost:3001/mcp端点。请保持该终端持续运行,以便下一步进行测试。

四、使用 MCP Inspector 测试(浏览器模式)

在服务器运行于一个终端的同时,打开另一个终端执行:

npx @modelcontextprotocol/inspector http://localhost:3001

该命令会启动一个带可视化界面的 Web 服务器,让你以图形化方式测试示例。

务必确认在 Inspector 界面中将传输类型(Transport)选择为Streamable HTTP,并将 URL 设置为http://localhost:3001/mcp(注意包含/mcp路径)。

服务器连接成功之后,可以进行两类验证:

  • 工具(Tools):列出工具,然后调用add,传入参数 2 和 4,应当得到结果6;
  • 资源(Resources)与资源模板(Resource Templates):调用名为greeting的资源模板,输入一个名字,应当返回带有该名字的问候语。

五、CLI 模式测试:更快、更脚本化

浏览器界面适合交互式探索,而在 CLI 模式下运行 Inspector 通常要快得多,也更容易集成到自动化脚本或 CI 流程中。

5.1 列出服务器上所有工具

npx @modelcontextprotocol/inspector --cli http://localhost:3001 --method tools/list

这条命令会列出服务器上所有可用工具,预期输出如下:

{ "tools": [ { "name": "AddNumbers", "description": "Add two numbers together.", "inputSchema": { "type": "object", "properties": { "a": { "description": "The first number", "type": "integer" }, "b": { "description": "The second number", "type": "integer" } }, "title": "AddNumbers", "description": "Add two numbers together.", "required": [ "a", "b" ] } } ] }

可以对照发现:这个 JSON Schema 中的工具名AddNumbers、描述 "Add two numbers together."、参数a/b及各自的描述,正是 Tools.cs 中[McpServerTool]、[Description]注解自动生成的,这直观体现了「属性注解 → 工具 Schema 暴露」的映射链路。

5.2 调用工具

npx @modelcontextprotocol/inspector --cli http://localhost:3001 --method tools/call --tool-name AddNumbers --tool-arg a=1 --tool-arg b=2

预期输出:

{ "content": [ { "type": "text", "text": "3" } ], "isError": false }

isError: false表示调用成功,text: "3"即1 + 2的结果,与 Tools.cs 中(a + b).ToString()的实现完全一致。

5.3 CLI 模式小结

命令片段含义
--cli以命令行模式运行,不启动浏览器界面
--method tools/list请求tools/list方法,列出工具
--method tools/call请求tools/call方法,调用工具
--tool-name AddNumbers指定要调用的工具名
--tool-arg a=1为参数a传值1(可重复使用以传递多个参数)

六、源码级深化:从示例到生产实践的启示

6.1 无状态模式与水平扩展

WithHttpTransport(o => o.Stateless = true)是本示例最具工程价值的配置。在无状态模式下,服务器不需要维护Mcp-Session-Id之类的会话信息,每个 HTTP 请求都独立可处理。这意味着:

  • 服务器可以轻松部署到无状态容器中,配合负载均衡进行水平扩展;
  • 请求失败重试时无需担心会话丢失;
  • 与 MCP 规范向「自包含请求」演进的趋势一致。

从源码结构看,Program.cs 把「MCP 服务注册」「HTTP 传输配置」「工具装配」放在三行链式调用中完成,职责清晰、易于扩展——新增工具只需在Tools类中追加带[McpServerTool]的方法,无需改动启动逻辑。

6.2 工具定义的最佳实践

Tools.cs 展示了 MCP 工具定义的两个最佳实践:

  1. 为工具和每个参数提供[Description]:这些描述会进入工具暴露的inputSchema,是 LLM/Agent 正确选择与调用工具的关键元数据;
  2. 参数类型尽量明确(int):明确的类型会让生成出的 JSON Schema 更精确("type": "integer"且自动加入required),减少客户端传参歧义。

6.3 与同章节其他语言实现的呼应

同一章节还提供了 Python 实现、Java 实现、Rust 实现 以及总览性的 solution/README.md。以 Python 为例,其 server.py 与 .NET 版遵循同一套 Streamable HTTP 语义:服务器暴露/mcp端点、提供AddNumbers工具与greeting资源模板,客户端则通过streamablehttp_client建立会话。这种跨语言的同构设计正是本仓库「同一实战、五种语言」课程理念的体现——掌握本篇文章的 .NET 实现后,你可以无障碍地对照阅读其他语言版本。

七、进一步阅读

  • 章节完整讲解(传输机制对比、通知实现、SSE 迁移、安全注意事项):06-http-streaming 章节 README
  • MCP 规范2026-07-28变更说明:01-CoreConcepts/mcp-2026-07-28.md
  • 基础概念与核心架构:01-CoreConcepts/README.md
  • 下一个章节(Microsoft Foundry Toolkit for VS Code):07-aitk/README.md
  • 教程
  • 文档
  • 人工智能

【免费下载链接】mcp-for-beginners

This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.

项目地址:https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners
点击查看免费下载

相关推荐

上一篇:FanControl终极指南:Windows风扇智能控制完整教程
下一篇:告别臃肿:G-Helper如何让华硕笔记本性能控制变得更简单高效

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

Linux进程生命周期全解:从task_struct到fork、僵尸进程与资源回收

如果你写过 Linux 下的多进程程序&#xff0c;或者在线上环境排查过“进程不见了”“进程卡死了”“怎么又多了一堆 Z 状态的东西”这类问题&#xff0c;那你一定绕不开今天要聊的这套东西&#xff1a;进程描述符、进程的产生、进程的消亡和释放。这是 Linux 系统编程最底层的骨…

作者头像 李华
网站建设 2026/10/7 2:33:36

Java+MySQL科研管理系统开发实战:从数据库到GUI完整落地

又到了写课设、毕设和内部小工具的高峰期&#xff0c;群里每天都会有人问“基于JavaMySQL实现&#xff08;GUI&#xff09;某高校科研管理系统”这类题该怎么做。说句实话&#xff0c;这个题目涉及的技术本身都不难&#xff1a;Java做客户端、MySQL存数据、Swing或JavaFX搭界面…

作者头像 李华
网站建设 2026/10/7 2:32:47

RK3588触摸屏开发到YOLOv8部署:嵌入式AI完整实战指南

做RK3588触摸屏开发这几年&#xff0c;我最大的感受是&#xff1a;网上资料多而杂&#xff0c;真正能一口气把从硬件点亮到AI应用跑通的完整链路讲清楚的内容&#xff0c;太少了。很多朋友板子买回来&#xff0c;第一步就卡在屏幕不亮、触摸没反应上&#xff0c;更别提后面还要…

作者头像 李华
网站建设 2026/10/7 2:32:31

文件学习:从杂乱无章到个人知识库的高效整理方法论

不知道你有没有这种经历&#xff1a;硬盘里攒了多年的文件&#xff0c;平时谁都想不起来&#xff0c;需要用的时候死活找不到&#xff0c;只能凭记忆一层层翻文件夹&#xff0c;最后实在不行重新做一份。更气人的是&#xff0c;刚整理完的桌面和文件夹&#xff0c;过两周又变得…

作者头像 李华
网站建设 2026/10/7 2:32:07

DeepEval LLM 评估:5 分钟跑通首次评估并接入 CI

DeepEval LLM 评估&#xff1a;5 分钟跑通首次评估并接入 CI 【免费下载链接】deepeval The LLM Evaluation Framework 项目地址: https://gitcode.com/GitHub_Trending/de/deepeval DeepEval 是一个开源的 LLM 评估框架&#xff0c;用"LLM 当法官"的方式给模…

作者头像 李华