{"record":{"id":"0debcddd06e23f74","repo":"different-ai/openwork","slug":"mcp-catalog-tool-name-limit-mcp-catalog-tool-descr","errorCode":"MCP_CATALOG_TOOL_NAME_LIMIT|MCP_CATALOG_TOOL_DESCRIPTION_LIMIT|MCP_CATALOG_TOOL_TITLE_LIMIT","errorMessage":"Reduce each serialized tool ${input.field} below ${input.limit} UTF-8 bytes.","messagePattern":"Reduce each serialized tool (.+?) below (.+?) UTF-8 bytes\\.","errorType":"error_code","errorClass":"ExternalMcpDiagnosticError","httpStatus":null,"severity":"error","filePath":"ee/apps/den-api/src/capability-sources/external-mcp-client.ts","lineNumber":589,"sourceCode":"  field: string\n  limit: number\n}): ExternalMcpDiagnosticError {\n  return catalogDiagnosticError({\n    tracker: input.diagnostic,\n    code: input.code,\n    operatorAction: `Reduce each serialized tool ${input.field} below ${input.limit} UTF-8 bytes.`,\n  })\n}\n\nfunction validateToolCatalogField(input: {\n  diagnostic: ExternalMcpDiagnosticTracker\n  value: string | undefined\n  limit: number\n  field: string\n  code: \"MCP_CATALOG_TOOL_NAME_LIMIT\" | \"MCP_CATALOG_TOOL_DESCRIPTION_LIMIT\" | \"MCP_CATALOG_TOOL_TITLE_LIMIT\"\n}): void {\n  if (input.value !== undefined && serializedStringBytes(input.value) > input.limit) {\n    throw fieldLimitError(input)\n  }\n}\n\nfunction validateToolSchema(input: {\n  diagnostic: ExternalMcpDiagnosticTracker\n  schema: unknown\n}): void {\n  const measurement = measureSerializedJson(\n    input.schema,\n    EXTERNAL_MCP_TOOL_SCHEMA_LIMIT_BYTES,\n    EXTERNAL_MCP_TOOL_SCHEMA_DEPTH_LIMIT,\n  )\n  if (measurement.ok) return\n  const code = measurement.reason === \"depth\"\n    ? \"MCP_CATALOG_SCHEMA_DEPTH_LIMIT\"\n    : measurement.reason === \"cycle\"\n      ? \"MCP_CATALOG_SCHEMA_CYCLE\"\n      : \"MCP_CATALOG_SCHEMA_SIZE_LIMIT\"","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/capability-sources/external-mcp-client.ts#L571-L607","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Shorten the offending field in the MCP provider's tool definition to fit under the limit (count UTF-8 bytes, not chars)","Have the MCP server truncate/summarize descriptions in its tools/list response","Use a scoped/proxy MCP server that rewrites tool metadata before exposing it","Identify the specific field via the error code and fix that one definition"],"exampleFix":"// before (server tool definition)\ndescription: fullApiDocs // 8000 bytes\n// after\ndescription: fullApiDocs.slice(0, 1900) // stay under description limit, UTF-8 safe","handlingStrategy":"validation","validationCode":"function utf8Len(s: string) { return new TextEncoder().encode(s).byteLength; }\nfor (const t of providerTools) {\n  if (utf8Len(t.name) > NAME_LIMIT || utf8Len(t.description) > DESC_LIMIT || utf8Len(t.title ?? \"\") > TITLE_LIMIT) {\n    throw new Error(`tool ${t.name} metadata exceeds byte limit`);\n  }\n}","typeGuard":"null","tryCatchPattern":"try {\n  await listExternalMcpTools(conn);\n} catch (e) {\n  if (/MCP_CATALOG_TOOL_(NAME|DESCRIPTION|TITLE)_LIMIT/.test(String(e))) {\n    shortenToolMetadata(e.field); // error names the offending field via code\n  } else throw e;\n}","preventionTips":["Measure metadata in UTF-8 bytes, not characters","Cap description length when generating tools from docs","Truncate long auto-generated descriptions server-side","Re-check limits after provider tool definition changes"],"tags":["mcp","validation","limits","utf-8"],"backgroundTag":"mcp-catalog-limit-exceeded","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}