{"record":{"id":"a2de339a5ca03590","repo":"different-ai/openwork","slug":"mcp-response-body-limit","errorCode":"MCP_RESPONSE_BODY_LIMIT","errorMessage":"MCP_RESPONSE_BODY_LIMIT","messagePattern":"MCP_RESPONSE_BODY_LIMIT","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts","lineNumber":1191,"sourceCode":"  // The enterprise client aborts with a RequestTimeout MCP error of its own, so\n  // check for our marker before any JSON-RPC code is read as the provider's.\n  if (error instanceof ExternalMcpLifecycleDeadlineError || isEnterpriseMcpLifecycleDeadline(error)) {\n    return {\n      phase: fallbackPhase,\n      category: \"lifecycle_deadline\",\n      code: \"MCP_LIFECYCLE_DEADLINE\",\n      retryable: true,\n      actionOwner: \"provider_admin\",\n      operatorAction: fallbackPhase === \"MCP_TOOL_EXECUTION\"\n        ? \"Retry the capability, and reduce provider latency for this tool if it keeps running past the bounded deadline.\"\n        : \"Reduce provider latency or catalog pagination so the complete MCP lifecycle finishes within the bounded deadline, then retry.\",\n    }\n  }\n  if (error instanceof ExternalMcpResponseBodyLimitError) {\n    return {\n      phase: fallbackPhase,\n      category: \"response_too_large\",\n      code: \"MCP_RESPONSE_BODY_LIMIT\",\n      retryable: false,\n      actionOwner: \"provider_admin\",\n      operatorAction: \"Reduce the provider response size, tool catalog, or event-stream payload before retrying.\",\n    }\n  }\n  if (error instanceof PrivateUrlError) {\n    return {\n      phase: \"CONFIGURATION\",\n      category: \"security_blocked\",\n      code: \"MCP_URL_BLOCKED\",\n      retryable: false,\n      actionOwner: \"organization_admin\",\n      operatorAction: \"Use a public HTTPS MCP URL or change the deployment's private-network policy through security review.\",\n    }\n  }\n  if (hasForbiddenPortMessage(error)) {\n    return {\n      phase: \"CONFIGURATION\",","sourceCodeStart":1173,"sourceCodeEnd":1209,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts#L1173-L1209","documentation":"MCP_RESPONSE_BODY_LIMIT is raised when the provider response exceeds the gateway's maximum body size, thrown as ExternalMcpResponseBodyLimitError and classified as response_too_large. The limit protects the gateway from unbounded payloads (huge tool catalogs, giant tool outputs, endless event streams). It is non-retryable and owned by the provider admin because the provider must shrink the payload.","triggerScenarios":"A tools/list response with an enormous catalog, a tool execution returning a very large result blob, or a text/event-stream that grows past the configured byte limit — any phase where the accumulated response body exceeds the limit before parsing completes.","commonSituations":"Providers exposing hundreds/thousands of tools in one unpaginated listing; tools returning entire datasets (full DB dumps, whole files) instead of summaries; misconfigured providers streaming verbose logs inside tool output; consumers requesting max-detail tool results.","solutions":["Reduce the provider response size — trim tool outputs to summaries or bounded result windows.","Shrink the exposed tool catalog (remove/deduplicate tools, paginate listing).","Cap event-stream payload sizes, then retry once the response fits within the body limit."],"exampleFix":"// before: tool returns the entire dataset\nreturn { rows: await db.select().from(events) }\n// after: bounded output\nreturn { rows: await db.select().from(events).limit(100), truncated: true }","handlingStrategy":"validation","validationCode":"// estimate payload size before sending large results through a tool\nconst serialized = JSON.stringify(result)\nif (serialized.length > 1_000_000) {\n  result = summarize(result) // truncate/summarize before returning from the tool\n}","typeGuard":"function isResponseBodyLimit(d: { code: string }): boolean {\n  return d.code === 'MCP_RESPONSE_BODY_LIMIT'\n}","tryCatchPattern":"try {\n  return await client.callTool(req)\n} catch (e) {\n  if (isResponseBodyLimit(e.diagnostic)) {\n    // non-retryable: request a narrower result window instead of retrying the same call\n    return await client.callTool({ ...req, arguments: { ...req.arguments, limit: 100 } })\n  }\n  throw e\n}","preventionTips":["Bound tool outputs (pagination, limits, summaries) at the provider.","Keep tool catalogs lean and paginate discovery responses.","Never stream unbounded logs or raw file dumps through tool results or event streams."],"tags":["mcp","payload-size","body-limit","non-retryable"],"backgroundTag":"response-too-large","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}