多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

使用 C 与 Model Context Protocol 构建基础计算器 MCP Server:从 stdio 配置到 Docker 容器化部署

使用 C 与 Model Context Protocol 构建基础计算器 MCP Server:从 stdio 配置到 Docker 容器化部署 教程文档人工智能【免费下载链接】mcp-for-beginnersThis 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点击查看免费下载本指南以仓库 03-GettingStarted/samples/csharp 中的 .NET 计算器示例为主体完整讲解如何用 C# 编写一个基于stdio传输的 MCP Server、在 VS Code 中通过.vscode/mcp.json注册并接入 GitHub Copilot Chat以及如何将同一服务打包为 Docker 镜像实现跨环境复用。读完本文你将掌握 MCP Server 的工具声明机制、stdio配置语法、#MyCalculator提示词调用技巧以及docker run --rm -i这种容器化 MCP 服务的标准运行方式为后续在 03-GettingStarted 中继续编写 MCP 客户端、接入 LLM 客户端打下基础。为什么用“计算器”作为 MCP 入门示例MCPModel Context Protocol是连接 LLM 与外部工具、数据源的标准开放协议。在 03-GettingStarted/README.md 中它被形象地比喻为“AI 应用的 USB-C 接口”它定义了一套标准化的方式让 AI 模型能够连接不同的数据源和工具。入门阶段选择计算器有两个现实原因逻辑简单、边界清晰加减乘除与素数判断的输入输出都是纯数值方便初学者聚焦于 MCP 的“工具注册—传输—调用”链路而不是业务复杂度。跨语言对照友好仓库在 03-GettingStarted/samples 下提供了 Java、JavaScript、TypeScript、Python 与 C# 等五种语言的同款计算器示例便于横向比对各语言 SDK 的异同。该示例在整个学习路径中扮演“第一个可运行的 MCP Server”的角色后续课程如编写客户端、接入 LLM、测试与部署都建立在这种最小可运行模型之上。项目结构与源码解析仓库中 C# 计算器示例的完整布局如下03-GettingStarted/samples/csharp/ ├── README.md # 英文原版说明本指南翻译自其丹麦语译本 ├── csharp.sln # Visual Studio 解决方案文件 └── src/ ├── calculator.csproj # .NET 9 项目文件 ├── Program.cs # 宿主程序注册 MCP Server 与 stdio 传输 ├── McpCalculatorServer.cs # 工具实现5 个计算工具 └── Dockerfile # 容器化构建脚本项目文件与依赖calculator.csprojcalculator.csproj 是一个面向 .NET 9 的普通控制台项目仅依赖两个 NuGet 包Project SdkMicrosoft.NET.Sdk PropertyGroup OutputTypeExe/OutputType TargetFrameworknet9.0/TargetFramework ImplicitUsingsenable/ImplicitUsings Nullableenable/Nullable /PropertyGroup ItemGroup PackageReference IncludeMicrosoft.Extensions.Hosting Version9.* / PackageReference IncludeModelContextProtocol Version0.*-* / /ItemGroup /Project其中ModelContextProtocol是官方 C# SDK与微软合作维护详见 03-GettingStarted/README.md 中的 SDK 列表而Microsoft.Extensions.Hosting提供通用主机与依赖注入容器。注意项目使用Version0.*-*的通配版本号实际生效版本取决于还原时获取到的具体包版本仓库在 03-GettingStarted/README.md 中也提醒不同语言的 SDK 对 MCP2026-07-28规范的支持是独立推进的运行示例前应核对包版本与 SDK 发布说明。宿主入口Program.csProgram.cs 只有 15 行却完成了 MCP Server 的三件核心工作using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; var builder Host.CreateApplicationBuilder(args); builder.Logging.AddConsole(consoleLogOptions { // 将所有日志输出到 stderr consoleLogOptions.LogToStandardErrorThreshold LogLevel.Trace; }); builder.Services .AddMcpServer() .WithStdioServerTransport() .WithToolsFromAssembly(); await builder.Build().RunAsync();三个关键点的原理日志全部走 stderrLogToStandardErrorThreshold LogLevel.Trace将所有级别的日志定向到标准错误流。这是 stdio 传输的硬性要求——stdout 被保留给 MCP 的 JSON-RPC 协议消息任何杂散输出都会破坏协议帧因此日志必须与协议数据分离。AddMcpServer()WithStdioServerTransport()注册 MCP Server 服务并选用标准输入输出stdio传输。stdio 是本地 MCP 通信的推荐标准宿主如 VS Code、Claude Desktop以子进程方式启动服务器提供内置的进程隔离是 03-GettingStarted/README.md 中第 5 课专门展开的主题。WithToolsFromAssembly()自动扫描当前程序集把所有标注了[McpServerTool]特性的方法注册为 MCP 工具无需逐一手写注册代码。工具实现McpCalculatorServer.csMcpCalculatorServer.cs 用声明式特性把普通静态方法变成 MCP 工具[McpServerToolType] public static class McpCalculatorServer { [McpServerTool, Description(Calculates the sum of two numbers)] public static double Add(double numberA, double numberB) { return numberA numberB; } // Subtract / Multiply 同理 [McpServerTool, Description(Calculates the quotient of two numbers)] public static double Divide(double numberA, double numberB) { if (numberB 0) { throw new ArgumentException(Cannot divide by zero); } return numberA / numberB; } [McpServerTool, Description(Validates if a number is prime)] public static bool IsPrime(long number) { if (number 1) return false; if (number 3) return true; if (number % 2 0 || number % 3 0) return false; // 使用 6k±1 优化检查整除性 for (long i 5; i * i number; i 6) { if (number % i 0 || number % (i 2) 0) { return false; } } return true; } }值得注意的实现细节Description即工具 Schema每个[McpServerTool]方法上的Description特性会直接成为 MCP 协议中工具描述信息帮助 LLM 判断“这个工具是干什么的、该不该调用”因此描述越清晰Agent 调用准确率越高。除零防护Divide在除数为 0 时抛出ArgumentException异常会作为工具调用错误回传给宿主。IsPrime使用 6k±1 优化跳过 2、3 的倍数只需检查到√n为止时间复杂度为 O(√n)是判断素数的高效写法。在 VS Code 中配置 stdio 类型 MCP 服务器原文文档明确采用stdio 类型Using stdio Type配置方式步骤如下在 VS Code 中打开你的工作区。在工作区根目录创建.vscode/mcp.json文件用于配置 MCP 服务器。完整配置如下{ inputs: [ { type: promptString, id: repository-root, description: The absolute path to the repository root } ], servers: { calculator-mcp-dotnet: { type: stdio, command: dotnet, args: [ run, --project, ${input:repository-root}/03-GettingStarted/samples/csharp/src/calculator.csproj ] } } }配置要点inputs变量提示VS Code 在首次加载配置时会弹出提示让你输入repository-root的值即仓库根目录的绝对路径。type: stdio声明这是一个通过标准输入输出通信的本地服务器。commandargs宿主以dotnet run --project 路径/03-GettingStarted/samples/csharp/src/calculator.csproj的方式启动子进程dotnet run会自行还原依赖并编译运行因此只要本机装有 .NET SDK 即可。获取仓库根路径在终端执行git rev-parse --show-toplevel即可得到当前 Git 仓库的绝对根路径填入上述提示即可。服务暴露的 MCP 工具端点配置完成后计算器服务通过 MCP 协议暴露以下工具即 API 端点工具签名说明addadd(a, b)两个数相加subtractsubtract(a, b)第一个数减去第二个数multiplymultiply(a, b)两个数相乘dividedivide(a, b)第一个数除以第二个数含除零检查isPrimeisPrime(n)判断一个数是否为素数这些工具对应 McpCalculatorServer.cs 中的Add、Subtract、Multiply、Divide、IsPrime五个方法。实际调用时无需关心类型细节——例如IsPrime的参数在 C# 中是long而 MCP 协议层会自动完成 JSON 数值的序列化与类型转换。使用 GitHub Copilot Chat 测试服务配置完成后可以在 VS Code 的 GitHub Copilot Chat 中直接用自然语言向服务发起请求。原文建议的测试用语如下“Add 5 and 3”5 加 3“Subtract 10 from 4”4 减 10“Multiply 6 and 7”6 乘 7“Divide 8 by 2”8 除以 2“Does 37854 prime?”37854 是素数吗“What are the 3 prime numbers before after 4242?”4242 前后的 3 个素数是什么让 Copilot 明确使用工具的技巧在提示词末尾追加#MyCalculator即服务器在.vscode/mcp.json中注册的服务器名称前加#强制 Copilot 优先调用该 MCP Server 的工具例如“Add 5 and 3 #MyCalculator”“Subtract 10 from 4 #MyCalculator”注意#后的名称必须与你配置中的服务器 key 完全一致。如果沿用仓库默认配置服务器名为calculator-mcp-dotnet则提示词应写#calculator-mcp-dotnet若你改名为MyCalculator等则相应调整。Docker 容器化版本跨环境复用前面基于dotnet run的方案要求本机安装 .NET SDK 且依赖齐全适合个人开发。但如果想分享解决方案或在其他环境运行就需要使用容器化版本——把运行环境与依赖一并打包进 Docker 镜像。Dockerfile 解析仓库自带的 Dockerfile 采用标准的两阶段构建# 构建阶段使用官方 .NET SDK 镜像 FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build WORKDIR /src COPY [calculator.csproj, ./] RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app/publish # 运行阶段使用精简运行时镜像 FROM mcr.microsoft.com/dotnet/runtime:9.0 AS runtime WORKDIR /app COPY --frombuild /app/publish . ENTRYPOINT [dotnet, calculator.dll] # 为 MCP stdio 通信配置容器 ENV DOTNET_RUNNING_IN_CONTAINERtrue ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT1设计要点两阶段构建第一阶段用带 SDK 的镜像完成restorepublish第二阶段仅拷贝发布产物到轻量的runtime镜像最终镜像体积更小。ENTRYPOINT [dotnet, calculator.dll]容器启动即运行计算器程序等待从 stdin 读取 MCP 消息。两个环境变量DOTNET_RUNNING_IN_CONTAINERtrue告知 .NET 运行时处于容器环境DOTNET_SYSTEM_GLOBALIZATION_INVARIANT1使用不变区域设置避免依赖 ICU 库从而保持镜像精简。构建并推送镜像按照原文步骤在 Docker 运行时执行启动 Docker 并确保其正常运行。在终端中进入目录03-GettingStarted/samples/csharp/src。构建计算器服务的 Docker 镜像将YOUR-DOCKER-USERNAME替换为你的 Docker Hub 用户名docker build -t YOUR-DOCKER-USERNAME/mcp-calculator .镜像构建完成后上传到 Docker Hubdocker push YOUR-DOCKER-USERNAME/mcp-calculator用 Docker 镜像替换 MCP 服务器配置在.vscode/mcp.json中将原来的服务器配置替换为mcp-calculator: { command: docker, args: [ run, --rm, -i, YOUR-DOCKER-USERNAME/mcp-calculator ], envFile: , env: {} }逐项解读启动命令docker run --rm -i YOUR-DOCKER-USERNAME/mcp-calculatordocker宿主直接以 docker CLI 作为 MCP 进程启动命令。run --rm -i--rm保证容器停止后即被自动删除不留垃圾容器-i保持容器标准输入打开允许宿主与容器内的 MCP Server 交互stdio 通信的关键前提。YOUR-DOCKER-USERNAME/mcp-calculator最后一项是刚构建并推送到 Docker Hub 的镜像名。envFile/env留空表示不需要额外的环境变量注入如需注入密钥等可在此补充。验证容器化版本配置完成后点击.vscode/mcp.json中mcp-calculator: {上方的小型Start按钮启动 MCP 服务器。启动成功后即可像之前一样用自然语言让计算器服务执行数学计算。由于该版本不依赖本机 .NET SDK可以轻松分享给团队或在 CI/云端环境复用。常见问题与排查建议结合源码与配置实践整理几个常见问题服务启动但工具不出现检查.vscode/mcp.json中的服务器名key与你追加到提示词#后的名称是否一致检查command/args路径是否正确仓库根路径务必使用git rev-parse --show-toplevel的实际输出。协议消息被污染Program.cs已将日志定向到 stderr若你在自己的实现中往 stdout 打印内容会破坏 stdio 的 JSON-RPC 帧务必保持 stdout 纯净。除零报错Divide对除数为 0 抛出ArgumentException这是预期行为应让 LLM 在提示词中给出非零除数或在调用层捕获该错误。Docker 版本无法交互确认docker run参数包含-i缺失该参数时容器 stdin 未连接stdio 传输将无法工作。版本兼容性ModelContextProtocol采用0.*-*通配版本若出现协议不兼容错误请核对具体还原到的 SDK 版本与 MCP2026-07-28规范的对应关系参考 03-GettingStarted/README.md 的 SDK 说明。延伸学习本示例属于 03-GettingStarted 第 1 课“你的第一个服务器”的配套样例该课还演示如何用 MCP Inspector 测试与调试服务器。下一步可学习第 2 课“客户端”用 C# 编写连接本服务器的 MCP 客户端第 3 课“带 LLM 的客户端”则展示如何让 LLM 与服务器“协商”任务。若想深入 stdio 传输的进程隔离与通信机制参见第 5 课 05-stdio-server。仓库还提供 Java、JavaScript、TypeScript、Python 的同款计算器样例见 03-GettingStarted/samples 目录适合横向学习跨语言 MCP 开发。赞分享教程文档人工智能【免费下载链接】mcp-for-beginnersThis 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点击查看免费下载相关推荐MCP-for-Beginners 实战用 C 构建基础计算器 MCP 服务从 stdio 配置到 Docker 容器化部署MCP for Beginners 实战用 C 构建基础计算器 MCP 服务从 stdio 配置到 Docker 容器化部署 本篇技术指南以 mcp for教程文档人工智能用 C 构建你的第一个 MCP 计算器服务器从 stdio 配置到 Docker 容器化部署用 C 构建你的第一个 MCP 计算器服务器从 stdio 配置到 Docker 容器化部署 本篇技术指南以 mcp for beginners 开源课程中教程文档人工智能基于 .NET 与 stdio 传输构建 C 计算器 MCP 服务器从 VS Code 配置到 Docker 容器化实战基于 .NET 与 stdio 传输构建 C 计算器 MCP 服务器从 VS Code 配置到 Docker 容器化实战 导读 本文以本仓库 03 Getti教程文档人工智能上一篇useEffectReducer单元测试策略确保你的状态管理代码可靠无误下一篇Claude Code Action:10分钟配好 GitHub Action 自动化 PR 审查的完整流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表