different-ai/openwork · error · ExternalMcpDiagnosticError

MCP_CATALOG_TOOL_NAME_LIMIT|MCP_CATALOG_TOOL_DESCRIPTION_LIMIT|MCP_CATALOG_TOOL_TITLE_LIMIT

MCP_CATALOG_TOOL_NAME_LIMIT|MCP_CATALOG_TOOL_DESCRIPTION_LIMIT|MCP_CATALOG_TOOL_TITLE_LIMIT

Error message

Reduce each serialized tool ${input.field} below ${input.limit} UTF-8 bytes.

What it means

`external-mcp-client.ts` validates each tool's metadata strings against per-field UTF-8 byte limits before admitting them to the enterprise catalog. `fieldLimitError` is thrown when name, description, or title exceeds its cap; the thrown code identifies which field (MCP_CATALOG_TOOL_NAME_LIMIT / DESCRIPTION_LIMIT / TITLE_LIMIT). This keeps serialized catalog entries bounded for enterprise clients.

Source

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

  field: string
  limit: number
}): ExternalMcpDiagnosticError {
  return catalogDiagnosticError({
    tracker: input.diagnostic,
    code: input.code,
    operatorAction: `Reduce each serialized tool ${input.field} below ${input.limit} UTF-8 bytes.`,
  })
}

function validateToolCatalogField(input: {
  diagnostic: ExternalMcpDiagnosticTracker
  value: string | undefined
  limit: number
  field: string
  code: "MCP_CATALOG_TOOL_NAME_LIMIT" | "MCP_CATALOG_TOOL_DESCRIPTION_LIMIT" | "MCP_CATALOG_TOOL_TITLE_LIMIT"
}): void {
  if (input.value !== undefined && serializedStringBytes(input.value) > input.limit) {
    throw fieldLimitError(input)
  }
}

function validateToolSchema(input: {
  diagnostic: ExternalMcpDiagnosticTracker
  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"

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Shorten the offending field in the MCP provider's tool definition to fit under the limit (count UTF-8 bytes, not chars)
  2. Have the MCP server truncate/summarize descriptions in its tools/list response
  3. Use a scoped/proxy MCP server that rewrites tool metadata before exposing it
  4. Identify the specific field via the error code and fix that one definition

Example fix

// before (server tool definition)
description: fullApiDocs // 8000 bytes
// after
description: fullApiDocs.slice(0, 1900) // stay under description limit, UTF-8 safe
Defensive patterns

Strategy: validation

Validate before calling

function utf8Len(s: string) { return new TextEncoder().encode(s).byteLength; }
for (const t of providerTools) {
  if (utf8Len(t.name) > NAME_LIMIT || utf8Len(t.description) > DESC_LIMIT || utf8Len(t.title ?? "") > TITLE_LIMIT) {
    throw new Error(`tool ${t.name} metadata exceeds byte limit`);
  }
}

Type guard

null

Try / catch

try {
  await listExternalMcpTools(conn);
} catch (e) {
  if (/MCP_CATALOG_TOOL_(NAME|DESCRIPTION|TITLE)_LIMIT/.test(String(e))) {
    shortenToolMetadata(e.field); // error names the offending field via code
  } else throw e;
}

Prevention

When it happens

Trigger: During tools/list ingestion, `assertStringLimit` (the function at line 589) sees input.value !== undefined with serializedStringBytes(value) > input.limit for the name, description, or title of any returned tool.

Common situations: Providers with very long auto-generated descriptions (full docs pasted into the description field); unicode-heavy titles inflating UTF-8 byte counts beyond char counts; a provider upgrade that lengthened tool metadata.

Related errors


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