{"record":{"id":"35a7970912773e8f","repo":"different-ai/openwork","slug":"mcp-catalog-item-limit-35a797","errorCode":"MCP_CATALOG_ITEM_LIMIT","errorMessage":"MCP_CATALOG_ITEM_LIMIT","messagePattern":"MCP_CATALOG_ITEM_LIMIT","errorType":"error_code","errorClass":"ExternalMcpDiagnosticError","httpStatus":null,"severity":"error","filePath":"ee/apps/den-api/src/capability-sources/external-mcp-client.ts","lineNumber":688,"sourceCode":"  const itemLimit = input.itemLimit ?? EXTERNAL_MCP_TOOL_ITEM_LIMIT\n  const deadline = input.deadline ?? createExternalMcpLifecycleDeadline()\n  const tools: ExternalMcpToolPage[\"tools\"] = []\n  const seenCursors = new Set<string>()\n  const seenToolNames = new Set<string>()\n  let catalogBytes = 0\n  let cursor: string | undefined\n  for (let page = 0; page < pageLimit; page += 1) {\n    input.diagnostic.begin(\"MCP_TOOL_DISCOVERY\")\n    const result = await runExternalMcpRequestWithinDeadline({\n      deadline,\n      diagnostic: input.diagnostic,\n      phase: \"MCP_TOOL_DISCOVERY\",\n      operation: (options) => input.listPage(cursor, options),\n    })\n    if (tools.length + result.tools.length > itemLimit) {\n      throw catalogDiagnosticError({\n        tracker: input.diagnostic,\n        code: \"MCP_CATALOG_ITEM_LIMIT\",\n        operatorAction: `Reduce the provider catalog below ${itemLimit} tools or use a scoped MCP server.`,\n      })\n    }\n    for (const tool of result.tools) {\n      catalogBytes += measureCatalogTool({\n        diagnostic: input.diagnostic,\n        tool,\n        remainingBytes: EXTERNAL_MCP_CATALOG_LIMIT_BYTES - catalogBytes,\n      })\n      if (seenToolNames.has(tool.name)) {\n        throw catalogDiagnosticError({\n          tracker: input.diagnostic,\n          code: \"MCP_CATALOG_DUPLICATE_TOOL\",\n          operatorAction: \"Ensure every tools/list page uses a unique, stable tool name.\",\n        })\n      }\n      seenToolNames.add(tool.name)\n      tools.push(tool)","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/capability-sources/external-mcp-client.ts#L670-L706","documentation":"Thrown by collectExternalMcpToolPages when a provider's tools/list returns more than itemLimit (default EXTERNAL_MCP_TOOL_ITEM_LIMIT = 2000) tools in total across all pages. The gateway refuses to ingest catalogs beyond this size to bound memory and agent context usage.","triggerScenarios":"During pagination, tools.length + result.tools.length exceeds 2000, triggering catalogDiagnosticError with code MCP_CATALOG_ITEM_LIMIT.","commonSituations":"Broad 'everything' MCP servers exposing thousands of tools; aggregated/proxy catalogs; a provider adding auto-generated tools (one per DB table, per endpoint) until the count explodes.","solutions":["Reduce the provider catalog below 2000 tools","Use a scoped MCP server that exposes only relevant tools","Split one large server into several focused servers and register them separately","If legitimately needed, run with an explicitly larger itemLimit via collectExternalMcpToolPages options (requires gateway-side change)"],"exampleFix":"// before: one server with 3500 tools\n// after: split into 'db-tools' (300) and 'docs-tools' (120) and connect each scoped server","handlingStrategy":"validation","validationCode":"const toolCount = (await fetchAllToolPages()).length\nif (toolCount > 2000) throw new Error(`${toolCount} tools exceeds the 2000-tool catalog limit`)","typeGuard":null,"tryCatchPattern":"try {\n  await connectExternalMcp(...)\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"MCP_CATALOG_ITEM_LIMIT\")) {\n    console.error(\"Provider exposes >2000 tools; connect a scoped server instead\")\n  } else throw err\n}","preventionTips":["Keep provider tool counts well under 2000","Prefer several focused MCP servers over one mega-server","Monitor tool count growth on providers you operate","Use allowlists to expose subsets of large internal tool registries"],"tags":["mcp","catalog-validation","item-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"}