different-ai/openwork · error · ExternalMcpDiagnosticError

MCP_CATALOG_SCHEMA_DEPTH_LIMIT|MCP_CATALOG_SCHEMA_CYCLE|MCP_CATALOG_SCHEMA_SIZE_LIMIT

MCP_CATALOG_SCHEMA_DEPTH_LIMIT|MCP_CATALOG_SCHEMA_CYCLE|MCP_CATALOG_SCHEMA_SIZE_LIMIT

Error message

Flatten each tool schema below ${EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT} nested levels.

What it means

During catalog ingestion, each tool's JSON schema is measured via measureSerializedJson; failures are classified by reason (depth, cycle, size) and converted into one of the codes MCP_CATALOG_SCHEMA_DEPTH_LIMIT, MCP_CATALOG_SCHEMA_CYCLE, or MCP_CATALOG_SCHEMA_SIZE_LIMIT with this operator action for the depth case. The gateway refuses schemas deeper than EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT, cyclic, or too large, to protect enterprise clients from pathological schemas.

Source

Thrown at ee/apps/den-api/src/capability-sources/external-mcp-client.ts:613

  schema: unknown
}): void {
  const measurement = measureSerializedJson(
    input.schema,
    EXTERNAL_MCP_TOOL_SCHEMA_LIMIT_BYTES,
    EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT,
  )
  if (measurement.ok) return
  const code = measurement.reason === "depth"
    ? "MCP_CATALOG_SCHEMA_DEPTH_LIMIT"
    : measurement.reason === "cycle"
      ? "MCP_CATALOG_SCHEMA_CYCLE"
      : "MCP_CATALOG_SCHEMA_SIZE_LIMIT"
  const operatorAction = measurement.reason === "depth"
    ? `Flatten each tool schema below ${EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT} nested levels.`
    : measurement.reason === "cycle"
      ? "Return JSON-serializable, acyclic tool schemas."
      : `Reduce each serialized tool schema below ${EXTERNAL_MCP_TOOL_SCHEMA_LIMIT_BYTES} bytes.`
  throw catalogDiagnosticError({ tracker: input.diagnostic, code, operatorAction })
}

function measureCatalogTool(input: {
  diagnostic: ExternalMcpDiagnosticTracker
  tool: ExternalMcpToolPage["tools"][number]
  remainingBytes: number
}): number {
  validateToolCatalogField({
    diagnostic: input.diagnostic,
    value: input.tool.name,
    field: "name",
    limit: EXTERNAL_MCP_TOOL_NAME_LIMIT_BYTES,
    code: "MCP_CATALOG_TOOL_NAME_LIMIT",
  })
  validateToolCatalogField({
    diagnostic: input.diagnostic,
    value: input.tool.title,
    field: "title",

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Flatten the tool schema to fewer than EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT nested levels (collapse oneOf/allOf nesting, hoist shared subschemas)
  2. Remove recursive/cyclic $ref structures or make the schema acyclic and JSON-serializable
  3. Minimize schema size: trim long descriptions, cap enum sizes, drop embedded defaults/examples
  4. Check the thrown code (DEPTH vs CYCLE vs SIZE) to know which measurement failed

Example fix

// before
schema: { a: { b: { c: { d: { e: { f: { type: "string" } } } } } } } // too deep
// after
schema: { a: { type: "object", properties: { b: { $ref: "#/definitions/leaf" } } }, definitions: { leaf: { type: "string" } } }
Defensive patterns

Strategy: validation

Validate before calling

function schemaDepth(s: unknown, d = 0): number {
  if (d > EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT) throw new Error("schema too deep");
  if (s && typeof s === "object") for (const v of Object.values(s)) schemaDepth(v, d + 1);
  return d;
}
schemaDepth(tool.inputSchema);

Type guard

null

Try / catch

try {
  await listExternalMcpTools(conn);
} catch (e) {
  const code = String(e);
  if (code.includes("SCHEMA_DEPTH")) flattenSchemas();
  else if (code.includes("SCHEMA_CYCLE")) breakRefCycles();
  else if (code.includes("SCHEMA_SIZE")) shrinkSchemas();
  else throw e;
}

Prevention

When it happens

Trigger: tools/list ingestion calls the schema validation with a tool whose inputSchema measurement fails: nesting exceeds EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT, the schema object contains a reference cycle, or its serialized form exceeds EXTERNAL_MCP_TOOL_SCHEMA_LIMIT_BYTES.

Common situations: Providers with deeply nested oneOf/allOf JSON Schemas generated from SDK types; recursive schema definitions ($ref cycles) that break naive serializers; monolithic schemas embedding large enums or embedded examples.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/968a8cfcae32bf1e. Report an issue: GitHub.