{"record":{"id":"527642d0be0565ab","repo":"mastra-ai/mastra","slug":"the-extra-key-is-now-nested-under-mcp-extra-in","errorCode":null,"errorMessage":"The \"extra\" key is now nested under \"mcp.extra\" in tool arguments","messagePattern":"The \"extra\" key is now nested under \"mcp\\.extra\" in tool arguments","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mcp/src/server/server.ts","lineNumber":1141,"sourceCode":"        };\n\n        const mcpOptions: MastraToolInvocationOptions = {\n          messages: [],\n          toolCallId: '',\n          requestContext: proxiedContext,\n          // Pass MCP-specific context through the mcp property\n          mcp: {\n            elicitation: sessionElicitation,\n            extra,\n            log: sessionLog,\n            progress: sessionProgress,\n          },\n          // @ts-expect-error this is to let people know that the elicitation and extra keys are now nested under mcp.elicitation and mcp.extra in tool arguments\n          get elicitation() {\n            throw new Error(`The \"elicitation\" key is now nested under \"mcp.elicitation\" in tool arguments`);\n          },\n          get extra() {\n            throw new Error(`The \"extra\" key is now nested under \"mcp.extra\" in tool arguments`);\n          },\n        };\n\n        await this.enforceToolExecutionFGA(request.params.name, proxiedContext);\n\n        const result = await tool.execute(validation?.value ?? request.params.arguments ?? {}, mcpOptions);\n\n        const duration = Date.now() - startTime;\n\n        // Check if the tool builder returned a validation error (e.g. input failed Zod validation\n        // after passing the JSON Schema first-pass validation above)\n        if (isValidationError(result)) {\n          this.logger.warn(`CallTool: Tool '${request.params.name}' returned a validation error in ${duration}ms.`, {\n            error: result.message,\n          });\n          return {\n            content: [{ type: 'text', text: result.message }],\n            isError: true,","sourceCodeStart":1123,"sourceCodeEnd":1159,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/mcp/src/server/server.ts#L1123-L1159","documentation":"Companion to the `elicitation` migration guard: accessing the top-level `extra` key in tool arguments now throws with a pointer to the new location, `mcp.extra`. The throwing getter exists solely to surface the rename to developers instead of silently returning undefined.","triggerScenarios":"During a `tools/call`, the tool's execute function accesses `context.extra` (e.g. `extra.requestInfo`, `extra.sessionId`, or request metadata) on the proxied MCP context.","commonSituations":"Tools that read HTTP request info, auth context, or per-session data via `extra` written before the `mcp.extra` nesting was introduced.","solutions":["Access request/session data via `mcp.extra` instead of the top-level `extra` argument.","Update destructured parameters to pull `extra` from the nested `mcp` object.","Grep tools for `extra.` and `extra}` usages and migrate them to `mcp.extra`."],"exampleFix":"// before\nexecute: async (args, { extra }) => console.log(extra.sessionId)\n// after\nexecute: async (args, mcp) => console.log(mcp.extra.sessionId)","handlingStrategy":"type-guard","validationCode":"// static check before deploy\ngrep -rn \"\\bextra\\b\" src/tools/ | grep -v \"mcp.extra\" && echo 'migrate to mcp.extra'","typeGuard":"function getExtra(mcp: unknown): McpExtra | undefined { return !!mcp && typeof mcp === 'object' && 'extra' in mcp ? (mcp as any).extra : undefined; }","tryCatchPattern":"try { return await tool.execute(args, mcpOptions); } catch (e) { if (String(e?.message).includes('mcp.extra')) { throw new Error('Tool uses deprecated top-level extra; migrate to mcp.extra'); } throw e; }","preventionTips":["Access request/session metadata exclusively via mcp.extra.","Update copied sample tools from older tutorials to the nested API.","Type the execute options parameter so unknown top-level keys are rejected at compile time."],"tags":["mcp","migration","breaking-change","tools"],"backgroundTag":"api-migration-renamed-key","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}