{"record":{"id":"9e332a6078464078","repo":"payloadcms/payload","slug":"mcp-overrideaccess-must-be-true-or-false","errorCode":null,"errorMessage":"MCP overrideAccess must be \"true\" or \"false\".","messagePattern":"MCP overrideAccess must be \"true\" or \"false\"\\.","errorType":"validation","errorClass":"APIError","httpStatus":400,"severity":"error","filePath":"packages/plugin-mcp/src/endpoint/index.ts","lineNumber":32,"sourceCode":"export const mcpEndpoint: PayloadHandler = async (req) => {\n  if (!req.url) {\n    throw new APIError('Missing request URL', 400)\n  }\n\n  req.payloadAPI = 'MCP' as const\n\n  const pluginConfig = getPluginConfig({ config: req.payload.config })\n  const overrideAccessParam = new URL(req.url).searchParams.get('overrideAccess')\n\n  if (overrideAccessParam !== null && process.env.NODE_ENV !== 'development') {\n    throw new APIError('MCP overrideAccess is only available in development.', 400)\n  }\n\n  let overrideAccess = false\n  if (overrideAccessParam === 'true') {\n    overrideAccess = true\n  } else if (overrideAccessParam !== null && overrideAccessParam !== 'false') {\n    throw new APIError('MCP overrideAccess must be \"true\" or \"false\".', 400)\n  }\n\n  const authorizedMCP = await getAuthorizedMCP({ overrideAccess, req })\n  // Payload augments the original web-standard Request in place.\n  const mcpRequest = req as PayloadRequest & Request\n\n  // Keep the old JSON-only, stateless behavior because the SDK's 2025 fallback uses SSE.\n  if (await isLegacyRequest(mcpRequest)) {\n    const server = buildMcpServer({ authorizedMCP, pluginConfig, req })\n    const transport = new WebStandardStreamableHTTPServerTransport({\n      enableJsonResponse: true,\n      sessionIdGenerator: undefined, // stateless mode\n    })\n    transport.onerror = (err) => {\n      req.payload.logger.error({ err, msg: 'Error serving legacy MCP request' })\n    }\n\n    try {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/plugin-mcp/src/endpoint/index.ts#L14-L50","documentation":"When overrideAccess is present in development, mcpEndpoint only accepts the literal strings 'true' or 'false'. Any other value (e.g. '1', 'yes', empty string) throws APIError 400. There is no boolean coercion.","triggerScenarios":"Query like ?overrideAccess=1, ?overrideAccess=yes, or ?overrideAccess= (empty) in a development environment.","commonSituations":"Assuming boolean coercion; typo; URL-encoding mishap producing an empty value; client library stringifying a boolean incorrectly.","solutions":["Use the literal string 'true' or 'false' for the overrideAccess param.","Omit the param entirely when you want the default (false).","Check the client isn't appending '=1' or an empty value."],"exampleFix":"// before\nGET /api/mcp?overrideAccess=1\n// after\nGET /api/mcp?overrideAccess=true","handlingStrategy":"validation","validationCode":"const raw = url.searchParams.get('overrideAccess')\nif (raw !== null && raw !== 'true' && raw !== 'false') {\n  throw new Error('overrideAccess must be literally \"true\" or \"false\"')\n}","typeGuard":"const isValidOverrideAccess = (v: string | null): boolean =>\n  v === null || v === 'true' || v === 'false'","tryCatchPattern":null,"preventionTips":["Use literal 'true'/'false' strings for the param.","Omit the param when you want the default behavior.","Ensure clients don't stringify booleans into '1'/'' values."],"tags":["validation","mcp","plugin-mcp"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}