different-ai/openwork · error · ExternalMcpDiagnosticError
MCP_CATALOG_BYTE_LIMIT
MCP_CATALOG_BYTE_LIMIT
Error message
MCP_CATALOG_BYTE_LIMIT
What it means
Thrown by measureCatalogTool when measuring an individual tool's serialized JSON would exceed the remaining budget of EXTERNAL_MCP_CATALOG_LIMIT_BYTES (8 MiB). The gateway caps the entire serialized tool catalog per provider so downstream storage and agent contexts stay bounded.
Source
Thrown at ee/apps/den-api/src/capability-sources/external-mcp-client.ts:655
value: input.tool.description,
field: "description",
limit: EXTERNAL_MCP_TOOL_DESCRIPTION_LIMIT_BYTES,
code: "MCP_CATALOG_TOOL_DESCRIPTION_LIMIT",
})
validateToolSchema({ diagnostic: input.diagnostic, schema: input.tool.inputSchema })
if (input.tool.outputSchema !== undefined) {
validateToolSchema({ diagnostic: input.diagnostic, schema: input.tool.outputSchema })
}
const measurement = measureSerializedJson(
input.tool,
Math.max(0, input.remainingBytes),
EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT + 4,
)
if (!measurement.ok) {
throw catalogDiagnosticError({
tracker: input.diagnostic,
code: "MCP_CATALOG_BYTE_LIMIT",
operatorAction: `Reduce the complete serialized tool catalog below ${EXTERNAL_MCP_CATALOG_LIMIT_BYTES} bytes.`,
})
}
return measurement.bytes
}
export async function collectExternalMcpToolPages(input: {
listPage: (cursor: string | undefined, options: RequestOptions) => Promise<ExternalMcpToolPage>
diagnostic: ExternalMcpDiagnosticTracker
pageLimit?: number
itemLimit?: number
deadline?: ExternalMcpLifecycleDeadline
}): Promise<ExternalMcpToolPage["tools"]> {
const pageLimit = input.pageLimit ?? EXTERNAL_MCP_TOOL_PAGE_LIMIT
const itemLimit = input.itemLimit ?? EXTERNAL_MCP_TOOL_ITEM_LIMIT
const deadline = input.deadline ?? createExternalMcpLifecycleDeadline()
const tools: ExternalMcpToolPage["tools"] = []
const seenCursors = new Set<string>()View on GitHub (pinned to 2b7df46e8a)
Solutions
- Reduce the number of tools exposed by the provider
- Shrink each tool's inputSchema/outputSchema (drop redundant fields, flatten oneOfs)
- Split the provider into multiple scoped MCP servers and connect only the needed ones
- Register the provider with a narrower tool allowlist if the gateway supports scoping
Example fix
// before: server exposes 500 tools with ~20KB schemas each (~10MB total) // after: expose only the 50 tools the org actually uses (~1MB total)
Defensive patterns
Strategy: validation
Validate before calling
const catalogBytes = new TextEncoder().encode(JSON.stringify({ tools })).byteLength
if (catalogBytes > 8 * 1024 * 1024) throw new Error(`catalog too large: ${catalogBytes} bytes (limit 8MiB)`) Type guard
function fitsCatalogBudget(serialized: string): boolean {
return new TextEncoder().encode(serialized).byteLength < 8 * 1024 * 1024
} Try / catch
try {
await connectExternalMcp(...)
} catch (err) {
if (err instanceof Error && err.message.includes("MCP_CATALOG_BYTE_LIMIT")) {
console.error("Serialized catalog exceeds 8MiB; reduce tool count/schema size")
} else throw err
} Prevention
- Budget ~8MiB total serialized catalog per provider
- Keep JSON Schemas small: avoid deeply nested oneOf/anyOf sprawl
- Expose only tools your org uses; use scoped servers
- Measure serialized catalog size in your server's CI
When it happens
Trigger: Cumulative catalogBytes plus the current tool's measured size surpasses 8 MiB, so measureSerializedJson is called with remainingBytes <= 0 or too little room and reports failure.
Common situations: One provider exposing thousands of very large tools; servers shipping huge JSON Schemas per tool; aggregating gateways that proxy many upstream servers into one catalog.
Related errors
- MCP_CATALOG_TOOL_TITLE_LIMIT
- MCP_CATALOG_TOOL_DESCRIPTION_LIMIT
- MCP_CATALOG_ITEM_LIMIT
- MCP_CATALOG_DUPLICATE_TOOL
- MCP_CATALOG_CURSOR_SIZE_LIMIT
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/5e45de72c7f88ec8.
Report an issue: GitHub.