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
- Trim the tool's description on the provider server to under 64 KiB UTF-8
- Move long documentation to a URL or linked resource and keep a concise summary in the description
- Use a scoped MCP server exposing fewer tools
- 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
- Keep descriptions to one or two concise sentences
- Link out to full docs instead of inlining them
- Test tools/list output size in CI for your MCP server
- Never paste entire README/error catalogs into descriptions
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
- MCP_CATALOG_TOOL_TITLE_LIMIT
- MCP_CATALOG_BYTE_LIMIT
- MCP_CATALOG_ITEM_LIMIT
- MCP_CATALOG_DUPLICATE_TOOL
- MCP_CATALOG_CURSOR_SIZE_LIMIT
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/a9b40f16c6f458b7.
Report an issue: GitHub.