Error Codes
All mcp2p tool errors follow the same response shape. The error field is null on success and contains a structured object on failure:
// Error response shape
{
"data": null,
"error": {
"code": "SPEI_INVALID_CLABE", // Machine-readable code
"message": "CLABE failed checksum.", // Human-readable message
"details": { ... } // Optional extra context
}
}The AI client receives this and communicates the issue to the user in natural language. Your application code should handle errors by checking the error.code field.
isError: true in the MCP protocol envelope, which signals to the AI client that the tool call did not succeed. The AI will read the error and respond accordingly.Error categories
License errors
Errors related to license key validity, entitlements, and configuration. These prevent tool calls from executing.
| Code | Description | Resolution |
|---|---|---|
| LICENSE_MISSING | No license key was provided in the server configuration. | Set the licenseKey field in createMcp2pServer and ensure MCP2P_LICENSE_KEY is set in your environment. |
| LICENSE_INVALID | The license key does not exist in the mcp2p license server. | Verify the key is correct and was not miscopied. Check the dashboard under Settings → License Keys. |
| LICENSE_REVOKED | The license key has been explicitly revoked. | Create a new key in the dashboard. If this was unintentional, contact support. |
| LICENSE_EXPIRED | The license key has passed its configured expiry date. | Renew the license from the dashboard or create a new key with an updated expiry. |
| LICENSE_RAIL_NOT_ENABLED | The called tool's rail is not included in the license entitlements. | Upgrade your license tier to enable the required rail, or remove it from your rails array. |
| LICENSE_ENV_MISMATCH | A sandbox key (mcp2p_test_*) was used to call a live rail, or vice versa. | Use a live key (mcp2p_live_*) for production rails, or enable sandbox mode in your config. |
Rate limit errors
Errors triggered when transaction volume exceeds license tier limits or burst protection thresholds.
| Code | Description | Resolution |
|---|---|---|
| RATE_LIMIT_MONTHLY | The monthly transaction limit for this license tier has been reached. | Upgrade to a higher tier or wait until the next billing period. Check current usage in the dashboard. |
| RATE_LIMIT_BURST | Too many tool calls in a short window (burst protection). | Implement retry logic with exponential backoff. Burst limits reset every 60 seconds. |
2FA errors
Errors and status codes from the two-factor authentication layer. Note that 2FA_REQUIRED is not a failure — it is the expected first-turn response for any payment tool.
| Code | Description | Resolution |
|---|---|---|
| 2FA_REQUIRED | The tool was called without a verificationCode. An SMS has been sent. | This is not an error — it is the expected first-turn response. Prompt the user for their code and call the tool again with verificationCode. |
| 2FA_INVALID | The provided verificationCode did not match the sent OTP. | Ask the user to check the code again. They have maxAttempts - 1 remaining attempts before lockout. |
| 2FA_EXPIRED | The OTP has expired (default TTL: 600 seconds). | Call the tool again without a verificationCode to trigger a new SMS. |
| 2FA_LOCKED | The session is locked after exceeding maxAttempts failed verifications. | Call the tool again without a verificationCode to start a fresh verification session. |
| 2FA_SMS_FAILED | Twilio Verify failed to deliver the SMS. | Check your Twilio credentials and Verify service configuration. Verify the phone number is reachable. |
Validation errors
Errors from input validation — identifier formats, account numbers, and amounts. These return immediately without any network call or SMS.
| Code | Description | Resolution |
|---|---|---|
| SPEI_INVALID_CLABE | The CLABE failed length or modulus-10 checksum validation. | Verify the CLABE is exactly 18 digits and was not mistyped. |
| SPEI_UNKNOWN_BANK | The bank code embedded in the CLABE is not recognized. | Check that the first 3 digits of the CLABE correspond to a valid BANXICO institution code. |
| PSE_INVALID_IDENTIFIER | The recipientId failed format or check-digit validation. | Ensure the format is "NIT:XXXXXXXXX" or "CC:XXXXXXXXXX" and the digits are correct. |
| PSE_UNKNOWN_BANK | The provided bank code is not a recognized ACH Colombia member. | Verify the 3-digit ACH Colombia bank code. Contact your bank aggregator for the correct code list. |
| PIX_INVALID_KEY | The pixKey failed format validation. The type could not be auto-detected or the value is malformed. | For CPF: 11 digits only. For CNPJ: 14 digits only. For phone: E.164 format (+5511999998888). For EVP: UUID v4. |
| PIX_KEY_NOT_FOUND | The PIX key is not registered in the DICT (Diretório de Identificadores do Banco Central). | Ask the recipient to confirm their PIX key. The key may have been unregistered or transferred. |
| AMOUNT_INVALID | The amount is zero, negative, or not an integer. | Pass amount as a positive integer representing minor units (centavos). E.g. 50000 for MXN 500.00. |
Payment errors
Errors returned by the bank connector or payment network after a transfer was attempted.
| Code | Description | Resolution |
|---|---|---|
| SPEI_INSUFFICIENT_FUNDS | The source account has insufficient balance. | Check the account balance before initiating a transfer. |
| SPEI_RECIPIENT_REJECTED | The receiving bank rejected the transfer. | Contact the recipient's bank for the rejection reason. The CLABE may be inactive. |
| SPEI_TIMEOUT | The transfer timed out waiting for BANXICO confirmation. | Use spei_check_status with the trackingKey to determine the final status. Do not retry without checking status first. |
| PSE_INSUFFICIENT_FUNDS | The source account has insufficient balance for the PSE payment. | Verify the account balance before retrying. |
| PSE_BANK_UNAVAILABLE | The receiving bank is temporarily unavailable in the PSE network. | Retry after a few minutes. PSE availability follows ACH Colombia's maintenance windows. |
| PSE_TIMEOUT | The payment timed out waiting for ACH Colombia confirmation. | Use pse_check_status to determine the final payment state before retrying. |
| PIX_INSUFFICIENT_FUNDS | The source account has insufficient balance. | Check the account balance before sending the PIX payment. |
| PIX_RECIPIENT_UNAVAILABLE | The recipient's institution is temporarily unavailable in the PIX network. | PIX is 24/7 but individual institutions may have maintenance windows. Retry after a few minutes. |
| PIX_TIMEOUT | The payment timed out waiting for Banco Central confirmation. | Use pix_check_status with the e2eId to determine the final status. |
| PIX_DUPLICATE_E2EID | A payment with the same end-to-end ID already exists. | This should not occur in normal operation. If it does, contact support. |
| BANK_CONNECTOR_ERROR | An unexpected error occurred in the bank connector layer. | Check your bank aggregator status and credentials. The error details field will contain the upstream error. |
Retrying after errors
Different error categories warrant different retry strategies:
- License errors — Do not retry. Fix the configuration issue first.
- Rate limit errors —
RATE_LIMIT_BURST: retry after 60 seconds with exponential backoff.RATE_LIMIT_MONTHLY: do not retry until the next billing period. - 2FA errors — Follow the resolution column.
2FA_REQUIREDis part of the normal flow, not an error. - Validation errors — Do not retry with the same input. Fix the input value first.
- Payment errors (timeout) — Always check the transaction status via the
check_statustool before retrying. A timed-out request may have still settled on the payment network.
Related pages
- MCP Tools — Full tool reference with parameter schemas
- Two-Factor Auth — 2FA flow and configuration
- License Management — License tiers and the 4-gate model