{"record":{"id":"93018d2546a40c34","repo":"different-ai/openwork","slug":"mcp-provider-invalid-params-mcp-provider-http-403","errorCode":"MCP_PROVIDER_INVALID_PARAMS|MCP_PROVIDER_HTTP_403|MCP_PROVIDER_HTTP_429","errorMessage":"MCP provider tool execution failed (${result})","messagePattern":"MCP provider tool execution failed \\((.+?)\\)","errorType":"error_code","errorClass":"ExternalMcpDiagnosticError","httpStatus":null,"severity":"error","filePath":"ee/apps/den-api/src/capability-sources/external-mcp-client.ts","lineNumber":1016,"sourceCode":"  let operationError: unknown\n  try {\n    await runExternalMcpRequestWithinDeadline({\n      deadline,\n      diagnostic,\n      phase: \"MCP_INITIALIZE\",\n      operation: (options) => client.connect(transport, options),\n    })\n    diagnostic.passed(\"MCP_INITIALIZED\", \"protocol_ready\")\n    diagnostic.begin(\"MCP_TOOL_EXECUTION\")\n    const result = await runExternalMcpRequestWithinDeadline({\n      deadline,\n      diagnostic,\n      phase: \"MCP_TOOL_EXECUTION\",\n      requestTimeoutMs: EXTERNAL_MCP_TOOL_CALL_TIMEOUT_MS,\n      operation: (options) => client.callTool({ name: input.toolName, arguments: input.args }, undefined, options),\n    })\n    if (result.isError) {\n      throw providerToolDiagnosticError({ tracker: diagnostic, result })\n    }\n    diagnostic.passed(\"PROVIDER_EXECUTION\", \"operation_ready\")\n    return result\n  } catch (error) {\n    operationError = error\n    throw diagnostic.error(error)\n  } finally {\n    try {\n      await client.close()\n    } catch (error) {\n      if (!operationError) throw diagnostic.error(error, \"SHUTDOWN\")\n    }\n  }\n}\n\nexport function callExternalMcpTool(input: ExternalMcpToolCallInput) {\n  return runExternalMcpToolCall(input)\n}","sourceCodeStart":998,"sourceCodeEnd":1034,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/capability-sources/external-mcp-client.ts#L998-L1034","documentation":"When Den executes a tool on an external MCP provider via client.callTool and the provider responds with isError true, providerToolDiagnosticError converts the result into a diagnostic error. The message embeds the provider's serialized result, and the code can be one of MCP_PROVIDER_INVALID_PARAMS, MCP_PROVIDER_HTTP_403, or MCP_PROVIDER_HTTP_429 depending on what the provider reported (tool call timeout is EXTERNAL_MCP_TOOL_CALL_TIMEOUT_MS = 120s).","triggerScenarios":"Calling a marketplace/external MCP tool where the provider replies with an error result: invalid arguments against the tool's input schema (INVALID_PARAMS), the provider rejecting the request with HTTP 403 (authz/permission), or HTTP 429 (rate limit) during the callTool operation.","commonSituations":"Sending arguments that don't match the tool's schema (missing required field, wrong type); OAuth token for the connection lacking scope for the tool; hitting the provider's rate limit from bursts or shared egress IPs; provider-side breaking changes to the tool's parameters.","solutions":["Inspect the embedded provider result in the message; fix the tool arguments to match the tool's declared input schema.","For HTTP_403: reconnect the provider via the Connect flow and verify the granted OAuth scopes include the tool.","For HTTP_429: reduce call frequency / add backoff and retry later.","Re-run tool discovery to pick up changed schemas, then retry the call."],"exampleFix":"// before: args guessed from memory\nrun: callTool({ name: 'sheet.append', arguments: { row: data } })\n// after: validate against the tool's schema from tools/list\nrun: callTool({ name: 'sheet.append', arguments: { values: data } }) // matches inputSchema.properties.values","handlingStrategy":"try-catch","validationCode":"// validate args against the tool's inputSchema before calling\nconst parsed = toolInputSchema.safeParse(args)\nif (!parsed.success) throw new Error(`invalid args for ${toolName}: ${parsed.error.message}`)","typeGuard":"function isProviderErrorResult(r: unknown): r is { isError: true; content: unknown } {\n  return typeof r === 'object' && r !== null && 'isError' in r && (r as { isError: boolean }).isError === true\n}","tryCatchPattern":"try {\n  result = await client.callTool({ name, arguments: args })\n} catch (error) {\n  const code = (error as { code?: string }).code ?? ''\n  if (code === 'MCP_PROVIDER_HTTP_429') await backoffAndRetry()\n  else if (code === 'MCP_PROVIDER_HTTP_403') promptReconnect()\n  else if (code === 'MCP_PROVIDER_INVALID_PARAMS') fixArgsAgainstSchema()\n  else throw error\n}","preventionTips":["Always validate tool arguments against the tool's declared inputSchema.","Re-run tools/list discovery after provider upgrades to catch schema changes.","Keep OAuth connections refreshed and scopes sufficient.","Apply client-side rate limiting/backoff for bursty tool calls."],"tags":["mcp","tool-execution","provider-error","rate-limit"],"backgroundTag":"remote-tool-call-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}