different-ai/openwork · error · ExternalMcpDiagnosticError

MCP_CATALOG_TOOL_DESCRIPTION_LIMIT

MCP_CATALOG_TOOL_DESCRIPTION_LIMIT

Error message

MCP_CATALOG_TOOL_DESCRIPTION_LIMIT

What it means

Thrown by measureCatalogTool when a tool's `description` exceeds EXTERNAL_MCP_TOOL_DESCRIPTION_LIMIT_BYTES (64 KiB of UTF-8). Descriptions are embedded in the serialized catalog passed to agents, so the gateway caps them to keep the catalog within its total byte budget.

Source

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

    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",
    limit: EXTERNAL_MCP_TOOL_TITLE_LIMIT_BYTES,
    code: "MCP_CATALOG_TOOL_TITLE_LIMIT",
  })
  validateToolCatalogField({
    diagnostic: input.diagnostic,
    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.`,
    })
  }

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Trim the tool's description on the provider server to under 64 KiB UTF-8
  2. Move long documentation to a URL or linked resource and keep a concise summary in the description
  3. Use a scoped MCP server exposing fewer tools
  4. Identify the failing tool via the diagnostic phase (MCP_TOOL_DISCOVERY) and patch it provider-side

Example fix

// before
{ name: "run", description: readmeFileContents }
// after
{ name: "run", description: "Run a shell command in the workspace." }
Defensive patterns

Strategy: validation

Validate before calling

function validateToolDescription(description: string): boolean {
  return new TextEncoder().encode(description).byteLength <= 65536
}
if (!validateToolDescription(tool.description)) throw new Error("tool description exceeds 64KB UTF-8")

Type guard

function hasSafeDescription(tool: { description: string }): boolean {
  return new TextEncoder().encode(tool.description).byteLength <= 65536
}

Try / catch

try {
  await connectExternalMcp(...)
} catch (err) {
  if (err instanceof Error && err.message.includes("MCP_CATALOG_TOOL_DESCRIPTION_LIMIT")) {
    console.error("Provider tool description too large; summarize to <64KB")
  } else throw err
}

Prevention

When it happens

Trigger: A tools/list page returns a tool whose description field is larger than 65536 UTF-8 bytes; validation occurs right after the title check in measureCatalogTool.

Common situations: Servers concatenating full Markdown docs into descriptions; code generators emitting entire schema comments as descriptions; providers with no own description-size hygiene.

Related errors


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