Serverless Framework MCP 服务器故障排查完全指南症状定位、根因分析与证据验证【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless本文以 Serverless Framework 官方 MCP 服务器故障排查参考文档 skills/serverless-mcp/references/troubleshooting.md 为骨架结合仓库内mcp插件的真实实现源码系统讲解将 MCP 服务器托管到 AWS Lambda / API Gateway 后遇到各类问题的定位思路与修复方法。无论你遇到的是端点有响应但行为不对、冷启动即失败、鉴权与 OAuth 发现异常、配置报错还是部署期 CLI 意外都能按症状 → 原因 → 修复的路子快速收敛并最终用真实的 JSON-RPC 结果、状态码或日志行完成复核。文章贯穿一个核心方法论不要凭 YAML看起来对或deploy 打印出了端点就断定服务器是好的——端点存在不等于协议可用。每种故障都必须找到可观测的真实证据再收工如何制造这些证据curl 最小往返、MCP Inspector、日志读取、鉴权端到端探测在 skills/serverless-mcp/references/testing.md 中有可直接照抄的命令本文是它的症状侧镜像看到什么意味着什么该怎么改。排查总纲先读症状后读日志以证据裁决整个参考文档的组织方式是按症状检索Find the symptom而非按组件检索。标准动作只有三步精确定位症状——是 HTTP 状态码504/401/403、协议层错误-32020/-32021/isError、冷启动日志中的异常还是配置解析阶段的MCP_*报错对应到根因类别——端点边界edge/regional 的静默上限、模块契约默认导出必须是createMcpHandler()的返回值、打包策略devDependencies、混合构建、IAM/KMS 授权、API Gateway 鉴权语义、OAuth 发现的 URL 解析链应用修复并重新用真实证据验证——一个 JSON-RPC 返回、一个状态码、一行日志。值得先建立的一张心智地图来自 skills/serverless-mcp/SKILL.mdMCP 部署被一切为二——你拥有一个模块用官方 SDK 构建、默认导出带 web 标准fetch的 handlerFramework 拥有它周边的一切HTTPS 路由、流式响应、鉴权接线、打包、state 密钥注入。因此几乎每个故障都可以先问一句这个错误出在我的模块还是Framework 围栏上下文五个症状表正好按此展开。症状表一端点有响应但行为不符合预期这是最隐蔽的一类问题请求能到达、状态码是2xx但工具行为、协议细节或生命周期不符合预期。核心诱因集中在API Gateway 的静默空闲边界、协议版本协商、zod/SDK 版本与注册方式上。症状原因修复工具写不出任何东西时大约30s出现504而短调用成功端点是 edge-optimizedFramework 默认从 invoke 起算流安静约 30s 即被掐断设provider.endpointType: REGIONAL并重新部署。提高timeout无用——被限制的是两次写入之间的间隔不是总时长regional 端点上流仍在大约 5 分钟时死亡regional 的空闲上限被触达因为工具长时间静默让工具周期性发出进度通知——每次通知都是一次写入会重置空闲时钟写法见 skills/serverless-mcp/references/server-code.md 的 progress 小节tools/list返回的工具带空 input schema而tools/call却正常服务里装的是 zod 3SDK 的 schema 转换需要 zod 4.2npm install zod^4.2后重新部署所有进度事件不是随工作发生而是结尾一次性 flush链路上某处缓冲了整个响应——例如手写路由没有response.transferMode: STREAM或前面挂了代理让 Framework 拥有这条路由在手工写的流式函数上每一条路由含任何 metadata 路由都要STREAM向客户端要东西的工具elicitation、sampling、roots报 did not declare the required capability 或 cannot receive server-to-client requests客户端协商到了早于2026-07-28的协议修订版官方 SDK 客户端默认值按请求服务的模式无法发出 client wire 请求而带内input_required流它同样携带elicitation/create、sampling/createMessage、roots/list是 2026 时代才有的让客户端选择现代修订版new Client(info, { capabilities: { elicitation: { form: {} } }, versionNegotiation: { mode: auto } })并注册配套 handlers。普通工具、流与进度不需要它——只有向客户端要东西的工具需要加了自定义域名后原本能用的execute-apiURL 的客户端拒绝服务器设置provider.domain后所有对外公布的 URL含 metadata 文档的resource都指向该域名符合规范的客户端用旧 URL 访问会因 origin 不匹配而拒绝让客户端指向域名。一旦域名前置execute-apiURL 就不再是可互换的别名tools/call返回isErrorCannot read properties of undefined (reading mcpReq)工具注册时没有inputSchema但回调签名是(args, ctx)——没有 schema 时 SDK 把 context 作为回调唯一参数传入于是ctx为undefined注册时补inputSchema无输入工具用z.object({})或把 context 作为唯一形参接收对端点发GET返回405这是预期行为——SDK 对非 POST 动词按规范返回错误无需修复客户端挂断后工具仍在运行并继续计费此入口不传播客户端断连timeout就是成本上限把它设为你实际最长的工具。观察ctx.mcpReq.signal让取消在它到达的任何位置生效其中前两行值得展开在 packages/serverless/lib/plugins/aws/mcp/lib/validate.js 中可以看到默认timeout 60、最低 Node 20、默认运行时nodejs24.x等常量而 idle 边界来自 API Gateway 本身而非函数配置——mcp既不改也不校验provider.endpointType它与服务里普通http函数共享同一个 API。因此该设置是API 级的要么整条服务REGIONAL要么靠工具内每 300s 至少一次的写入进度通知续命。这一点在 skills/serverless-mcp/references/config.md 的 Endpoint type 一节有同样的表述edge 大约 30s、regional 大约 5 分钟、超过约 300s 后进度通知是唯一把调用留在空闲边界内的手段。注册了工具却带空 schema其实是 zod 版本这一条的可见形态修复后可用 skills/serverless-mcp/references/testing.md 的端点类型试金石试验验证请求一个静默约 35s、不带progressToken的工具——200延迟返回 regional、流式完好约 30s504 仍是 edge。镜像试验同样重要约 36s 每秒发一次进度的调用第一个事件应在前几秒落地若它与其余事件在结尾一起到达说明有东西缓冲了整条响应。症状表二冷启动失败去函数日志里读这一表的所有条目都以Lambda 冷启动为舞台。MCP 服务器函数与普通函数无异因此用serverless logs -f name就能看到入口entry自己爆出的错误而入口正是 packages/serverless/lib/plugins/aws/mcp/entry/index.mjs 所描述的那个预构建桥它先解析环境含 state 密钥再import你的模块最后经由 Hono 的 Lambda 桥把流式运行时接到 SDK handler 的fetch上。症状原因修复错误点名了server:属性和createMcpHandler()模块的默认导出没有暴露 web 标准的fetch写成export default createMcpHandler(() { … })——不是导出McpServer实例也不是具名导出ERR_MODULE_NOT_FOUND针对modelcontextprotocol/server或zod经典打包会剥离devDependencies或混合服务把该 server 漏出了 bundle把它们移入dependencies或设package.excludeDevDependencies: false让每个server 接受同等的构建处理The MCP server module … is not in the deployed packageserver:路径写错或打包规则排除了该文件修正路径或修正把它丢掉的package.patterns读 state key 报AccessDenied且点名一个 action 和一个 ARN你带来的执行角色没有被授予读权限——Framework 不能修改它不是它创建的角色把消息中引用的那条语句附加到该角色的 policy 上同一条消息但 AWS 文本提及 KMS密钥由客户管理的 KMS key 加密额外授予该 key 的kms:Decrypt并让 key 自身 policy 允许该角色使用SERVERLESS_MCP_STATE_KEY_REF is empty/ state key 里没有字符串值引用指向不可读内容或指向二进制 secretstate key 必须是纯文本 secret或 String/SecureString 参数报SERVERLESS_MCP_SERVER_MODULE未设置该函数没有被作为 MCP 服务器部署通过mcp:部署若此前跑过serverless dev会话用serverless deploy重新部署关于默认导出必须是fetch这条模块侧契约在 skills/serverless-mcp/references/server-code.md 写得很清楚createMcpHandler()的工厂每个请求跑一次模块作用域之外不共享状态默认导出必须暴露 web 标准的fetch——导出McpServer实例、transport 或具名导出正是冷启动报错点名server:的根因。而 state key 的时序细节藏在入口源码里entry/index.mjs中入口会先把 state 密钥放进process.env.SERVERLESS_MCP_STATE_KEY再import 你的模块且该顺序被注释明确为规范要求而非偏好——因为模块作用域代码例如模块级的createRequestStateCodec({ key })需要读它。把 state 密钥设计成先注入后导入同时解释了SERVERLESS_MCP_STATE_KEY_REF is empty与二进制 secret 两行Framework 把 key引用放进函数环境入口在运行时用ssm:GetParameter或secretsmanager:GetSecretValue解析它见 packages/serverless/lib/plugins/aws/mcp/entry/index.mjs引用指向空、指向二进制值时自然得不到可用字符串。症状表三鉴权与发现开始这一表之前文档给了一条关键的分流规则Framework 从不校验 token所以 MCP 路由上的401/403要么来自 API Gateway裸形态invoke 之前拒绝要么来自你自己的模块规范形态invoke 之后返回——绝不是入口的。判断办法是看服务器自身的日志组有没有新增条目有 函数被调用了错误出自你的模块/网关后的逻辑没有 拒绝发生在 invoke 之前属于 API Gateway/authorizer 的语义。这也是在 skills/serverless-mcp/references/testing.md 中鉴权端到端一节反复强调的证据标准。症状原因修复裸401{message:Unauthorized}且服务器与 authorizer 的日志组都无新增API Gateway 在 invoke 前就拒绝请求缺了 authorizer 的 identity source默认是Authorization头或 Cognito user pool authorizer 自行判定 token 无效无 token 的调用方得到它就是设计在起作用。若合法调用方也如此检查客户端是否发送了identitySource点名的那个头所有调用者含有效 token都401且 authorizer 自己的日志显示它在拒绝或报错字符串形式编译成TOKENauthorizer它只收到event.authorizationToken没有event.headers按完整请求事件写的函数在它找的地方找不到东西用带type: request、identitySource: method.request.header.Authorization的对象形式或改读event.authorizationToken403User is not authorized to access this resourceAPI Gateway 的ACCESS_DENIED响应Lambda authorizer执行后返回了 Deny policy——本行不是aws_iam形态下面两行才是这就是 authorizer 的裁决——检查它的 policy 逻辑。裁决会被resultTtlInSeconds缓存默认 300s所以修好的 authorizer 可能继续按旧裁决响应这么久authorizer: aws_iam服务器的 MCP 路由上403{message:Missing Authentication Token}请求没有 SigV4 签名。IAM 授权的 method 从不答401未签名请求得到这个403——与下面路由未命中的发现型403字节一致因此要按命中哪个路由哪个 path来区分用 AWS 凭证对请求做 SigV4 签名不能签名的调用方需要换别的authorizer形态403User: arn:… is not authorized to perform: execute-api:Invoke on resource: …请求已签名但调用者的 IAM 身份缺少该路由上的execute-api:Invoke。裁决来自逐请求的 IAM policy 评估——不存在 authorizer 资源也没有resultTtlInSeconds缓存参与给调用身份授予该 API stage/route ARN 上的execute-api:Invoke发现 URL 的GET答403——{message:Missing Authentication Token}或{message:Forbidden}文字会误导两者都与鉴权无关都是路径未命中。Missing Authentication Token表示请求到达了一个 API 但没有路由匹配在execute-api上是路径或 stage 错了在自定义域名上是路径匹配了 base-path 映射但背后的 API 没有该路由或此服务器没有oauthDiscovery该路由从未被创建。Forbidden是自定义域名下没有任何 base-path 映射匹配——请求从未到达任何 API。状态码永远不会替你区分——是响应体 被请求的 URL在区分检查 URL在裸execute-api源上 stage 前缀是 URL 的一部分在自定义域名上 domain 的basePath是 URL 的一部分。并确认mcp.servers.name.oauthDiscovery已设置浏览器客户端POST发现 URL 后报不透明的 CORS 失败该路由只服务GET和OPTIONS其他方法得到不带 CORS 头的 API Gateway 默认403浏览器只能把它报告成 CORS 错误用GET取文档package 或 deploy 警告发现被公布在 stage URL 上没有oauthDiscovery.publicUrl也没有单一 REST 面向的自定义域名于是文档的 URL 解析回退到 stage URL——任何客户端常用的相对于 origin root 探测都落不到那里交互式登录将无法工作把mcp.servers.name.oauthDiscovery.publicUrl设为客户端真正使用的 URL或在provider.domain下声明域名。在二者之一被设置之前每次package/deploy 都会重复该警告对默认execute-apiURL 的 OAuth 发现失败——Claude Code 落在永不加载的origin/authorize登录页客户端探测 well-known 路径是相对于origin root的在默认端点上文档位于 stage 前缀之下任何探测都落空完全落空时客户端可能把服务器 origin 当成授权服务器于是出现死登录页。官方 SDK 客户端从裸401直接开始流程——不需要 challenge 头——随后探测同样的路径在根路径映射处放一个自定义域名——stage 前缀消失root 探测即命中非 root 的basePath会让文档再次离开 root。接受直接给 metadata URL 的客户端可指向 stage 感知 URL 而无需域名Claude Code 没有此类设置改动 issuer/URL 并部署后发现文档仍显示旧值栈更新完成后端点还会继续返回旧响应体一段时间edge-optimized默认经 CloudFront 大约 50–70 秒即便是 regional 也有 60–90 秒——此时控制面已显示新文档而端点仍答旧文档最多等两分钟再重新抓取然后再往下调试未鉴权的洪泛在烧 invoke 次数路由上没有任何authorizer——每个请求都到达函数模块内门禁只在付过 invoke 费之后才拒绝设置authorizerCognito user pool 与aws_iam在任何地方都不触发 invoke 就拒绝Lambda authorizer 在无 token 时甚至不被 invoke缺 identity source就拒绝坏 token 也只花费它自己远便宜得多的 invoke以抛401方式拒绝时不被缓存。无论哪种发现路由都保持开放交互式 OAuth connect 以一条裸客户端消息失败、无任何细节——Claude Code 只报SDK auth failed:客户端侧表面设计上就是静默的issuer 实际答了什么注册被拒、端点被禁用、登录后的 policy 失败都不会被转述直接问 issuer。对 URL-onlyDCR连接用 issuer 自己 metadata 里的注册端点跑curl -s -X POST registration_endpoint带最小请求体{client_name:probe,redirect_uris:[http://localhost:8976/callback]}会返回 issuer 的真实错误——issuer 无论是否开启注册都会公布registration_endpoint所以试探性 POST 才是测试metadata 不是把TOKENvsrequest区分、aws_iam的两种403形态放回源码可以看得更实在 packages/serverless/lib/plugins/aws/mcp/lib/validate.js 中authorizer 的合法类型集合token、request、cognito_user_pools、aws_iam、custom以及编译期大写拼写TOKEN/REQUEST/COGNITO_USER_POOLSvs 挂在已有 authorizer 上的CUSTOM都被显式列出并注明与http事件共用同一套 API Gateway 编译机制——字符串 authorizer 正是默认得到 TOKEN的那条路径这从实现上解释了为什么字符串形式收不到 headers。aws_iam则是唯一API Gateway 自行校验、不需要 authorizer 资源的类型validate.js 中专门处理了它与authorizerId的矛盾组合。关于发现路由不挂 authorizer的取舍它必须让没有 token 的客户端先读到去哪拿 token因此oauthDiscovery的GET/OPTIONS由 API Gateway 以 MOCK 响应模板静态服务、无 Lambda 在背后在 packages/serverless/lib/plugins/aws/mcp/index.js 的before:package:compileEvents钩子中通过registerExternalHttpEvents一次性注册 MCP 路由与发现路由未鉴权探测不 invoke、不冷启动、每请求零成本。与之配套发现是公告而非强制发布文档并不保护服务器oauthDiscovery不带任何authorizer也是合法配置模块内门禁对 Framework 不可见部署时--verbose仅作提醒——详见 packages/serverless/lib/plugins/aws/mcp/index.js 的reportDiscoveryExposure。最后一行的 issuer 侧静默同样映射到客户端设计Claude Code 这类 URL-only 客户端按 URL 识别服务器失败时几乎不吐细节skills/serverless-mcp/references/testing.md 对此给出同一条诊断建议——用 curl 直接 POST 注册端点拿 issuer 的真实错误。症状表四配置错误MCP_*错误码全集这一类有个共同的好消息每一个都在碰到 AWS 之前被抛出——大多在配置解析期间所以print和package就能暴露它们不需要一次 deploy。其中MCP_OAUTH_DISCOVERY_VTL_UNSAFE_VALUE分两段抛schema 拥有的值含Fn::Subissuer 的字面文本在配置解析时抛schema 看不见的值自定义域名、stage、服务器名在模板编译时抛。MCP_OAUTH_DISCOVERY_ISSUER_VARIABLE_COLLISION同理在模板编译期浮现——package两种都能抓到。错误码原因修复MCP_AWS_PROVIDER_REQUIRED服务的provider.name不是aws却写了mcp块把 provider 切到aws或删掉该块MCP_UNSUPPORTED_NODE_RUNTIMEprovider.runtime钉在低于 20 的 Node.js 运行时设nodejs20.x或更新或去掉它用默认的nodejs24.xMCP_RESERVED_SERVER_NAME服务器名叫well-known会与发现路径冲突或__proto__重命名服务器MCP_FUNCTION_NAME_COLLISION服务器名归一化后与某个函数或另一服务器编译成同一个 CloudFormation 逻辑 ID重命名其一——归一化折叠大小写并去掉_所以foo_bar与foobar会冲突MCP_INVALID_STATE_ARNstate是 CloudFormation intrinsic或既非 SSM 参数也非 Secrets Manager secret 的 ARN把 ARN 写全或改用state: trueMCP_AUTHORIZER_INVALIDauthorizer为空、既非字符串也非对象、type 未知、没有指名name/arn/authorizerId之一type: aws_iam例外它不需要标识符、设了authorizerId却没有 API Gateway 要求同列的type、字符串携带冒号字符串总是指函数——ARN 放对象形式、intrinsicarn旁边没有name否则 CloudFormation 名要从尚不存在的 ARN 推导、或把type: aws_iam与authorizerId配对IAM 不挂 authorizer 资源该 id 会被静默忽略指名一个 authorizer 函数、aws_iam、或带标识符的 http-event 风格对象给裸authorizerId配上type给 ARN 用对象形式给 intrinsicarn配nameMCP_AUTHORIZER_NAME_COLLISION两个不同authorizer——在两个服务器上、或一个服务器加一个http事件上——名字编译成同一个 CloudFormation 逻辑 ID只会创建一个 authorizer 资源于是某条路由会静默地被另一个的 authorizer 守护把其中一个改名为归一化后不同的逻辑 ID或让两个定义完全相同以真正成为一个 authorizerMCP_OAUTH_DISCOVERY_ISSUER_REQUIREDoauthDiscovery存在但没有issuer——或issuer是对象但不在受支持的 CloudFormation intrinsic 之列Ref、Fn::GetAtt、Fn::ImportValue、Fn::Sub、Fn::Join、Fn::Base64、Fn::ToJsonString拼错的或不被认可的Fn::键也会落到这里把oauthDiscovery.issuer设为授权服务器的 https URL 或能解析到它的受支持 intrinsic或删掉该块MCP_OAUTH_DISCOVERY_ISSUER_NOT_HTTPSissuer不是带 host 的 https URL——或含$/#会被文档的 Velocity 模板改写。对Fn::Subissuer检查的是${...}占位符之外的字面文本因此整体只是一个占位符的Fn::Sub会失败前缀检查写 provider 公布的完整 https URL在Fn::Sub的替换之外把 scheme 写出来或直接用Ref/Fn::GetAtt指名整个 URL 值MCP_OAUTH_DISCOVERY_PUBLIC_URL_NOT_HTTPSpublicUrl没通过同样的两项检查——或publicUrl是 CloudFormation intrinsic它指本栈之外的前门deploy 会打印它、或带查询串服务器路由会追加在其后URL 中间夹查询串什么都指不到写客户端使用的纯 https 基础 URL——/name/mcp之前的全部不带查询MCP_OAUTH_DISCOVERY_VTL_UNSAFE_VALUE$或#会进入发现文档而 Velocity 把两者都当活语法来源是Fn::Subissuer 的字面文本含${!Literal}转义——它渲染为字面${...}文本在验证期被抛或来自 schema 看不见的值——自定义域名、stage 名、服务器名在模板编译时被抛package能抓到从消息点名的那个值里去掉该字符MCP_OAUTH_DISCOVERY_ISSUER_VARIABLE_COLLISION列表形式的Fn::Subissuer 声明了一个叫RestApiId的变量而发现文档自身的渲染会用这个名字作为本服务的 REST API id改掉Fn::Sub变量映射里的那个变量名MCP_SERVER_MODULE_REQUIRED服务器条目没有可用的server:路径——条目不是对象或server缺失/为空设mcp.servers.name.server为模块路径MCP_ENTRY_STAGING_PATH_TAKEN服务目录里有个serverless-mcp/目录放着 Framework 不拥有的文件移走或改名——打包会在此暂存入口并在结束后移除MCP_PREBUILT_ARTIFACT_UNSUPPORTED设了package.artifact此类 artifact 原样上传入口永远到不了它去掉 artifact 设置或把 MCP 服务器移进自己的服务MCP_ENTRY_BUNDLE_MISSING预构建入口缺失。发布版 CLI 里这是值得上报的 bug源码检出里它是构建产物在packages/serverless下运行npm run build:mcp:entryMCP_API_GATEWAY_PLUGIN_NOT_FOUND内部错误——找不到 API Gateway 编译器上报它API_GATEWAY_EXTERNAL_EVENT_ROUTE_COLLISION你的某个http事件与 MCP 路由坐在同一个 API Gateway 资源上那里的具体 method 会压过路由的ANY从而分流 JSON-RPC 流量挪走你的事件。子路径如/crm/mcp/extra没有问题这份配置错误表与源码中的校验器一一对应。validateMcp在 packages/serverless/lib/plugins/aws/mcp/lib/validate.js 里实现并由插件在initialize钩子中调用见 packages/serverless/lib/plugins/aws/mcp/index.js这就是为什么print/package就能触发错误。几个值得强调的实现细节保留名well-known因与oauthDiscovery文档服务的.well-known路径冲突、__proto__因 JavaScript 原型 setter 而被禁用validate.js 中RESERVED_SERVER_NAMES约 L14-L23函数名校验用naming.getNormalizedFunctionName归一化与 CloudFormation 逻辑 ID 的实际产出保持同一套规则validate.js 约 L591、L631-L648运行时校验provider.runtime低于nodejs20.x即抛MCP_UNSUPPORTED_NODE_RUNTIMEvalidate.js 约 L593-L600state ARN仅接受ssm:parameter/*与secretsmanager:secret/*两类字面 ARN正则见 validate.js 约 L34-L37判定在约 L666-L686authorizer 的复杂规则字符串 vs 对象、authorizerId要配type、ARN 该进对象形式、intrinsicarn要配name、aws_iam不得配authorizerId集中在validateAuthorizer约 L115-L271每条都配有解释为什么——例如裸 Cognito pool ARN 推导出的逻辑名以数字开头、会在 CloudFormation 内毙命intrinsic ARN 上做.split(:)会 TypeErrorVTL 安全发现文档由 API Gateway 在每次请求时以 Velocity 求值$开变量、#开指令所以issuer/publicUrl中两者都被拒Fn::Sub的${...}占位符由 CloudFormation 先解析故被遮蔽后再检查唯独${!Literal}转义会渲染成字面${…}文本、必须拒绝validate.js 中maskSubPlaceholders与validateIntrinsicIssuer约 L437-L475。这些错误码的行为都受单元测试守护相关覆盖见 packages/serverless/test/unit/lib/plugins/aws/mcp/validate.test.js。症状表五部署期与 CLI 意外最后一类发生在 deploy/info 等 CLI 环节多数是框架围栏的行为边界不一定是配置错误。症状原因修复警告说 Dev Mode 不支持 MCP 服务器serverless dev下打包集成让位部署出来的函数在模块前没有入口用serverless deploy部署来真正跑一个服务器deploy function -f name更新了代码却没更新环境Lambda 配置更新在任一值是 CloudFormation 引用时会跳过整个environment——而state正是这样传 key 的环境变更请跑完整serverless deploydeploy 后紧跟一条执行角色读不了 state key的警告部署后的模拟得到确定性的拒绝附上警告引用的那条 statement没有警告但服务器运行时在 key 上失败模拟得不到裁决例如部署凭据可能调不了iam:SimulatePrincipalPolicy于是选择保持沉默而非猜测读冷启动错误——它点名 action 和 ARNdeploy 或info摘要里没有端点行没有自定义域名且没有收集到ServiceEndpoint输出栈尚不存在或查找失败栈起来后再跑一次serverless info--verbose会显示调试行Dev Mode 不支持 MCP在 packages/serverless/lib/plugins/aws/mcp/index.js 有清晰说明Dev Mode 自己接管 artifact 与 handler若照常暂存入口和换 handler 会被覆盖因此整个打包集成让位同时用一次显式警告requests to the deployed endpoint will fail避免端点存在但答不出任何 MCP 内容的隐性失败。deploy function 不更新环境则源于 Framework 行为updateFunctionConfiguration在遇到非字符串对象如{Ref}时会删除整个Environment参数——这正是state: true传 key 的方式。插件选择警告而非绕过因为绕过意味着要在已部署栈里解析引用见 packages/serverless/lib/plugins/aws/mcp/index.js。最后两行对应部署后的权限模拟机制只针对你带来的字面角色 ARN 执行见 packages/serverless/lib/plugins/aws/mcp/lib/permission-check.js 的byoRoleArnFor用iam:SimulatePrincipalPolicy对 state key 求值——能拿到明确拒绝就警告拿不到裁决就沉默宁可不猜把最可信的失败现场留给冷启动错误去点名 action 与 ARN。这一设计让deploy 没警告 运行时报错的组合有了解释不是检查漏了是模拟没能得到裁决。收尾把排查闭环成一个可重复的循环回到 skills/serverless-mcp/SKILL.md 给出的操作循环success signal → write the module → declare it → deploy → verify a real round trip → clean up scratch stacks排障是这条循环的反向行驶用本文的症状表把现象翻译成根因修复后用 skills/serverless-mcp/references/testing.md 里可复制的curl2026-07-28 修订版要求content-type: application/json、accept: application/json, text/event-stream、mcp-method、mcp-name、params._metaenvelope 等头部/信封约定跑一次真实往返确认 HTTP 状态、JSON-RPC 结果与日志证据三者都符合预期——顺手把两个负向用例也验一下-32020头与 body 不一致与-32021工具索要了客户端从未声明能提供的能力它们同时证明请求完好到达了函数内的 SDK。修完别忘了验证端点是mcp: crm → https://…/dev/crm/mcp那行单个服务器内联、多个则缩进块为试验临时起的一整套 REST API、函数、日志组与可能的 secret用serverless remove --stage stage清掉随后重新部署永远是安全的。速查三句话记住这套排障法先分清围栏内外报错来自入口冷启动日志、FrameworkMCP_*/警告还是你自己的模块/网关authorizer、in-module gate看服务器日志组有没有新条目即可分流。静默是头号杀手edge 约 30s、regional 约 5 分钟的空闲上限约束的是写入间隔而非总时长长工具要么REGIONAL要么发进度通知而timeout只是成本上限。文档与配置是提前失效的MCP_*配置错误不需要 deployprint/package就报Discovery 文档由 API Gateway 以 Velocity 模板静态服务因此$、#、RestApiId冲突与publicUrl/issuer 的 URL 解析问题全都能在触碰 AWS 之前或package阶段被拦下。【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?