让AI直接调用.NET接口:MCP服务端与客户端落地实战

发布时间:2026/9/24 20:14:35
让AI直接调用.NET接口:MCP服务端与客户端落地实战 让 AI 直接调你的 .NET 接口MCP 服务端与客户端落地实战先说我为什么会折腾这个事儿。前阵子团队里老有人抱怨AI 写代码再强也只是一块高级键盘它看不到我们系统的真实数据。你问它这个订单是什么状态它只能瞎猜因为它连数据库在哪儿都不知道。那时候我们内部数据接口其实已经很全了订单、库存、权限、配置都有现成的 API但 AI 用不上——它没有手没法点接口、填参数、看返回。后来 MCP 这词儿在各个技术社区刷屏我用 .NET 折腾了一周把公司内部几个核心接口暴露给 AI 客户端直接调用效果比想象中直接AI 不再是纸上谈兵而是真的能查订单、改配置、跑统计。这篇就是完整的落地过程服务端和客户端两边都有适合手里有 .NET 接口、想让 AI Agent 直接调用的人参考。1. 为什么需要 MCPAI 与你的接口之间缺一条数据高速公路MCPModel Context Protocol模型上下文协议本质上就是一个标准化通道让 AI 模型能够发现外部工具、调用外部工具、读取外部资源。听起来很玄乎但拆开就三层东西AI 端、协议层、你现有的服务。协议层定义了一套 JSON-RPC 格式的消息AI 端通过这些消息知道你暴露了哪些工具、每个工具接受什么参数、返回什么结构。用大白话说MCP 就是给 AI 装了一双可以操作你系统的手。1.1 大模型的能力边界只会说不会做得先承认一个事实大模型本身是离线的。它训练完之后世界里的一切对它来说都是不可见的。你说帮我查一下订单 1024 的状态它只能凭训练数据里的零散知识给你编一个答案编错了它自己都不知道。这在大模型圈叫幻觉但根子上是因为它没有访问你系统的通道。你要么把数据贴进 Prompt 里要么让它写一段代码由人去执行——前者受限于上下文窗口后者倒是常见但每一次人机交互都停在这一步人复制、人粘贴、人执行、人把结果贴回去。效率极低而且中间任何一步看错、漏选结果就差之千里。我之前用过的伪方案是搞一个函数调用Function Calling接口把工具描述和参数 JSON Schema 发给大模型模型返回一个结构化的调用意图再由后端代码手动分发。这套东西能跑但每个业务都要单独写一段分发逻辑加一个工具就要改一遍后端代码。时间一久工具多了以后那堆 if/switch 简直像一盘散线谁都不敢动。1.2 MCP 协议说到底在解决什么问题MCP 解决的恰恰是这个散字。它把工具注册、参数发现、调用分发、结果回传全部标准化走同一条 JSON-RPC 通道。AI 端客户端启动时向服务端发一条tools/list拿到全部工具清单和参数说明需要调用时发tools/call带着工具名和参数服务端执行完把结构化结果返回。不需要为每个接口写专门的胶水代码协议层搞定一切。这就像你去餐厅吃饭不用每家店的厨房都重新学一遍怎么做菜只需要看懂菜单、会跟服务员点单就行。菜单就是tools/list点单就是tools/call上菜就是返回结果。MCP 做的就是把每一家餐厅都统一成同一个点单流程。1.3 一个真实场景让 AI 直接查订单、改配置我们这边最有价值的一个落地场景是内部运营平台的订单问答。运营同事经常会问最近 7 天退款率是多少订单 XX 的物流单号是什么把商品 X 的库存预警阈值改成 50这类问题。以前要么技术同学帮着写 SQL要么运营自己打开后台一顿找。MCP 接好之后运营直接在 AI 聊天窗口里用自然语言提问AI 客户端调用 MCP 服务端暴露的 QueryOrder、QueryRefundRate、UpdateStockThreshold 等工具把参数提取出来调用 .NET 接口再把真实结果组织成自然语言回复。整个过程中AI 不需要记住任何业务数据它只负责把你的口语翻译成参数、把返回结果翻译回口语。数据永远来自你真实的接口不会存在模型幻觉里。这一点至关重要MCP 不是让 AI 变成一个业务专家而是让 AI 变成一个懂接口的翻译官它负责沟通不负责编造。2. 落地前的选型.NET 下的 MCP 服务端该用什么姿势想清楚了要干什么下一步就是选型。MCP 的 .NET 生态相比 Python 和 TypeScript 要年轻一些但现在已经可以稳定用了。核心有两条路一是基于官方 SDKModelContextProtocol 包快速搭建二是自己撸协议。我强烈建议走官方 SDK除非你有特殊诉求比如要支持一些奇怪的自定义传输。2.1 官方 SDK 与自己写协议的对比我最早看 MCP 规范文档时第一反应是这协议不复杂不就 JSON-RPC 嘛自己解析消息再分发给业务方法就行。真动手才发现坑不少协议版本协商、会话初始化、能力声明、分页、错误码还有 JSON-RPC 中initialize和notifications/initialized的时序要求自己实现容易漏掉边界情况。官方 SDK 把这些封装好了你只需要写工具类SDK 负责协议细节。用 .NET 官方 SDK 的好处有三点工具描述自动生成你用特性标注一个方法SDK 会把方法的 XML 注释、参数模型转换成 JSON Schema不需要手动维护工具描述文档。传输层可插拔stdio 和 HTTP/SSE 的切换就是个配置项不用改业务代码。生命周期管理完善SDK 自己处理客户端的连接状态、初始化超时和断线重连不用自己造轮子。2.2 传输方式选择stdio 还是 HTTP/SSEMCP 目前主流的两种传输方式是 stdio 和 Streamable HTTP以前叫 HTTP/SSE。理解它们的区别很重要维度stdioStreamable HTTP适用场景本地进程间通信AI 工具以子进程方式启动远程服务多客户端共享访问网络开销低走标准输入输出流高走 HTTP 请求服务端形态控制台程序随客户端启动ASP.NET Core Web API调试方式较难需要看日志方便浏览器和 curl 都能测鉴权不需要天然本地需要要考虑 Token、API Key典型用户Claude Desktop、本地 Agent多租户后台、团队共享机器人我自己的建议是如果你的 AI 客户端和接口服务在同一台机器或者你只是在开发阶段直接用 stdio省去鉴权和网络的麻烦。但如果你要做一个团队共享的服务让多个 AI Agent、多个运营同时连那就必须走 HTTP 模式把 MCP 服务挂到 ASP.NET Core 上。我这回落地的是内网运营平台团队十几个人都可能用所以选的是 Streamable HTTP 模式用 ASP.NET Core 承载。2.3 开发环境准备与版本踩坑环境方面我用的 .NET 8LTS 版本稳定优先IDE 是 Rider也可以用 VS 2022 或者 VS Code。需要用到的包ModelContextProtocol.AspNetCoreASP.NET Core 集成的主包ModelContextProtocol核心协议库一般会被上面那个包带进来不用单独加我在刚上手时踩过一个版本坑直接 install 最新版的时候不小心装到了 Preview 版本跑起来和 IDE 的 MCP 客户端插件兼容性有些问题插件握手总是失败。后来锁定稳定版装的时候不加--prerelease或者直接指定版本号马上就通了。这里建议你就用 NuGet 上的最新稳定版最好在本地先跑一个最简单的 HelloWorld 确认链路通再往里面加业务工具。别一上来就接一堆真实接口否则出了问题都不知道是协议不行还是业务代码出岔子。3. 服务端实战把普通接口暴露成 MCP 工具选型定了开始写服务端。这边我尽量按实际顺序来每一步都给代码和关键解释。3.1 创建项目与引入依赖我用的是 ASP.NET Core Web API 模板目标框架 net8.0。创建完项目以后在 csproj 里加包引用Project SdkMicrosoft.NET.Sdk.Web PropertyGroup TargetFrameworknet8.0/TargetFramework Nullableenable/Nullable ImplicitUsingsenable/ImplicitUsings /PropertyGroup ItemGroup PackageReference IncludeModelContextProtocol.AspNetCore Version0.7.0 / PackageReference IncludeMicrosoft.Extensions.AI Version9.0.0 / /ItemGroup /Project注意版本号是随官方迭代变的我写的是一个稳定版本示例你装的时候以 NuGet 上的最新稳定版为准。Microsoft.Extensions.AI不是必须的但如果你希望 MCP 工具内部还能再调用小模型做数据格式化这个包会很有用。Program.cs 里注册服务using ModelContextProtocol.AspNetCore; var builder WebApplication.CreateBuilder(args); builder.Services.AddMcpServer() .WithToolsOrderTools() .WithToolsStockTools(); var app builder.Build(); app.MapMcp(); app.Run();这段代码做的事情非常核心AddMcpServer()注册 MCP 服务端运行时WithToolsT()把指定类型里的公开方法暴露为 MCP 工具MapMcp()把 MCP 的 HTTP 端点映射到路由表。默认情况下MCP 端点会被映射到/mcp路径客户端连接地址就是http(s)://你的主机:端口/mcp。3.2 用特性定义工具从查天气到查订单工具是 MCP 服务端的核心能力。一个工具就是你的 .NET 类里的一个公开方法。我们用特性标注它SDK 自动帮我们生成协议描述。先看一个最简单的工具——获取订单信息using ModelContextProtocol; using System.ComponentModel; using System.ComponentModel.DataAnnotations; public class OrderTools { public record QueryOrderRequest( [property: Required, Description(订单号)] string OrderNo); public record QueryOrderResponse( string OrderNo, string Status, decimal Amount, string CustomerName, string CreatedAt); [McpServerTool(Description 根据订单号查询订单详情)] public static async TaskQueryOrderResponse QueryOrder( [Required, Description(订单号)] string orderNo, CancellationToken cancellationToken) { // 这里调用你已有的订单接口或数据库 await Task.Delay(10, cancellationToken); return new QueryOrderResponse( OrderNo: orderNo, Status: 已发货, Amount: 299.00m, CustomerName: 张三, CreatedAt: 2025-06-01 10:30:00 ); } }关键点拆解一下[McpServerTool]告诉 SDK 这是一个 MCP 工具括号里的Description会作为工具描述发给 AI 模型。这段描述很重要AI 靠它判断什么时候用这个工具。参数上的[Required]和[Description]会映射到 JSON SchemaAI 能据此生成正确的参数。返回类型可以用一个 record 或普通类SDK 会把它序列化成 JSON 返回给客户端。方法可以接受CancellationToken如果客户端断开服务端能及时取消后面的耗时操作。一个服务端可以挂多个工具类比如 OrderTools、StockTools、ConfigTools用WithToolsT()一个个注册进去。工具名默认是方法名比如QueryOrder如果你想显式指定工具名可以用[McpServerTool(Name query_order)]这种写法。实际在我们内部我直接复用了现有的仓储层代码工具方法里调用IOrderRepository.GetByOrderNoAsync(orderNo)之类的厚重业务方法而不是像演示代码里写死返回。这样做的好处是 AI 拿到的数据和你现有系统完全一致不会出现AI 说已发货但系统实际是退款中这种两头对不上的情况。3.3 通过资源Resources暴露只读数据工具适合有参数、会触发动作的场景比如查订单、改配置。但 AI 有时候也需要一些背景资料比如业务术语表、接口调用规范、当前的促销活动列表。这类数据不适合做成工具去调用更适合以只读资源的形式挂给 AI让它在对话时自动获取。MCP 里的资源Resources就是干这个的。实现一个资源在 .NET SDK 里也很直接using ModelContextProtocol; public class SystemResources { [McpServerResource(Description 获取当前可售商品分类清单)] public static async Taskstring GetCategoryList(CancellationToken cancellationToken) { // 从缓存或数据库读取分类 return await Task.FromResult([ \手机数码\,\家用电器\,\食品生鲜\,\服饰鞋包\ ]); } }资源跟工具的区别在于资源没有或者很少参数返回的是纯文本或结构化数据主要用来帮 AI 理解业务的上下文。拿人打比方工具是手资源是眼睛和耳朵。AI 在接到复杂任务时会通过resources/read来看一眼系统提供的上下文然后决定下一步怎么调工具。我把公司内部常用的业务口径比如退款率 退款订单数 / 支付订单数放到资源里AI 在回答财务类问题时就不会用错公式。这个收益非常直接等于给 AI 做了个上岗培训。3.4 启用日志观察服务端行为接真实接口前务必把日志打开。MCP 服务端就像一个黑盒你有日志才知道 AI 到底调了哪个工具、传了哪些参数、花了多久。我用的是 ASP.NET Core 自带的日志builder.Logging.AddConsole().SetMinimumLevel(LogLevel.Information);然后在 Program.cs 里加一句app.LogMcpRequests();这行LogMcpRequests()会把 MCP 的请求和响应摘要打到控制台或你配置的日志提供程序包括工具名、参数、执行耗时、HTTP 状态码。我调试时经常打开这个开关看着 AI 一步步调工具就像观察一个实习生干活哪里传错参数一清二楚。注意不要把LogMcpRequests()放到生产环境且日访问量大的服务上否则日志量会非常可观。我在正式环境把 MCP 请求日志接到了集中日志系统控制台只保留 Warnings 以上的输出。4. 客户端实战让 AI 真正上手你的接口服务端起来了MCP 的 HTTP 端点也映射好了接下来要看客户端怎么连。这部分我用两种方式演示一种是通用命令行工具快速验证另一种是在自己的 .NET 应用里内嵌 MCP 客户端。4.1 客户端类型从 IDE 插件到自研 AgentMCP 客户端目前已经是百家争鸣。按使用场景可以分为三类桌面型 AI 助手比如 Claude Desktop适合个人向、本地 stdio 场景配置一下就能让 AI 连上你本机的工具。IDE 智能编程插件比如 GitHub Copilot 的 agent 模式、Cline、Continue 等很多都支持配置 MCP Server 地址对于让 AI 写代码时直接查接口非常有价值。代码级 MCP Client在你的 .NET 应用里通过 SDK 连接 MCP 服务端适合定制自己的 Agent 产品。我们最终给运营做的是第三种团队内部的一个对话机器人后端就是一个 .NET Worker里面启动了 MCP 客户端连接的是我们自己的 MCP 服务端上层再挂一个自定义的对话界面。这样做的原因是运营同事不需要理解 MCP 是什么他只知道打开一个聊天窗口发消息系统自动回答。4.2 用 .NET 客户端调通第一个工具为了演示我在一个控制台应用里写了个最小客户端using ModelContextProtocol.Client; await using var mcpClient await McpClientFactory.CreateAsync( new McpClientOptions { ClientInfo new() { Name MyTestClient, Version 1.0.0 } }, new McpClientTransportOptions { Transport http, RequestEndpoint https://localhost:7088/mcp, ClientEndpoint https://localhost:7088/mcp }); var tools await mcpClient.ListToolsAsync(); Console.WriteLine($可用工具: {string.Join(, , tools.Select(t t.Name))}); var callResult await mcpClient.CallToolAsync( QueryOrder, new Dictionarystring, object? { [orderNo] 1024 }); Console.WriteLine(callResult.ToString());这段代码干了几件事McpClientFactory.CreateAsync创建客户端并指定连接的地址及传输方式。ListToolsAsync从服务端拉取工具清单这一步会触发协议握手initialize。CallToolAsync传入工具名和参数服务端返回结果。这就是最核心的调用链路。如果你的服务端用了 API Key 鉴权可以在McpClientTransportOptions里加 headers客户端与服务端约定统一的密钥。4.3 多轮对话中的工具上下文传递MCP 不会替你管理多轮对话的状态。比如运营问订单 1024 什么状态你调一次 QueryOrder 返回已发货。接着他再问那它什么时候能到——这时候新工具没有接收上一个问题的参数AI 客户端需要把这个订单号1024的上下文注入到这次调用的参数里。这一层逻辑通常在客户端应用里完成我做的聊天机器人是这么处理的把每一次工具调用的参数和结果拼接成一段观测记录追加到 Prompt 上下文里。让大模型基于当前问题 历史调用记录决定下一次调用什么工具、传什么参数。所有编排在客户端完成服务端无状态保持纯粹。一个经验工具返回值里尽量包含结构化信息比如订单号、金额、状态等客户端可以用它来拼接下一步的 Prompt。如果只返回一串拼接好的中文描述大模型很容易丢失关键的字段信息。5. 落地过程中的真实坑从 SSL 报错到响应截断这部分是我最想写的。因为 MCP 协议本身并不复杂真正折磨人的全是落地链路中的暗坑。我把我踩过的、以及从社区里看到的高频问题列一下希望能帮你省点时间。5.1 localhost 上的 SSL 协议错误我在本地调试时AI 客户端打卡在https://localhost:8889/mcp经常在浏览器 Console 里看到GET https://localhost:8889/img/banner.jpg net::ERR_SSL_PROTOCOL_ERROR其实这个报错不只是 MCP 场景所有本地 HTTPS 开发都遇到过。根因一般是开发证书问题。ASP.NET Core 默认会用本地开发证书但很多机器没有信任它或者证书过期/被覆盖TLS 握手失败就成了ERR_SSL_PROTOCOL_ERROR。解决办法按顺序排查信任开发证书dotnet dev-certs https --trust如果--trust失败手动把证书导入到受信任的根证书颁发机构。清掉旧证书dotnet dev-certs https --clean后再重新创建。如果证书没问题还报错检查launchSettings.json里 HTTPS 端口和实际监听端口是否一致。我遇到过 launchSettings 里写 8889但 Kestrel 实际监听 5001前端访问 8889 自然握不上手。MCP 客户端对 SSL 证书很敏感因为它是后台 HTTP 调用不弹证书信任窗口。如果你不想折腾证书开发阶段可以临时改 HTTP 不加密内网环境控制好网络策略问题不大。生产环境建议用受信任的正式证书或内部 CA 证书并在客户端里预置 CA。5.2 响应被截断net::ERR_INCOMPLETE_CHUNKED_ENCODING另一个高频错误是net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)这个报错的意思是服务端返回了分块传输Chunked的响应但响应体没有完整传完连接就断了。HTTP 状态码已经变成 200客户端却拿不到完整 body。我在 MCP 场景里遇到这个问题的原因是工具方法内部调了一个很慢的外部服务超过了 ASP.NET Core 默认的请求超时时间Kestrel 把连接掐了。常见诱因有三类工具本身耗时长比如聚合多个下游接口、跑复杂报表。反代Nginx、IIS的缓冲或超时配置太短MCP 长响应传到一半被反代掐断。响应体特别大比如tools/call返回了几万行的数据表达到网关限制。针对 MCP 场景我的处理建议给长任务设计异步工具模式工具先返回一个任务 ID客户端轮询查询结果。MCP 规范支持进度通知但异步任务更直观。我们内部的大报表查询就是这么做的。如果是反代超时调整proxy_read_timeout、proxy_send_timeoutNginx或requestTimeoutIIS ARR。如果是 Kestrel 超时在 Program.cs 里适当调大但别忘了这会影响所有请求builder.WebHost.ConfigureKestrel(options { options.Limits.KeepAliveTimeout TimeSpan.FromMinutes(5); options.Limits.RequestHeadersTimeout TimeSpan.FromSeconds(30); });ERR_INCOMPLETE_CHUNKED_ENCODING的好消息是它远比一般的 500 错误好排查——你只要去服务端日志看连接是被谁断的是 Kestrel 自己超时还是反代超时还是业务抛了未捕获异常导致连接异常关闭基本就能定位。5.3 工具名冲突、重复注册与并发调用还有一个很隐蔽的问题如果你在多个工具类里定义了同名方法SDK 默认用方法名作为工具名注册时就会冲突。比如 OrderTools 和 RefundTools 都有GetStatusAsyncMCP 服务端启动时就会报类似duplicate的错。解决办法很简单给每个工具显式指定唯一名称[McpServerTool(Name order_get_status, Description 查询订单状态)] [McpServerTool(Name refund_get_status, Description 查询退款单状态)]另外注意 MCP 工具是并发的。AI 可能一次性发起多个tools/call请求比如同时查订单和查库存如果你的业务方法不是线程安全的比如共享了一个非线程安全的 Service 实例会出各种诡异问题。我这边把所有工具方法都设计成无状态静态方法或者从 DI 容器里取作用域服务避免共享状态。5.4 开发时给客户端配置 API Key 与白名单接内网生产数据之前一定要先把鉴权做上。MCP 协议本身不定义鉴权方式你可以直接用 HTTP 层的中间件。ASP.NET Core 下最简单的方式是自定义一个中间件校验自定义 Headerapp.Use(async (context, next) { var apiKey context.Request.Headers[X-Api-Key].FirstOrDefault(); if (apiKey ! builder.Configuration[McpApiKey]) { context.Response.StatusCode 401; return; } await next(); });有了这层即使 MCP 地址暴露到内网不可信网络没有正确 API Key 的客户端也拿不到tools/list的任何信息。AI 工具越强大越要控制谁能调用。这跟数据库连接字符串不应该明文出现在前端是同一个道理。6. 实测对比同样的需求无 MCP 与有 MCP 的差别光说不练假把式。我拿一个真实需求走了一遍完整链路运营问帮我查一下订单 1024 的物流信息如果已经签收就把订单状态改成已完成。6.1 无 MCP 的链路复制粘贴越多错误越多没有 MCP 时AI 的参与方式是帮我把这个需求写成一个调用物流接口的脚本。我用聊天窗口让大模型生成了一段 C# 代码先调物流查询接口判断签收状态再调订单更新接口。代码本身写得没什么大问题但接下来这个过程堪称痛苦我要找到物流查询接口的文档确认参数名是orderNo还是orderId。我要找到订单更新接口的鉴权 Token 配置。我要在本地把代码跑起来发现 NuGet 包缺了依赖。运行时发现物流接口返回的签收状态字段是sign_status跟代码里对不上一一改。最后跑完我还得自己检查更新接口到底生效了没有。这个过程中AI 其实只完成了一小步生成了代码。剩下所有的和真实系统对接的活都是人干的。如果你每天只处理一次这类需求可能感受不深但运营一天问二三十个问题你光陪着跑脚本就啥也不用干了。6.2 有 MCP 的链路AI 直接查数、直接改接上 MCP 以后同一需求链路变成了AI 读到你服务的工具清单里面有QueryLogistics和UpdateOrderStatus。它自动调用QueryLogistics参数orderNo1024返回里带着物流状态已签收。它再调用UpdateOrderStatus参数orderNo1024, status已签收完成。最后它把两个调用结果整理成一段话订单已签收状态已更新完成。整个过程不需要我写任何胶水代码。AI 自己根据工具描述和参数 schema 决定调哪个、传什么值服务端执行真实逻辑并返回真实结果。运营得到的是可信的、可溯源的答案。有个细节如果QueryLogistics返回的不是已签收而是派送中AI 应该停止后续操作并告诉用户订单还在派送暂未签收未变更订单状态。这就体现出 AI 的判断能力——它虽然不能访问真实系统但能基于工具返回值做条件分支。MCP 给它的价值正是拿到这些真实返回值。6.3 安全边界与权限控制的进一步思考MCP 让 AI 有了手这也意味着一旦控制不好它可能乱摸。我建议从设计上把工具的粒度调成操作级而不是全量接口级不要粗暴地把自己所有 Web API 都映射成 MCP 工具只暴露 AI 切实需要的那几个操作。每个工具的 Description 里写清楚什么情况下用它和禁止用什么参数能明显降低 AI 误调用的概率。写操作工具比如更新订单、改库存加一层二次确认逻辑。比如客户端在界面上弹出AI 准备执行以下操作请确认确认后才真正调用服务端。我自己对AI 自动写操作的态度是可以在内网、低风险场景开放但高危操作必须加人审。这个边界想得越清楚MCP 给你带来的收益就越稳。7. 上线之后的一些维护经验服务挂上去之后还有个日常维护的问题怎么知道 AI 调用失败率高不高怎么加一个新工具怎么灰度我的做法是把 MCP 请求日志接到现有的日志系统做了两个指标按工具统计调用成功率、按客户端统计调用频率。这样能很快发现哪个工具经常报错或者哪个客户端在疯狂刷接口。另外我留了一个管理端点可以动态查看已注册的工具列表不用翻代码app.MapGet(/health, () new { Status ok, ToolsCount 0 // 运行时从 DI 容器里取 IMcpServer 统计 });MCP 工具的新增流程基本是写一个方法 → 加特性 → 在 Program.cs 里WithToolsT()注册 → 重启服务。AI 客户端下次连接时通过tools/list自动拿到新工具不需要更新客户端。这个动态发现机制很香团队里其他同事要用新功能只要服务端加了客户端立即就能用。我在实际操作中的体会是MCP 的价值不在于协议本身有多酷而在于它强行让你把接口的语义讲清楚了——工具描述、参数说明、返回结构这些以前常常躺在文档里吃灰的东西现在成了 AI 能不能用对接口的关键。给工具写描述的时候要像给一个完全不懂业务的新同事交代任务那样写清楚AI 表现会有质的提升。最后再分享一个小技巧如果你在调试 MCP 客户端和服务端可以在服务端把LogMcpRequests()打开客户端每调一次工具控制台就能看到完整的 request 和 response。这套组合拳比任何调试器都直观——你能亲眼看着 AI 是怎么思考、怎么传参、怎么处理返回值的。看完你会觉得这玩意儿确实是下一代接口交互的雏形。