different-ai/openwork · error · ExternalMcpDiagnosticError
MCP_CATALOG_ITEM_LIMIT
MCP_CATALOG_ITEM_LIMIT
Error message
MCP_CATALOG_ITEM_LIMIT
What it means
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.
Source
Thrown at ee/apps/den-api/src/capability-sources/external-mcp-client.ts:688
const itemLimit = input.itemLimit ?? EXTERNAL_MCP_TOOL_ITEM_LIMIT
const deadline = input.deadline ?? createExternalMcpLifecycleDeadline()
const tools: ExternalMcpToolPage["tools"] = []
const seenCursors = new Set<string>()
const seenToolNames = new Set<string>()
let catalogBytes = 0
let cursor: string | undefined
for (let page = 0; page < pageLimit; page += 1) {
input.diagnostic.begin("MCP_TOOL_DISCOVERY")
const result = await runExternalMcpRequestWithinDeadline({
deadline,
diagnostic: input.diagnostic,
phase: "MCP_TOOL_DISCOVERY",
operation: (options) => input.listPage(cursor, options),
})
if (tools.length + result.tools.length > itemLimit) {
throw catalogDiagnosticError({
tracker: input.diagnostic,
code: "MCP_CATALOG_ITEM_LIMIT",
operatorAction: `Reduce the provider catalog below ${itemLimit} tools or use a scoped MCP server.`,
})
}
for (const tool of result.tools) {
catalogBytes += measureCatalogTool({
diagnostic: input.diagnostic,
tool,
remainingBytes: EXTERNAL_MCP_CATALOG_LIMIT_BYTES - catalogBytes,
})
if (seenToolNames.has(tool.name)) {
throw catalogDiagnosticError({
tracker: input.diagnostic,
code: "MCP_CATALOG_DUPLICATE_TOOL",
operatorAction: "Ensure every tools/list page uses a unique, stable tool name.",
})
}
seenToolNames.add(tool.name)
tools.push(tool)View on GitHub (pinned to 2b7df46e8a)
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)
Example fix
// before: one server with 3500 tools // after: split into 'db-tools' (300) and 'docs-tools' (120) and connect each scoped server
Defensive patterns
Strategy: validation
Validate before calling
const toolCount = (await fetchAllToolPages()).length
if (toolCount > 2000) throw new Error(`${toolCount} tools exceeds the 2000-tool catalog limit`) Try / catch
try {
await connectExternalMcp(...)
} catch (err) {
if (err instanceof Error && err.message.includes("MCP_CATALOG_ITEM_LIMIT")) {
console.error("Provider exposes >2000 tools; connect a scoped server instead")
} else throw err
} Prevention
- 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
When it happens
Trigger: During pagination, tools.length + result.tools.length exceeds 2000, triggering catalogDiagnosticError with code MCP_CATALOG_ITEM_LIMIT.
Common situations: 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.
Related errors
- MCP_CATALOG_TOOL_TITLE_LIMIT
- MCP_CATALOG_TOOL_DESCRIPTION_LIMIT
- MCP_CATALOG_BYTE_LIMIT
- MCP_CATALOG_DUPLICATE_TOOL
- invalid_mcp_token_payload
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/35a7970912773e8f.
Report an issue: GitHub.