MCP › Errors & Troubleshooting

MCP

Errors & Troubleshooting

MCP clients need to distinguish transport or protocol errors from tool-level outcomes. A successful JSON-RPC response does not always mean the business action completed — inspect isError, structuredContent.reason_code, structuredContent.tool_output, and structuredContent.execution.status.

Response shapes

1. JSON-RPC error response

Used for protocol, authentication, authorization, session, rate-limit, or unavailable-edge failures.

{
  "jsonrpc": "2.0",
  "id": "tools-list",
  "error": {
    "code": -32001,
    "message": "Public MCP requests require Authorization: Bearer <api_key>.",
    "data": { "code": "authentication_required" }
  }
}

2. Tool result with isError: true

tools/call may return HTTP 200 and a JSON-RPC result with isError: true. Treat that as a business failure — inspect structuredContent before retrying.

{
  "jsonrpc": "2.0",
  "id": "call-send-email",
  "result": {
    "content": [{ "type": "text", "text": "Tool invocation failed." }],
    "structuredContent": {
      "reason_code": "sender_profile_unavailable",
      "tool_output": {
        "error_code": "sender_profile_unavailable",
        "error_message": "The default sending domain must finish verification before production email can be sent without from. Provide from explicitly, or verify the default domain."
      },
      "execution": {
        "status": "failed"
      }
    },
    "isError": true
  }
}

This example shows sender_profile_unavailable when send_email runs with full_execution and an omitted from while the workspace default sender/domain is not ready for production. Omit from only when that default is configured and verified for production; otherwise confirm production sending setup with the user before retrying, or supply a production-authorized from.

3. Tool result awaiting confirmation (isError: false)

Some production actions pause for explicit human confirmation instead of failing. The JSON-RPC request still succeeds, but isError stays false and structuredContent.execution.status is awaiting_confirmation. No production send has been created yet.

{
  "jsonrpc": "2.0",
  "id": "call-send-email",
  "result": {
    "content": [{ "type": "text", "text": "Production email is awaiting explicit confirmation. No production send request or schedule has been created." }],
    "structuredContent": {
      "reason_code": "explicit_production_confirmation_required",
      "tool_output": {
        "error_code": "explicit_production_confirmation_required",
        "error_message": "explicit_production_confirmation must be true for production execution."
      },
      "execution": {
        "status": "awaiting_confirmation",
        "confirmation": {
          "required": true,
          "required_argument": "explicit_production_confirmation"
        }
      }
    },
    "isError": false
  }
}

After the user confirms, retry with explicit_production_confirmation: true and a new idempotency_key (for example, production-send-confirmed-002). Do not reuse the idempotency_key from the suspended awaiting_confirmation call.

Common error codes

CodeMeaning
authentication_required (401)Missing bearer credential.
invalid_bearer_credential (401)The bearer credential is invalid or could not be authenticated.
invalid_token (401)The OAuth token is invalid or expired.
insufficient_scope (403)The credential lacks the required scope for this operation.
workspace_not_accessible (403)The credential cannot access the requested workspace.
scope_selection_required (409)Send X-Workspace-Id — the credential can access multiple workspaces.
unknown_sessionThe supplied Mcp-Session-Id is unknown or expired.
rate_limitedBack off using retry_after_seconds.
resource_not_foundThe resource is not published or not visible for this workspace.

Troubleshooting

SymptomLikely causeFix
Workspace selection error Your API key can access multiple workspaces and the request did not specify which one to use. Ask your AI agent: "Ask me to choose a workspace, then retry with the selected workspace ID."
No tools are visible The API key lacks the required scopes. Confirm the API key scopes in your Constant Contact for Agents account.
Tool result has isError: true The MCP request succeeded, but the business action was rejected or failed. Ask your AI agent: "My last MCP tool call returned an error. Help me understand what went wrong and how to fix it."
Tool result has execution.status: "awaiting_confirmation" Production send paused for explicit confirmation. The JSON-RPC result keeps isError: false — this is not a failure. Confirm intent with the user, then retry with explicit_production_confirmation: true and a new idempotency_key (for example, production-send-confirmed-002). Do not reuse the key from the suspended call.
Send with draft_id went to production unexpectedly draft_id and emails default to full_execution when execution_class is omitted. Set execution_class: "test" for sandbox delivery (uses CTCT domain), or include explicit_production_confirmation: true for production sends only when the workspace default sender/domain is configured and verified for production (or supply a production-authorized from).
from address rejected The from address supplied by the caller is not production-authorized for this workspace. Leave from empty only when the workspace default sender/domain is configured and verified for production. Otherwise confirm setup with the user before retrying, or supply a different production-authorized from.
Production send blocked (sender_profile_unavailable or sender_domain_not_verified) The workspace default sender/domain is not ready for production, or the supplied from is not production-authorized. Confirm production sending setup with the user before retrying. Omit from only when the workspace default sender is ready; otherwise use a different production-authorized from.
Email arrived from wrong domain Expected a different sender domain but got noreply@send.ctct.dev This is expected in test mode — test sends always use the CTCT sandbox domain. For production sends, use execution_class: "full_execution" with explicit_production_confirmation: true only when the workspace default sender/domain is configured and verified for production; the backend uses that default when from is omitted.
explicit_production_confirmation required Missing confirmation flag for production send. The response uses isError: false with execution.status: "awaiting_confirmation". Confirm intent with the user, then retry full_execution with explicit_production_confirmation: true and a new idempotency_key.