different-ai/openwork · error
MCP_PROVIDER_HTTP_403
MCP_PROVIDER_HTTP_403
Error message
MCP_PROVIDER_HTTP_403
What it means
MCP_PROVIDER_HTTP_403 is raised when an MCP tool discovery or tool execution request receives HTTP 403 from the provider. It is classified as PROVIDER_AUTHORIZATION / provider_policy_denied and is non-retryable with the provider admin as owner: authentication passed far enough to reach an authorization check, but the provider's role, ACL, or application permission policy denies this specific operation.
Source
Thrown at ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts:965
// enterprise providers: only a Bearer/insufficient_scope challenge means
// token validation; an ordinary tools/* 403 is usually an ACL/role denial.
if (status === 401 || input.bearerChallenge || input.insufficientScope) {
return {
phase: "AUTH_RESOURCE_VALIDATION",
category: input.insufficientScope ? "oauth_insufficient_scope" : "oauth_resource_rejected",
code: input.insufficientScope ? "MCP_OAUTH_INSUFFICIENT_SCOPE" : `MCP_OAUTH_HTTP_${status}`,
retryable: status === 401,
actionOwner: input.insufficientScope ? "organization_admin" : "member",
operatorAction: input.insufficientScope
? "Grant the provider scopes required by this MCP resource and reconnect."
: "Reconnect the provider account and verify token audience, tenant, and resource binding.",
}
}
if (status === 403 && (phase === "MCP_TOOL_DISCOVERY" || phase === "MCP_TOOL_EXECUTION")) {
return {
phase: "PROVIDER_AUTHORIZATION",
category: "provider_policy_denied",
code: "MCP_PROVIDER_HTTP_403",
retryable: false,
actionOwner: "provider_admin",
operatorAction: "Grant the provider role, ACL, or application permission required for this operation.",
}
}
}
if (status >= 400) {
return {
phase,
category: "http_failure",
code: `MCP_HTTP_${status}`,
retryable: status === 408,
actionOwner: "provider_admin",
operatorAction: "Inspect provider and proxy logs for the failing HTTP request using the diagnostic reference.",
}
}
if (phase.startsWith("MCP_") && input.contentType === "text/html") {
return {View on GitHub (pinned to 2b7df46e8a)
Solutions
- Grant the provider role, ACL, or application permission required for this specific discovery/execution operation.
- Confirm which identity the gateway presents to the provider and check its permissions in the provider's admin console.
- Re-run the operation after the grant is applied; retries without a permission change will keep failing with 403.
Example fix
// before: token scoped to viewer role calling a mutating tool
await client.callTool({ name: 'delete-record', arguments })
// after: provider admin grants editor role / tool permission, then it succeeds
await client.callTool({ name: 'delete-record', arguments }) Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast: check the identity's granted scopes against the tool's requirement before executing
if (!grantedScovers.includes(tool.requiredPermission)) {
throw new Error(`missing provider permission ${tool.requiredPermission}`)
} Type guard
function isProviderAuthzDenied(d: { code: string }): boolean {
return d.code === 'MCP_PROVIDER_HTTP_403'
} Try / catch
try {
return await client.callTool(req)
} catch (e) {
if (isProviderAuthzDenied(e.diagnostic)) {
// non-retryable: escalate to provider admin for role/ACL grant
escalateToProviderAdmin({ operation: req.name, diagnostic: e.diagnostic })
}
throw e
} Prevention
- Provision the provider service account with the roles/ACLs for every tool the integration exposes.
- Re-audit permissions whenever new tools are enabled on the provider side.
- Test discovery (tools/list) and one representative execution after any provider access change.
When it happens
Trigger: Calling tools/list (MCP_TOOL_DISCOVERY) or a tool invocation (MCP_TOOL_EXECUTION) against a provider that returns 403 — e.g. the provider token authenticates but the account lacks the role/permission for that tool, or the app is not allow-listed for that operation.
Common situations: Provider API key issued for a read-only role used for a write tool; provider-side ACL changes removing a service account's access; a new tool added on the provider that the existing integration app is not permissioned for; expired or rotated grants on the provider tenant.
Related errors
- PROVIDER_AUTHORIZATION
- unsupported_resource_permissions
- The MCP provider did not return an authorization URL.
- Only workspace owners and super-admins can change settings.
- Only the workspace owner can delete this organization.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/0eda8092509d7d17.
Report an issue: GitHub.