{"record":{"id":"3cb90bd3a9332557","repo":"different-ai/openwork","slug":"mcp-provider-declared-error","errorCode":"MCP_PROVIDER_DECLARED_ERROR","errorMessage":"MCP_PROVIDER_DECLARED_ERROR","messagePattern":"MCP_PROVIDER_DECLARED_ERROR","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts","lineNumber":497,"sourceCode":"}\n\nfunction providerAuthorizationClassification(connectUrl: string): Classification {\n  return {\n    phase: \"PROVIDER_AUTHORIZATION\",\n    category: \"provider_authorization_required\",\n    code: \"MCP_PROVIDER_AUTH_REQUIRED\",\n    retryable: false,\n    actionOwner: \"member\",\n    operatorAction: \"Connect your account for this provider using its sign-in link, then retry this capability.\",\n    connectUrl,\n  }\n}\n\nfunction providerDeclaredErrorClassification(): Classification {\n  return {\n    phase: \"PROVIDER_EXECUTION\",\n    category: \"provider_declared_error\",\n    code: \"MCP_PROVIDER_DECLARED_ERROR\",\n    retryable: false,\n    actionOwner: \"provider_admin\",\n    operatorAction: \"Look up the provider-declared JSON-RPC error code with the provider, then correct the downstream condition and retry.\",\n  }\n}\n\nfunction safeNativeToken(value: string | undefined, pattern: RegExp, maxLength = 64): string | undefined {\n  if (!value || value.length > maxLength || !pattern.test(value)) return undefined\n  return value\n}\n\nfunction safeProviderToken(value: unknown, maxLength = 64): string | undefined {\n  return typeof value === \"string\" ? safeNativeToken(value, SAFE_PROVIDER_TOKEN_PATTERN, maxLength) : undefined\n}\n\nfunction safeProviderRequestId(value: unknown): string | undefined {\n  return typeof value === \"string\" ? safeNativeToken(value, SAFE_PROVIDER_REQUEST_ID_PATTERN, 128) : undefined\n}","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts#L479-L515","documentation":"MCP_PROVIDER_DECLARED_ERROR is raised in PROVIDER_EXECUTION phase when the external MCP server itself returned a declared JSON-RPC error. The gateway treats this as a non-retryable, provider-owned failure: the request reached the server and the server deliberately rejected it. The operator is directed to the provider admin because the JSON-RPC error code must be looked up with the provider before correcting the downstream condition.","triggerScenarios":"An MCP tool execution or other JSON-RPC request completes at the HTTP level but the response body contains a JSON-RPC error object with a provider-declared code (e.g. invalid params, method not supported by that server, tool-internal failure). The classifier in external-mcp-diagnostics.ts maps any such declared error to this code via providerDeclaredErrorClassification().","commonSituations":"Calling a tool with arguments the remote server validates and rejects; invoking a JSON-RPC method the specific MCP server build does not implement; server-side domain rules (quota policy inside the tool, unsupported model name) surfacing as JSON-RPC errors after a provider upgrade or config change.","solutions":["Read the provider-declared JSON-RPC error code and message from the diagnostic details and look it up in the provider's documentation.","Fix the downstream condition it points to (wrong tool arguments, unsupported method, server-side policy) in the caller or provider config.","Retry the operation once the condition is corrected; do not blind-retry, this classification is explicitly non-retryable."],"exampleFix":"// before: retrying blindly on any MCP failure\nawait retry(() => client.callTool({ name: 'search', arguments: { q: 42 } }))\n// after: correct the arguments the provider rejected (string expected)\nawait client.callTool({ name: 'search', arguments: { q: '42' } })","handlingStrategy":"try-catch","validationCode":"// validate tool arguments against the tool's inputSchema before calling\nconst parsed = toolInputSchema.safeParse(args)\nif (!parsed.success) throw new Error('Invalid tool arguments: ' + parsed.error.message)","typeGuard":"function isProviderDeclaredError(d: { code: string; data?: { jsonRpcCode?: number | string } }): boolean {\n  return d.code === 'MCP_PROVIDER_DECLARED_ERROR'\n}","tryCatchPattern":"try {\n  await client.callTool({ name, arguments: args })\n} catch (e) {\n  if (isProviderDeclaredError(e.diagnostic)) {\n    // inspect e.diagnostic.data.jsonRpcCode, fix the downstream condition; do NOT retry\n    log.error('provider rejected request', e.diagnostic.data?.jsonRpcCode)\n  }\n  throw e\n}","preventionTips":["Validate tool arguments against the tool's declared inputSchema before every call.","Keep the provider's JSON-RPC error-code documentation linked in your integration runbook.","Pin and test against the provider server version you deploy against."],"tags":["mcp","json-rpc","provider-error","non-retryable"],"backgroundTag":"mcp-provider-declared-json-rpc-error","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}