{"record":{"id":"ba00eb0c4d266cc4","repo":"docusealco/docuseal","slug":"32603","errorCode":"-32603","errorMessage":"Forbidden","messagePattern":"Forbidden","errorType":"http","errorClass":"CanCan::AccessDenied","httpStatus":403,"severity":"error","filePath":"app/controllers/mcp/mcp_base_controller.rb","lineNumber":12,"sourceCode":"# frozen_string_literal: true\n\nmodule Mcp\n  class McpBaseController < ActionController::API\n    wrap_parameters false\n\n    before_action :authenticate_user!\n    before_action :verify_mcp_enabled!\n    check_authorization\n\n    before_action do\n      raise CanCan::AccessDenied unless can?(:manage, :mcp)\n    end\n\n    rescue_from CanCan::AccessDenied do\n      render_error(-32_603, 'Forbidden', status: :forbidden)\n    end\n\n    rescue_from ActiveRecord::RecordNotFound do\n      render_tool_error('Not found')\n    end\n\n    private\n\n    def default_url_options\n      Docuseal.default_url_options\n    end\n\n    def mcp_body\n      request.request_parameters","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/docusealco/docuseal/blob/004a22c1c88109c7ba0b567df011a8cb13894001/app/controllers/mcp/mcp_base_controller.rb#L1-L30","documentation":"The MCP (Model Context Protocol) controller rejected the request and rendered JSON-RPC error code -32603 with message 'Forbidden' over HTTP 403. It fires from the before_action chain: Devise's authenticate_user! (no valid session), verify_mcp_enabled! (feature disabled), or the inline CanCan check can?(:manage, :mcp) failing for the authenticated user. Note that -32603 is the JSON-RPC 'internal error' slot reused here for authorization denials, which can confuse generic MCP clients.","triggerScenarios":"Calling any /mcp route without a valid authenticated session; authenticating as a user whose role lacks the manage :mcp ability; hitting MCP endpoints on an instance where the MCP feature is disabled.","commonSituations":"Wiring an MCP client (editor assistant, agent) with missing cookies/tokens; self-hosted instances without MCP enabled; roles or plans without MCP entitlements.","solutions":["Confirm MCP is enabled for the instance/account (the verify_mcp_enabled! gate).","Authenticate with a user whose role grants manage :mcp - check the CanCan ability definitions for :mcp.","Ensure the MCP client sends credentials on every request, not just the initial handshake.","When building an MCP client, treat code -32603 with message 'Forbidden' as a terminal auth error, not a retryable internal error."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# smoke-test access before registering tools\ncurl -i -b 'session=...' https://app.example.com/mcp\n# expect 2xx; 403 with -32603 'Forbidden' means stop and fix auth/entitlements first","typeGuard":"const isMcpForbidden = (err) => err?.code === -32603 && err?.message === 'Forbidden'","tryCatchPattern":null,"preventionTips":["Use a dedicated admin-scoped user for MCP integrations","Verify feature flags before pointing clients at /mcp","Prefer a dedicated JSON-RPC error code for authz failures so clients can react precisely"],"tags":["mcp","json-rpc","authorization","cancan","forbidden"],"backgroundTag":"permission-denied","analyzedSha":"004a22c1c88109c7ba0b567df011a8cb13894001","analyzedAt":"2026-08-21T13:38:23.343Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}