{"record":{"id":"cc5d8580b6d9b1f9","repo":"different-ai/openwork","slug":"mcp-catalog-page-limit-cc5d85","errorCode":"MCP_CATALOG_PAGE_LIMIT","errorMessage":"MCP_CATALOG_PAGE_LIMIT","messagePattern":"MCP_CATALOG_PAGE_LIMIT","errorType":"error_code","errorClass":"ExternalMcpDiagnosticError","httpStatus":null,"severity":"error","filePath":"ee/apps/den-api/src/capability-sources/external-mcp-client.ts","lineNumber":744,"sourceCode":"        tracker: input.diagnostic,\n        code: \"MCP_CATALOG_BYTE_LIMIT\",\n        operatorAction: `Reduce the complete serialized tool catalog below ${EXTERNAL_MCP_CATALOG_LIMIT_BYTES} bytes.`,\n      })\n    }\n    catalogBytes += cursorMeasurement.bytes\n    if (seenCursors.has(result.nextCursor)) {\n      throw catalogDiagnosticError({\n        tracker: input.diagnostic,\n        code: \"MCP_CATALOG_CURSOR_LOOP\",\n        operatorAction: \"Fix the provider's tools/list pagination so each nextCursor advances.\",\n      })\n    }\n    seenCursors.add(result.nextCursor)\n    cursor = result.nextCursor\n  }\n  throw catalogDiagnosticError({\n    tracker: input.diagnostic,\n    code: \"MCP_CATALOG_PAGE_LIMIT\",\n    operatorAction: `Reduce the provider catalog to at most ${pageLimit} pages or use a scoped MCP server.`,\n  })\n}\n\nexport type ExternalMcpConnectResult =\n  | { status: \"connected\" }\n  | { status: \"needs_auth\"; authorizeUrl: string }\n\n/**\n * Attempts to connect. For authType \"none\"/\"apikey\" this either succeeds or\n * throws. For \"oauth\", if there's no valid token yet, the SDK's transport\n * drives discovery (+ dynamic client registration if needed) and returns the\n * authorize URL to send the admin's browser to — no token exchange happens\n * yet, that's connect/callback's job. `signedState` (our own signed token\n * identifying which connection this is for) is passed through as the\n * standard OAuth `state` param, since that's the only param guaranteed to\n * round-trip back to connect/callback on any spec-compliant server.\n */","sourceCodeStart":726,"sourceCodeEnd":762,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/capability-sources/external-mcp-client.ts#L726-L762","documentation":"Thrown after the loop when the provider requires more than pageLimit (default EXTERNAL_MCP_TOOL_PAGE_LIMIT = 20) tools/list pages to return its full catalog. This is a hard cap on pagination round-trips, distinct from the tool-item and byte limits.","triggerScenarios":"The while (cursor !== undefined) loop in collectExternalMcpToolPages exits without the diagnostic 'catalog_ready' pass because the iteration count reached pageLimit pages and nextCursor is still defined.","commonSituations":"Providers with tiny page sizes (e.g. 10 tools/page) and large catalogs (thousands of tools); servers that ignore the client's requested page size; very broad aggregator servers.","solutions":["Reduce the provider catalog to at most 20 pages worth of tools","Use a scoped MCP server exposing only the needed tools","Increase the server's page size so the catalog fits in fewer pages","Split the provider into multiple smaller servers"],"exampleFix":"// before: server pageSize=10 with 500 tools -> 50 pages\n// after: server pageSize=100 -> 5 pages (under the 20-page limit)","handlingStrategy":"validation","validationCode":"const pages = Math.ceil(totalTools / pageSize)\nif (pages > 20) throw new Error(`${pages} pages exceeds the 20-page catalog limit`)","typeGuard":null,"tryCatchPattern":"try {\n  await connectExternalMcp(...)\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"MCP_CATALOG_PAGE_LIMIT\")) {\n    console.error(\"Provider needs >20 tools/list pages; increase page size or reduce catalog\")\n  } else throw err\n}","preventionTips":["Honor the client's requested page size and use a large page size (e.g. 100+)","Keep catalogs small enough to fit in 20 pages","Prefer scoped servers for large internal registries","Monitor page growth as your tool set expands"],"tags":["mcp","pagination","page-limit"],"backgroundTag":"payload-size-limit-exceeded","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}