different-ai/openwork · warning · ExternalMcpDiagnosticError

MCP_CATALOG_TOOL_NAME_LIMIT

MCP_CATALOG_TOOL_NAME_LIMIT

Error message

MCP_CATALOG_TOOL_NAME_LIMIT

What it means

External MCP tool catalog validation: each tool's `name` field is checked against EXTERNAL_MCP_TOOL_NAME_LIMIT_BYTES using validateToolCatalogField. A tool whose name exceeds the byte limit produces diagnostic code MCP_CATALOG_TOOL_NAME_LIMIT, rejecting that tool (or the catalog sync) rather than accepting oversized identifiers that break downstream storage/routing.

Source

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

  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",
    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 })

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Shorten the tool name on the external MCP server so it fits within EXTERNAL_MCP_TOOL_NAME_LIMIT_BYTES.
  2. Check the diagnostic payload for the exact byte count vs. limit, then trim the namespacing/prefix.
  3. If the upstream name can't change, register an alias/mapping with a short name at the gateway level.
  4. If the limit is too strict for your org, adjust EXTERNAL_MCP_TOOL_NAME_LIMIT_BYTES in the Den API config.

Example fix

// before
server.tool("acme_corporate_crm_integration_create_contact_record_v2", ...)
// after
server.tool("acme_create_contact", ...)
Defensive patterns

Strategy: validation

Validate before calling

const LIMIT = 128; // keep in sync with EXTERNAL_MCP_TOOL_NAME_LIMIT_BYTES
new TextEncoder().encode(tool.name).length <= LIMIT || reject(tool, "tool name exceeds byte limit");

Try / catch

try {
  await syncCatalog(source);
} catch (e) {
  if (e.diagnostics?.some((d) => d.code === "MCP_CATALOG_TOOL_NAME_LIMIT")) {
    // skip/alias the offending tool instead of failing the whole sync
  } else throw e;
}

Prevention

When it happens

Trigger: Syncing/publishing an external MCP server whose tool definition has a name longer than the configured byte limit — typically very long namespaced tool names like my_org__very_long_integration__do_something_specific_v2.

Common situations: Upstream MCP server generating verbose tool names; concatenating server prefix + tool name before publishing; migration from another gateway that allowed longer names; multibyte characters consuming bytes faster than characters.

Related errors


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