{
  "name": "BreakPass MCP",
  "updated": "2026-10-23",
  "status": "Live. Example values are illustrative; amounts in cents are placeholders (0), not prices.",
  "docs": "https://breakpass.ai/docs/mcp/",
  "endpoint": "https://mcp.breakpass.ai/mcp",
  "connect": [
    {
      "item": "Endpoint",
      "value": "https://mcp.breakpass.ai/mcp"
    },
    {
      "item": "Transport",
      "value": "HTTP only. No SSE."
    },
    {
      "item": "MCP version",
      "value": "2026-07-28 (stateless requests with Mcp-Method and Mcp-Name headers). Legacy clients are still accepted: 2025-06-18 and 2025-11-25, with initialize and a session."
    },
    {
      "item": "Server info",
      "value": "Name breakpass, title \"BreakPass\". Tool list responses carry ttlMs 3,600,000."
    },
    {
      "item": "Timestamps",
      "value": "ISO 8601 in UTC. The server sends milliseconds, for example 2026-10-03T19:00:00.000Z; the examples leave them out."
    },
    {
      "item": "Tool results",
      "value": "Every tool returns structuredContent (with an outputSchema) and a one-line text summary. No phone number, payment detail or country appears in any tool output, error or log."
    }
  ],
  "serverInstructions": "BreakPass alerts the account owner, and people they invited who confirmed their number with a code, by WhatsApp, SMS or phone call. It can only reach those verified numbers, by the person's name; it can't call, text or message anyone else. Send only what the user asked to be told about. BreakPass reaches the user by WhatsApp, SMS or phone call. `get_setup_status` reports whether the account can send yet and what is left to set up. `list_workflows` returns the saved workflows and when each fits; a workflow_id is one of those. `start_workflow` runs a saved workflow when the user may need follow-up: Inform for no reply, Acknowledge when receipt matters, Escalate when the user must know or act before returning. `send_whatsapp`, `send_sms` and `make_call` send one message or place one call. `start_workflow` takes an idempotency_key. An acknowledgement means the user saw the alert; it is not approval to act. A recipient is a person's name from get_setup_status (owner means the user), not a phone number. Messages are for what the user asked to be told about. BreakPass sends alerts only to the account owner's verified numbers. It can't contact emergency services, and delivery isn't guaranteed, so it isn't designed for emergency or life-safety use.",
  "authorization": [
    {
      "item": "Protocol",
      "value": "OAuth 2.1 with PKCE. S256 only."
    },
    {
      "item": "Resource metadata (RFC 9728)",
      "value": "GET /.well-known/oauth-protected-resource and …/mcp. resource is https://mcp.breakpass.ai/mcp, authorization_servers is https://mcp.breakpass.ai."
    },
    {
      "item": "Authorization server metadata (RFC 8414)",
      "value": "GET /.well-known/oauth-authorization-server. Issuer https://mcp.breakpass.ai. Endpoints /authorize, /token (also revocation) and /register."
    },
    {
      "item": "Client registration",
      "value": "Client ID Metadata Documents (CIMD), or Dynamic Client Registration (deprecated, kept until summer 2027) at /register. No pre-registration."
    },
    {
      "item": "Resource indicators (RFC 8707)",
      "value": "resource is required. Tokens are bound to https://mcp.breakpass.ai/mcp. Other audiences are rejected."
    },
    {
      "item": "Issuer (RFC 9207)",
      "value": "iss on every authorization response, errors included."
    },
    {
      "item": "Tokens",
      "value": "Access token 1 hour. Refresh token 90 days, rotating on use."
    },
    {
      "item": "Unauthenticated",
      "value": "HTTP 401 with WWW-Authenticate: Bearer resource_metadata=\"…\", scope=\"alerts.read alerts.send\". A tool outside the granted scopes gets HTTP 403 insufficient_scope. Authentication failures are never tool errors."
    },
    {
      "item": "Sign-in and consent",
      "value": "/authorize opens BreakPass sign-in (Google or an email code). An email with no account gets \"You need a BreakPass account\"; no account is created here. Then a consent page: the app's name, with a tick when BreakPass recognises the platform; otherwise the name is marked \"(name not verified)\" with \"We can't confirm this app's name.\" Then where access goes, the scopes, the account, and Allow or Deny. Signing in to BreakPass is separate from granting an agent access. A phone number is not needed to connect."
    }
  ],
  "scopes": [
    {
      "scope": "alerts.read",
      "tools": "get_setup_status, list_workflows, get_alert_status",
      "notes": "Read-only. Works from sign-in, before any payment."
    },
    {
      "scope": "alerts.send",
      "tools": "send_whatsapp, send_sms, make_call, start_workflow, cancel_alert",
      "notes": "Sends alerts and stops them. The owner can untick it on the consent page for a read-only connection."
    }
  ],
  "workflows": {
    "inform": {
      "Steps": "Message at minute 0.",
      "Acknowledgement": "Off by default; the owner can switch it on.",
      "SMS fallback": "One, only after a confirmed WhatsApp delivery failure.",
      "Max attempts, fallback included": "2",
      "Stops on": "Delivery, or a bounded delivery failure.",
      "Deadline (initial)": "75 min"
    },
    "acknowledge": {
      "Steps": "Message at minutes 0, 10 and 30, if still unacknowledged.",
      "Acknowledgement": "On by default; the owner can switch it off.",
      "SMS fallback": "Same.",
      "Max attempts, fallback included": "4",
      "Stops on": "Acknowledgement, cancellation, an empty balance, or expiry after the last attempt.",
      "Deadline (initial)": "40 min (last attempt + 10 min grace)."
    },
    "escalate": {
      "Steps": "A WhatsApp message and a call at minute 0; calls at minutes 1 and 2, if still unacknowledged.",
      "Acknowledgement": "On by default; the owner can switch it off.",
      "SMS fallback": "Same (for the minute-0 message).",
      "Max attempts, fallback included": "5",
      "Stops on": "Same.",
      "Deadline (initial)": "12 min (last attempt + 10 min grace)."
    }
  },
  "limits": [
    {
      "scope": "Account",
      "limit": "Until a payment is confirmed, an account can send only setup tests, within these limits: 10 alerts a minute, 100 an hour, 500 a day, and at most 30 alerts and 6 calls a day. Paid plans: no account-wide count cap; the unbilled-sends budget applies to every account."
    },
    {
      "scope": "One holder (recipient)",
      "limit": "20 alerts an hour."
    },
    {
      "scope": "Calls to one holder",
      "limit": "1 at a time, 10 an hour (support can raise it for an account). Free setup-test calls don't count."
    },
    {
      "scope": "Runaway brake",
      "limit": "Accounts without a paid plan: a connection that hits a rate cap 3 times in 10 minutes is paused for 15 minutes. On a paid plan the per-number limits never pause the connection."
    },
    {
      "scope": "Content",
      "limit": "message 600 (150 when the alert includes a call; one SMS part when it goes by SMS), recipient 30, agent_name 30, use_case 40, event_reference 100, idempotency_key 64, workflow_id 40 and alert ids 32 characters; alert_ids 1 to 20. Control characters are stripped."
    }
  ],
  "errorShape": {
    "isError": true,
    "structuredContent": {
      "error": {
        "code": "RATE_LIMITED",
        "message": "Too many alerts to this recipient in the last hour (the limit is 20 an hour).",
        "retry_after_s": 1200,
        "details": {
          "reason": "holder_per_hour"
        }
      }
    }
  },
  "errors": [
    {
      "code": "SETUP_INCOMPLETE",
      "when": "Payment, number verification or the residence confirmation is missing. Details: blockers, setup_url (absent while payment is missing).",
      "retry": "After setup"
    },
    {
      "code": "INSUFFICIENT_BALANCE",
      "when": "Available balance is below the price of the alert or of its next step. Details: price_cents, balance_cents. No link.",
      "retry": "After the owner adds balance in their BreakPass account"
    },
    {
      "code": "RATE_LIMITED",
      "when": "A rate cap, the account's unbilled-sends budget, one call at a time to a number, or the runaway brake applies. retry_after_s (next to code) says when to try again; details.reason names the limit (table below).",
      "retry": "After retry_after_s"
    },
    {
      "code": "RECIPIENT_NOT_FOUND",
      "when": "No one on this account has that name. Use a name from recipients in get_setup_status, or owner for the user's own number.",
      "retry": "No"
    },
    {
      "code": "RECIPIENT_AMBIGUOUS",
      "when": "Two or more people on the account share the name, so nothing was sent. The owner renames one in Settings > Phone numbers.",
      "retry": "After the owner renames one"
    },
    {
      "code": "RECIPIENT_NOT_VERIFIED",
      "when": "The number isn't verified yet, or it is paused because the plan allows fewer numbers. details.reason: pending, plan_limit, or, when no recipient was named, number_not_verified / number_paused.",
      "retry": "After the user verifies the number or picks another one"
    },
    {
      "code": "RECIPIENT_OPTED_OUT",
      "when": "The person stopped all BreakPass alerts to the number (STOP, key 9 or email). Only a new invite and verification restart them.",
      "retry": "No"
    },
    {
      "code": "CHANNEL_UNAVAILABLE",
      "when": "A channel the send or workflow needs is not available for that number. Details: available_channels, unavailable_steps (workflows), channel and reason: not_in_country, coming_soon, no_whatsapp, test_alert_pending, rate_above_max, country_unsupported, country_not_offered, whatsapp_capacity, whatsapp_not_live, sms_ack_us_ca_only, recipient_channel_paused, channel_unavailable. Examples: \"This number isn't on WhatsApp. Use SMS or a call.\", \"BreakPass doesn't reach this country yet.\", \"WhatsApp is paused right now. Use make_call, or send_sms where SMS is offered.\"",
      "retry": "Another channel or workflow"
    },
    {
      "code": "WORKFLOW_NOT_FOUND",
      "when": "Unknown workflow_id. Details: available (the valid ids).",
      "retry": "No"
    },
    {
      "code": "WORKFLOWS_LOCKED",
      "when": "Not returned today (the workflow lock was withdrawn); kept in the contract.",
      "retry": "No"
    },
    {
      "code": "PLAN_LIMIT",
      "when": "Not returned by the tools today; a number paused by the plan returns RECIPIENT_NOT_VERIFIED (reason plan_limit).",
      "retry": "No"
    },
    {
      "code": "ALERT_NOT_FOUND",
      "when": "Unknown id, or the alert is not on this account.",
      "retry": "No"
    },
    {
      "code": "CONTENT_REJECTED",
      "when": "A field breaks a rule: missing, empty, over its limit, the wrong type or format, a message too long for one SMS or for a call, a link shortener or wa.me link, a link in an SMS outside the US and Canada, or emoji only. Details: field, with max_length, rule or shorten_by.",
      "retry": "Fix the input"
    },
    {
      "code": "IDEMPOTENCY_CONFLICT",
      "when": "The same idempotency_key was used with a different payload.",
      "retry": "Use a new key"
    },
    {
      "code": "ACCOUNT_SUSPENDED",
      "when": "The account is suspended (an admin action or a dispute freeze) or closed, or its sends are paused until a number is verified.",
      "retry": "No"
    },
    {
      "code": "PROVIDER_ERROR",
      "when": "A delivery provider returned a server error or timed out, after failover.",
      "retry": "After 30 seconds"
    },
    {
      "code": "TEMPLATE_MISMATCH",
      "when": "A WhatsApp message template failed its check, so the send was refused.",
      "retry": "Later"
    },
    {
      "code": "SERVICE_PAUSED",
      "when": "Sending is paused for this scope (\"Sending is paused right now. Try again later.\"). Details: flag; retry_after_s 300.",
      "retry": "Later"
    }
  ],
  "tools": [
    {
      "name": "get_setup_status",
      "description": "Reports where the account is in setup: readiness states, blockers, the people on the account by name (never phone numbers) with their channels, balance and the next setup link. Call it first and follow its next steps. It sends nothing and costs nothing.",
      "scope": "alerts.read",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      },
      "cost": "No cost. Read-only.",
      "inputSchema": {
        "type": "object",
        "properties": {}
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "account_state": {
            "type": "string",
            "enum": [
              "signed_in",
              "payment_needed",
              "verification_needed",
              "test_needed",
              "ready",
              "suspended"
            ],
            "description": "Where the account is in setup. An agent never sees signed_in or test_needed: a paid account with a verified number reads ready."
          },
          "readiness": {
            "type": "object",
            "properties": {
              "account_connected": {
                "type": "boolean",
                "description": "An agent is connected."
              },
              "delivery_ready": {
                "type": "boolean",
                "description": "true once the account can send (paid, with a verified number)."
              },
              "agent_guidance_configured": {
                "type": "boolean",
                "description": "Ticked by the owner in the BreakPass app. BreakPass cannot verify an agent's memory."
              }
            },
            "required": [
              "account_connected",
              "delivery_ready",
              "agent_guidance_configured"
            ],
            "description": "Separate readiness states. Installing MCP or paying does not set them all."
          },
          "onboarding_complete": {
            "type": "boolean",
            "description": "true once setup is complete. For information only: start_workflow and the direct sends work as soon as the account can send (delivery_ready)."
          },
          "blockers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "description": "Blocker code."
                },
                "message": {
                  "type": "string",
                  "description": "Readable reason."
                },
                "action_url": {
                  "type": "string",
                  "description": "Where the owner fixes it. Absent while payment is missing."
                }
              },
              "required": [
                "code",
                "message"
              ]
            },
            "description": "What still blocks sending."
          },
          "recipients": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "description": "The person's name as saved in Settings > Phone numbers. The owner shows as the Name from Settings, else Owner; once another number is picked in Settings > Your number, the owner's own number keeps its name (or Previous number). Use it as recipient (any case)."
                },
                "is_owner": {
                  "type": "boolean",
                  "description": "Whether this person is the owner: the number picked in Settings > Your number, by default the owner's own."
                },
                "verified": {
                  "type": "boolean",
                  "description": "Whether the person confirmed the number with a code."
                },
                "channels": {
                  "type": "object",
                  "properties": {
                    "whatsapp": {
                      "type": "string",
                      "enum": [
                        "yes",
                        "no",
                        "unknown"
                      ],
                      "description": "WhatsApp capability."
                    },
                    "sms": {
                      "type": "string",
                      "enum": [
                        "available",
                        "coming_soon",
                        "unavailable"
                      ],
                      "description": "SMS capability."
                    },
                    "call": {
                      "type": "string",
                      "enum": [
                        "available",
                        "unavailable"
                      ],
                      "description": "Call capability."
                    }
                  },
                  "required": [
                    "whatsapp",
                    "sms",
                    "call"
                  ],
                  "description": "Channel capability for this person's number."
                },
                "price_cents": {
                  "type": "object",
                  "description": "Price per channel, in US cents: an object with whatsapp, sms and call, each an integer, or null where that channel isn't offered."
                },
                "max_chars": {
                  "type": "object",
                  "description": "The longest message each channel takes for this number, in characters: an object with whatsapp, sms, sms_confirm_link (an SMS that carries the confirmation link; null outside the US and Canada, where no SMS carries a link) and call, each an integer, or null where that channel isn't offered. SMS counts the +1 footer or the \"BreakPass: \" prefix. A reminder number (\"Reminder 2 of 3: \") takes room on top."
                }
              },
              "required": [
                "name",
                "is_owner",
                "verified",
                "channels",
                "price_cents",
                "max_chars"
              ]
            },
            "description": "The people on the account, one entry each, by the name your agent sends as recipient. Never phone numbers."
          },
          "default_recipient": {
            "type": [
              "string",
              "null"
            ],
            "description": "The name of the person an alert reaches when the agent names no recipient: the number picked in Settings > Your number (the owner, is_owner true), else the owner's own number. null before the account has an owner number."
          },
          "owner_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The owner's name as saved in Settings, for a greeting, or null. Never a phone number."
          },
          "balance_cents": {
            "type": "integer",
            "description": "US cents the owner can spend now."
          },
          "reserved_cents": {
            "type": "integer",
            "description": "US cents held for alerts that are still running."
          },
          "spent_today_cents": {
            "type": "integer",
            "description": "US cents spent today."
          },
          "workflows_version": {
            "type": "integer",
            "description": "Version of the saved workflows."
          },
          "setup_url": {
            "type": "string",
            "description": "Where the owner finishes setup. Absent while payment is missing."
          }
        },
        "required": [
          "account_state",
          "readiness",
          "onboarding_complete",
          "blockers",
          "recipients",
          "default_recipient",
          "owner_name",
          "balance_cents",
          "reserved_cents",
          "spent_today_cents",
          "workflows_version"
        ]
      },
      "errors": [
        "ACCOUNT_SUSPENDED"
      ],
      "example": {
        "request": {
          "name": "get_setup_status",
          "arguments": {}
        },
        "response": {
          "account_state": "ready",
          "readiness": {
            "account_connected": true,
            "delivery_ready": true,
            "agent_guidance_configured": false
          },
          "onboarding_complete": true,
          "blockers": [],
          "recipients": [
            {
              "name": "Sam",
              "is_owner": true,
              "verified": true,
              "channels": {
                "whatsapp": "yes",
                "sms": "coming_soon",
                "call": "available"
              },
              "price_cents": {
                "whatsapp": 0,
                "sms": null,
                "call": 0
              },
              "max_chars": {
                "whatsapp": 600,
                "sms": null,
                "sms_confirm_link": null,
                "call": 150
              }
            }
          ],
          "default_recipient": "Sam",
          "owner_name": "Sam",
          "balance_cents": 2400,
          "reserved_cents": 0,
          "spent_today_cents": 0,
          "workflows_version": 1,
          "setup_url": "https://app.breakpass.ai/start"
        }
      }
    },
    {
      "name": "list_workflows",
      "description": "Lists the saved alert workflows (Inform, Acknowledge, Escalate) with their ids, readable steps, limits and version. It reads the current configuration on every call, so changes the owner makes in the BreakPass app show up on the next read. It sends nothing and costs nothing.",
      "scope": "alerts.read",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      },
      "cost": "No cost. Read-only.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "recipient": {
            "type": "string",
            "minLength": 1,
            "maxLength": 30,
            "description": "A person's name, so max_cost_cents is priced for that person's number. Default: the owner."
          }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "description": "Version of the workflow set."
          },
          "updated_at": {
            "type": "string",
            "description": "When the set last changed (timestamp)."
          },
          "recipient": {
            "type": "string",
            "description": "The name the costs are worked out for: recipient from the input, else the default recipient."
          },
          "workflows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workflow_id": {
                  "type": "string",
                  "enum": [
                    "inform",
                    "acknowledge",
                    "escalate"
                  ],
                  "description": "Id to pass to start_workflow."
                },
                "name": {
                  "type": "string",
                  "description": "Display name."
                },
                "summary": {
                  "type": "string",
                  "description": "One line on what the workflow does."
                },
                "use_when": {
                  "type": "string",
                  "description": "When to use this workflow."
                },
                "version": {
                  "type": "integer",
                  "description": "Version of this workflow."
                },
                "steps": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "offset_min": {
                        "type": "integer",
                        "description": "Minutes from the first alert, not from the previous step."
                      },
                      "kind": {
                        "type": "string",
                        "enum": [
                          "message",
                          "call"
                        ],
                        "description": "Kind of step."
                      },
                      "channel": {
                        "type": "string",
                        "enum": [
                          "whatsapp",
                          "sms",
                          "call"
                        ],
                        "description": "The channel this step uses for the recipient."
                      }
                    },
                    "required": [
                      "offset_min",
                      "kind",
                      "channel"
                    ]
                  },
                  "description": "The readable steps, with the channel each uses for the recipient."
                },
                "ack_required_default": {
                  "type": "boolean",
                  "description": "Whether the workflow asks for acknowledgement (the same value as requires_acknowledgement)."
                },
                "requires_acknowledgement": {
                  "type": "boolean",
                  "description": "Whether the workflow asks for acknowledgement, as the owner set it with the \"Wait for acknowledgement\" switch."
                },
                "sms_fallback": {
                  "type": "boolean",
                  "description": "Whether one SMS fallback is allowed after a confirmed WhatsApp delivery failure. It is false when the workflow's steps already fill max_attempts, because the fallback is an attempt of its own."
                },
                "max_attempts": {
                  "type": "integer",
                  "description": "Most attempts in one run, fallback included."
                },
                "deadline_min": {
                  "type": "integer",
                  "description": "Minutes after which the alert ends."
                },
                "max_cost_cents": {
                  "type": "integer",
                  "description": "Worst-case cost in US cents, for information. Reflects the holder in recipient when given."
                },
                "available": {
                  "type": "boolean",
                  "description": "Whether every step has a channel for the recipient."
                },
                "editable_in": {
                  "type": "string",
                  "enum": [
                    "portal"
                  ],
                  "description": "Where the owner edits this workflow (the BreakPass app)."
                }
              },
              "required": [
                "workflow_id",
                "name",
                "summary",
                "use_when",
                "version",
                "steps",
                "ack_required_default",
                "requires_acknowledgement",
                "sms_fallback",
                "max_attempts",
                "deadline_min",
                "max_cost_cents",
                "available",
                "editable_in"
              ]
            },
            "description": "The saved workflows."
          },
          "decision_model": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "matrix_enabled": {
                "type": "boolean",
                "description": "Whether the matrix is on."
              },
              "urgency_threshold": {
                "type": "integer",
                "description": "Score from which urgency counts as high."
              },
              "importance_threshold": {
                "type": "integer",
                "description": "Score from which importance counts as high."
              }
            },
            "required": [
              "matrix_enabled",
              "urgency_threshold",
              "importance_threshold"
            ],
            "description": "null unless the owner turned on the advanced decision matrix."
          }
        },
        "required": [
          "version",
          "updated_at",
          "recipient",
          "workflows",
          "decision_model"
        ]
      },
      "errors": [
        "RECIPIENT_NOT_FOUND",
        "RECIPIENT_AMBIGUOUS"
      ],
      "example": {
        "request": {
          "name": "list_workflows",
          "arguments": {
            "recipient": "owner"
          }
        },
        "response": {
          "version": 1,
          "updated_at": "2026-10-03T09:00:00Z",
          "recipient": "owner",
          "workflows": [
            {
              "workflow_id": "inform",
              "name": "Inform",
              "summary": "Message at minute 0. No acknowledgement. One SMS if a WhatsApp message can't be delivered.",
              "use_when": "The user only needs to know. One message, no reply needed.",
              "version": 1,
              "steps": [
                {
                  "offset_min": 0,
                  "kind": "message",
                  "channel": "whatsapp"
                }
              ],
              "ack_required_default": false,
              "requires_acknowledgement": false,
              "sms_fallback": true,
              "max_attempts": 2,
              "deadline_min": 75,
              "max_cost_cents": 0,
              "available": true,
              "editable_in": "portal"
            },
            {
              "workflow_id": "acknowledge",
              "name": "Acknowledge",
              "summary": "Messages at minutes 0, 10 and 30, then it stops; an acknowledgement stops it sooner. One SMS if a WhatsApp message can't be delivered.",
              "use_when": "It matters that the user saw it. Up to 3 messages, at 0, 10 and 30 minutes, until acknowledged.",
              "version": 1,
              "steps": [
                {
                  "offset_min": 0,
                  "kind": "message",
                  "channel": "whatsapp"
                },
                {
                  "offset_min": 10,
                  "kind": "message",
                  "channel": "whatsapp"
                },
                {
                  "offset_min": 30,
                  "kind": "message",
                  "channel": "whatsapp"
                }
              ],
              "ack_required_default": true,
              "requires_acknowledgement": true,
              "sms_fallback": true,
              "max_attempts": 4,
              "deadline_min": 40,
              "max_cost_cents": 0,
              "available": true,
              "editable_in": "portal"
            },
            {
              "workflow_id": "escalate",
              "name": "Escalate",
              "summary": "Message at minute 0; calls at minutes 0, 1 and 2, then it stops; an acknowledgement stops it sooner. One SMS if a WhatsApp message can't be delivered.",
              "use_when": "The user must know or act before returning. A message and a call at once, then calls at 1 and 2 minutes; 3 calls in all.",
              "version": 1,
              "steps": [
                {
                  "offset_min": 0,
                  "kind": "message",
                  "channel": "whatsapp"
                },
                {
                  "offset_min": 0,
                  "kind": "call",
                  "channel": "call"
                },
                {
                  "offset_min": 1,
                  "kind": "call",
                  "channel": "call"
                },
                {
                  "offset_min": 2,
                  "kind": "call",
                  "channel": "call"
                }
              ],
              "ack_required_default": true,
              "requires_acknowledgement": true,
              "sms_fallback": true,
              "max_attempts": 5,
              "deadline_min": 12,
              "max_cost_cents": 0,
              "available": true,
              "editable_in": "portal"
            }
          ],
          "decision_model": null
        }
      }
    },
    {
      "name": "send_whatsapp",
      "description": "Sends one WhatsApp message to a verified number. This spends the owner's balance and contacts a real person. One attempt: no retries and no follow-up. For repeated attempts use start_workflow.",
      "scope": "alerts.send",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": false,
        "openWorldHint": true
      },
      "cost": "The cost is reserved when you call and charged when the message is delivered. A message that is not delivered is released. The price per alert for each country and channel is shown in the owner's BreakPass account. Amounts are in US cents (USD).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "maxLength": 600,
            "description": "One line of plain text (line breaks become spaces or full stops; markdown, HTML and invisible characters are removed), 600 characters at most. At most 150 characters when the alert includes a call (make_call, or a workflow with calls such as escalate), because a call is cut off 55 seconds after it is answered; under 150 reads well on every channel. An SMS is one part and is not cut. To a US or Canadian (+1) number it ends with a blank line and \"This is an automated BreakPass alert. Reply STOP to opt out.\", which leaves 98 characters for the message (8 when it has a character outside the SMS alphabet, such as ł). Where the SMS sender shows as a number (AR, BE, CL, CO, IN, MX) it starts with \"BreakPass: \": 149 characters (59). To other countries there is no footer and no prefix: 160 characters (70). To a US or Canadian number a confirmation link (require_ack, or a workflow that asks for acknowledgement) takes 37 characters; a reminder number (\"Reminder 2 of 3: \") takes room too; get_setup_status gives each number's room per channel (max_chars). An alert that goes by SMS with a longer message is refused with the number of characters to remove, and a WhatsApp alert's SMS fallback is not sent when the text does not fit one SMS. At most one link, a full https address, no link shorteners and no wa.me links.",
            "minLength": 1
          },
          "recipient": {
            "type": "string",
            "minLength": 1,
            "maxLength": 30,
            "description": "A person's name from recipients in get_setup_status, as saved in Settings > Phone numbers (any case, at most 30 characters); owner is the owner: the number picked in Settings > Your number, by default the owner's own. Default: the owner. No other destination parameter exists: no tool accepts a phone number."
          },
          "agent_name": {
            "type": "string",
            "maxLength": 30,
            "description": "The sender name the person sees (a call says \"with an alert from\" this name), 1 to 30 characters. Default: the connected app's name.",
            "minLength": 1
          },
          "use_case": {
            "type": "string",
            "maxLength": 40,
            "pattern": "^[a-z0-9 -]*$",
            "description": "Optional label, 40 characters at most, lowercase a-z, 0-9, space and -."
          },
          "event_reference": {
            "type": "string",
            "maxLength": 100,
            "description": "Optional. Your own id for the event, 100 characters at most.",
            "minLength": 1
          },
          "idempotency_key": {
            "type": "string",
            "maxLength": 64,
            "description": "Optional, 64 characters at most. Same key and same payload within 24 hours returns the original alert with idempotent_replay: true. Same key with a different payload returns IDEMPOTENCY_CONFLICT.",
            "minLength": 1
          },
          "require_ack": {
            "type": "boolean",
            "default": false,
            "description": "Default false. When true, the message carries the Acknowledge button. The alert then stays open for an acknowledgement window of 60 minutes from when it is accepted (deadline_at, initial value) and ends as expired if nobody acknowledges. It never retries. Acknowledging confirms receipt. It never approves anything."
          }
        },
        "required": [
          "message"
        ]
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "alert_id": {
            "type": "string",
            "description": "Public alert id, for example A-7K3Q9X."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued"
            ],
            "description": "Always queued. Without an idempotency_key, the same recipient, channel and message within 60 seconds returns the original alert with idempotent_replay: true; nothing is charged."
          },
          "channel": {
            "type": "string",
            "enum": [
              "whatsapp",
              "sms",
              "call"
            ],
            "description": "The channel used."
          },
          "recipient": {
            "type": "string",
            "description": "The person's name."
          },
          "estimated_cost_cents": {
            "type": "integer",
            "description": "What this send is expected to cost, in US cents (0 for a free setup test). The final amount is charged_cents in get_alert_status."
          },
          "require_ack": {
            "type": "boolean",
            "description": "Whether acknowledgement was requested."
          },
          "deadline_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the acknowledgement window ends, or null when no acknowledgement was requested (timestamp)."
          },
          "idempotent_replay": {
            "type": "boolean",
            "description": "true when this response repeats an earlier request: the same idempotency_key, or the same send within 60 seconds."
          },
          "notice": {
            "type": "string",
            "description": "Present once the account has 5 failed sends today (while that rule is switched on). It reads: \"From now on today, texts that carriers block as spam are charged at the normal price.\""
          }
        },
        "required": [
          "alert_id",
          "status",
          "channel",
          "recipient",
          "estimated_cost_cents",
          "require_ack",
          "deadline_at",
          "idempotent_replay"
        ]
      },
      "errors": [
        "SETUP_INCOMPLETE",
        "INSUFFICIENT_BALANCE",
        "RATE_LIMITED",
        "RECIPIENT_NOT_FOUND",
        "RECIPIENT_AMBIGUOUS",
        "RECIPIENT_NOT_VERIFIED",
        "RECIPIENT_OPTED_OUT",
        "CHANNEL_UNAVAILABLE",
        "CONTENT_REJECTED",
        "IDEMPOTENCY_CONFLICT",
        "ACCOUNT_SUSPENDED",
        "PROVIDER_ERROR",
        "SERVICE_PAUSED",
        "TEMPLATE_MISMATCH"
      ],
      "example": {
        "request": {
          "name": "send_whatsapp",
          "arguments": {
            "message": "Checkout is failing.",
            "recipient": "owner",
            "agent_name": "Checkout monitor",
            "use_case": "checkout",
            "require_ack": false,
            "idempotency_key": "checkout-failing-2026-10-03-1"
          }
        },
        "response": {
          "alert_id": "A-7K3Q9X",
          "status": "queued",
          "channel": "whatsapp",
          "recipient": "owner",
          "estimated_cost_cents": 0,
          "require_ack": false,
          "deadline_at": null,
          "idempotent_replay": false
        }
      }
    },
    {
      "name": "send_sms",
      "description": "Sends one SMS to a verified number. This spends the owner's balance and contacts a real person. One attempt: no retries and no follow-up. The text is never cut: a message that does not fit one SMS is refused (see message). SMS is not offered in every country; where it is not, the tool returns CHANNEL_UNAVAILABLE.",
      "scope": "alerts.send",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": false,
        "openWorldHint": true
      },
      "cost": "The cost is reserved when you call and charged when the SMS is delivered, or when the carrier accepts it without a receipt. It is released if sending fails. The price per alert for each country and channel is shown in the owner's BreakPass account. Amounts are in US cents (USD).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "maxLength": 600,
            "description": "One line of plain text (line breaks become spaces or full stops; markdown, HTML and invisible characters are removed), 600 characters at most. At most 150 characters when the alert includes a call (make_call, or a workflow with calls such as escalate), because a call is cut off 55 seconds after it is answered; under 150 reads well on every channel. An SMS is one part and is not cut. To a US or Canadian (+1) number it ends with a blank line and \"This is an automated BreakPass alert. Reply STOP to opt out.\", which leaves 98 characters for the message (8 when it has a character outside the SMS alphabet, such as ł). Where the SMS sender shows as a number (AR, BE, CL, CO, IN, MX) it starts with \"BreakPass: \": 149 characters (59). To other countries there is no footer and no prefix: 160 characters (70). To a US or Canadian number a confirmation link (require_ack, or a workflow that asks for acknowledgement) takes 37 characters; a reminder number (\"Reminder 2 of 3: \") takes room too; get_setup_status gives each number's room per channel (max_chars). An alert that goes by SMS with a longer message is refused with the number of characters to remove, and a WhatsApp alert's SMS fallback is not sent when the text does not fit one SMS. At most one link, a full https address, no link shorteners and no wa.me links.",
            "minLength": 1
          },
          "recipient": {
            "type": "string",
            "minLength": 1,
            "maxLength": 30,
            "description": "A person's name from recipients in get_setup_status, as saved in Settings > Phone numbers (any case, at most 30 characters); owner is the owner: the number picked in Settings > Your number, by default the owner's own. Default: the owner. No other destination parameter exists: no tool accepts a phone number."
          },
          "agent_name": {
            "type": "string",
            "maxLength": 30,
            "description": "The sender name the person sees (a call says \"with an alert from\" this name), 1 to 30 characters. Default: the connected app's name.",
            "minLength": 1
          },
          "use_case": {
            "type": "string",
            "maxLength": 40,
            "pattern": "^[a-z0-9 -]*$",
            "description": "Optional label, 40 characters at most, lowercase a-z, 0-9, space and -."
          },
          "event_reference": {
            "type": "string",
            "maxLength": 100,
            "description": "Optional. Your own id for the event, 100 characters at most.",
            "minLength": 1
          },
          "idempotency_key": {
            "type": "string",
            "maxLength": 64,
            "description": "Optional, 64 characters at most. Same key and same payload within 24 hours returns the original alert with idempotent_replay: true. Same key with a different payload returns IDEMPOTENCY_CONFLICT.",
            "minLength": 1
          },
          "require_ack": {
            "type": "boolean",
            "default": false,
            "description": "Default false. When true, the SMS carries a link to a page where the holder confirms (US and Canadian numbers only). Opening the link changes nothing; the holder presses a button on the page. Outside the US and Canada an SMS carries no link, so send_sms with require_ack is refused there (CHANNEL_UNAVAILABLE: \"An SMS can be acknowledged only on a US or Canadian number. Send it without acknowledgement, or by WhatsApp or a call.\"). The alert then stays open for an acknowledgement window of 60 minutes from when it is accepted (deadline_at, initial value) and ends as expired if nobody acknowledges. It never retries. Acknowledging confirms receipt. It never approves anything."
          }
        },
        "required": [
          "message"
        ]
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "alert_id": {
            "type": "string",
            "description": "Public alert id, for example A-7K3Q9X."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued"
            ],
            "description": "Always queued. Without an idempotency_key, the same recipient, channel and message within 60 seconds returns the original alert with idempotent_replay: true; nothing is charged."
          },
          "channel": {
            "type": "string",
            "enum": [
              "whatsapp",
              "sms",
              "call"
            ],
            "description": "The channel used."
          },
          "recipient": {
            "type": "string",
            "description": "The person's name."
          },
          "estimated_cost_cents": {
            "type": "integer",
            "description": "What this send is expected to cost, in US cents (0 for a free setup test). The final amount is charged_cents in get_alert_status."
          },
          "require_ack": {
            "type": "boolean",
            "description": "Whether acknowledgement was requested."
          },
          "deadline_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the acknowledgement window ends, or null when no acknowledgement was requested (timestamp)."
          },
          "idempotent_replay": {
            "type": "boolean",
            "description": "true when this response repeats an earlier request: the same idempotency_key, or the same send within 60 seconds."
          },
          "notice": {
            "type": "string",
            "description": "Present once the account has 5 failed sends today (while that rule is switched on). It reads: \"From now on today, texts that carriers block as spam are charged at the normal price.\""
          }
        },
        "required": [
          "alert_id",
          "status",
          "channel",
          "recipient",
          "estimated_cost_cents",
          "require_ack",
          "deadline_at",
          "idempotent_replay"
        ]
      },
      "errors": [
        "SETUP_INCOMPLETE",
        "INSUFFICIENT_BALANCE",
        "RATE_LIMITED",
        "RECIPIENT_NOT_FOUND",
        "RECIPIENT_AMBIGUOUS",
        "RECIPIENT_NOT_VERIFIED",
        "RECIPIENT_OPTED_OUT",
        "CHANNEL_UNAVAILABLE",
        "CONTENT_REJECTED",
        "IDEMPOTENCY_CONFLICT",
        "ACCOUNT_SUSPENDED",
        "PROVIDER_ERROR",
        "SERVICE_PAUSED"
      ],
      "example": {
        "request": {
          "name": "send_sms",
          "arguments": {
            "message": "A refund over $200 waits for your OK.",
            "recipient": "owner",
            "use_case": "refunds",
            "require_ack": true
          }
        },
        "response": {
          "alert_id": "A-4M8TQ2",
          "status": "queued",
          "channel": "sms",
          "recipient": "owner",
          "estimated_cost_cents": 0,
          "require_ack": true,
          "deadline_at": "2026-10-03T20:05:00Z",
          "idempotent_replay": false
        }
      }
    },
    {
      "name": "make_call",
      "description": "Phones a verified number and reads the message out loud (at most 150 characters; a call is cut off 55 seconds after it is answered). This spends the owner's balance and contacts a real person. One attempt: no redial and no follow-up. A voicemail ends the attempt and no message is left. For repeated calls use start_workflow.",
      "scope": "alerts.send",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": false,
        "openWorldHint": true
      },
      "cost": "The cost is reserved when you call and charged by the outcome of the call (Terms, \"When a charge applies\"): a call answered by a person or voicemail costs the price shown, and a call that isn't picked up costs a reduced fee. The rest is released. The price for each country and channel is shown in the owner's BreakPass account. Amounts are in US cents (USD).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "maxLength": 600,
            "description": "One line of plain text (line breaks become spaces or full stops; markdown, HTML and invisible characters are removed), 600 characters at most. At most 150 characters when the alert includes a call (make_call, or a workflow with calls such as escalate), because a call is cut off 55 seconds after it is answered; under 150 reads well on every channel. An SMS is one part and is not cut. To a US or Canadian (+1) number it ends with a blank line and \"This is an automated BreakPass alert. Reply STOP to opt out.\", which leaves 98 characters for the message (8 when it has a character outside the SMS alphabet, such as ł). Where the SMS sender shows as a number (AR, BE, CL, CO, IN, MX) it starts with \"BreakPass: \": 149 characters (59). To other countries there is no footer and no prefix: 160 characters (70). To a US or Canadian number a confirmation link (require_ack, or a workflow that asks for acknowledgement) takes 37 characters; a reminder number (\"Reminder 2 of 3: \") takes room too; get_setup_status gives each number's room per channel (max_chars). An alert that goes by SMS with a longer message is refused with the number of characters to remove, and a WhatsApp alert's SMS fallback is not sent when the text does not fit one SMS. At most one link, a full https address, no link shorteners and no wa.me links.",
            "minLength": 1
          },
          "recipient": {
            "type": "string",
            "minLength": 1,
            "maxLength": 30,
            "description": "A person's name from recipients in get_setup_status, as saved in Settings > Phone numbers (any case, at most 30 characters); owner is the owner: the number picked in Settings > Your number, by default the owner's own. Default: the owner. No other destination parameter exists: no tool accepts a phone number."
          },
          "agent_name": {
            "type": "string",
            "maxLength": 30,
            "description": "The sender name the person sees (a call says \"with an alert from\" this name), 1 to 30 characters. Default: the connected app's name.",
            "minLength": 1
          },
          "use_case": {
            "type": "string",
            "maxLength": 40,
            "pattern": "^[a-z0-9 -]*$",
            "description": "Optional label, 40 characters at most, lowercase a-z, 0-9, space and -."
          },
          "event_reference": {
            "type": "string",
            "maxLength": 100,
            "description": "Optional. Your own id for the event, 100 characters at most.",
            "minLength": 1
          },
          "idempotency_key": {
            "type": "string",
            "maxLength": 64,
            "description": "Optional, 64 characters at most. Same key and same payload within 24 hours returns the original alert with idempotent_replay: true. Same key with a different payload returns IDEMPOTENCY_CONFLICT.",
            "minLength": 1
          },
          "require_ack": {
            "type": "boolean",
            "default": false,
            "description": "Default false. When true, the call says \"Press 1 to acknowledge.\" after the message; pressing 1 at any point in the call acknowledges. The alert then stays open for an acknowledgement window of 60 minutes from when it is accepted (deadline_at, initial value) and ends as expired if nobody acknowledges. It never retries. Acknowledging confirms receipt. It never approves anything."
          }
        },
        "required": [
          "message"
        ]
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "alert_id": {
            "type": "string",
            "description": "Public alert id, for example A-7K3Q9X."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued"
            ],
            "description": "Always queued. Without an idempotency_key, the same recipient, channel and message within 60 seconds returns the original alert with idempotent_replay: true; nothing is charged."
          },
          "channel": {
            "type": "string",
            "enum": [
              "whatsapp",
              "sms",
              "call"
            ],
            "description": "The channel used."
          },
          "recipient": {
            "type": "string",
            "description": "The person's name."
          },
          "estimated_cost_cents": {
            "type": "integer",
            "description": "What this send is expected to cost, in US cents (0 for a free setup test). The final amount is charged_cents in get_alert_status."
          },
          "require_ack": {
            "type": "boolean",
            "description": "Whether acknowledgement was requested."
          },
          "deadline_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the acknowledgement window ends, or null when no acknowledgement was requested (timestamp)."
          },
          "idempotent_replay": {
            "type": "boolean",
            "description": "true when this response repeats an earlier request: the same idempotency_key, or the same send within 60 seconds."
          },
          "notice": {
            "type": "string",
            "description": "Present once the account has 5 failed sends today (while that rule is switched on). It reads: \"From now on today, texts that carriers block as spam are charged at the normal price.\""
          }
        },
        "required": [
          "alert_id",
          "status",
          "channel",
          "recipient",
          "estimated_cost_cents",
          "require_ack",
          "deadline_at",
          "idempotent_replay"
        ]
      },
      "errors": [
        "SETUP_INCOMPLETE",
        "INSUFFICIENT_BALANCE",
        "RATE_LIMITED",
        "RECIPIENT_NOT_FOUND",
        "RECIPIENT_AMBIGUOUS",
        "RECIPIENT_NOT_VERIFIED",
        "RECIPIENT_OPTED_OUT",
        "CHANNEL_UNAVAILABLE",
        "CONTENT_REJECTED",
        "IDEMPOTENCY_CONFLICT",
        "ACCOUNT_SUSPENDED",
        "PROVIDER_ERROR",
        "SERVICE_PAUSED"
      ],
      "example": {
        "request": {
          "name": "make_call",
          "arguments": {
            "message": "Checkout is failing.",
            "recipient": "owner",
            "require_ack": true,
            "idempotency_key": "checkout-failing-call-1"
          }
        },
        "response": {
          "alert_id": "A-2R6WZ5",
          "status": "queued",
          "channel": "call",
          "recipient": "owner",
          "estimated_cost_cents": 0,
          "require_ack": true,
          "deadline_at": "2026-10-03T20:05:00Z",
          "idempotent_replay": false
        }
      }
    },
    {
      "name": "start_workflow",
      "description": "Starts a saved workflow on BreakPass servers. The timers run on our side until the owner acknowledges or a stop rule applies, so the alert keeps going if your agent restarts. This spends the owner's balance and contacts a real person. Retries are always limited. The alert snapshots the workflow version: edits affect new alerts only. Poll get_alert_status; do not call again.",
      "scope": "alerts.send",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": true
      },
      "cost": "The balance is held one step at a time: the first step when you call, each later step when it's due, up to the worst case (max_cost_cents, for information). A step the balance can't cover isn't sent, and the alert ends failed with INSUFFICIENT_BALANCE. Each attempt is charged on its own: a message when it is delivered, a call by its outcome (Terms, \"When a charge applies\"). Everything else is released when the alert ends or the owner acknowledges. The price per alert for each country and channel is shown in the owner's BreakPass account. Amounts are in US cents (USD).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "workflow_id": {
            "type": "string",
            "maxLength": 40,
            "pattern": "^[a-z0-9_]{1,40}$",
            "description": "One of the ids list_workflows returns (today inform, acknowledge, escalate); an unknown id returns WORKFLOW_NOT_FOUND with the valid ids in details.available."
          },
          "message": {
            "type": "string",
            "maxLength": 600,
            "description": "One line of plain text (line breaks become spaces or full stops; markdown, HTML and invisible characters are removed), 600 characters at most. At most 150 characters when the alert includes a call (make_call, or a workflow with calls such as escalate), because a call is cut off 55 seconds after it is answered; under 150 reads well on every channel. An SMS is one part and is not cut. To a US or Canadian (+1) number it ends with a blank line and \"This is an automated BreakPass alert. Reply STOP to opt out.\", which leaves 98 characters for the message (8 when it has a character outside the SMS alphabet, such as ł). Where the SMS sender shows as a number (AR, BE, CL, CO, IN, MX) it starts with \"BreakPass: \": 149 characters (59). To other countries there is no footer and no prefix: 160 characters (70). To a US or Canadian number a confirmation link (require_ack, or a workflow that asks for acknowledgement) takes 37 characters; a reminder number (\"Reminder 2 of 3: \") takes room too; get_setup_status gives each number's room per channel (max_chars). An alert that goes by SMS with a longer message is refused with the number of characters to remove, and a WhatsApp alert's SMS fallback is not sent when the text does not fit one SMS. At most one link, a full https address, no link shorteners and no wa.me links.",
            "minLength": 1
          },
          "recipient": {
            "type": "string",
            "minLength": 1,
            "maxLength": 30,
            "description": "A person's name from recipients in get_setup_status, as saved in Settings > Phone numbers (any case, at most 30 characters); owner is the owner: the number picked in Settings > Your number, by default the owner's own. Default: the owner. No other destination parameter exists: no tool accepts a phone number."
          },
          "agent_name": {
            "type": "string",
            "maxLength": 30,
            "description": "The sender name the person sees (a call says \"with an alert from\" this name), 1 to 30 characters. Default: the connected app's name.",
            "minLength": 1
          },
          "use_case": {
            "type": "string",
            "maxLength": 40,
            "pattern": "^[a-z0-9 -]*$",
            "description": "Optional label, 40 characters at most, lowercase a-z, 0-9, space and -."
          },
          "event_reference": {
            "type": "string",
            "maxLength": 100,
            "description": "Optional. Your own id for the event, 100 characters at most.",
            "minLength": 1
          },
          "idempotency_key": {
            "type": "string",
            "maxLength": 64,
            "description": "Required, 64 characters at most. Same key and same payload within 24 hours returns the original alert with idempotent_replay: true: no new send and no charge. Same key with a different payload returns IDEMPOTENCY_CONFLICT.",
            "minLength": 1
          }
        },
        "required": [
          "workflow_id",
          "message",
          "idempotency_key"
        ]
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "alert_id": {
            "type": "string",
            "description": "Public alert id."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued"
            ],
            "description": "Always queued."
          },
          "workflow": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "enum": [
                  "inform",
                  "acknowledge",
                  "escalate"
                ],
                "description": "Workflow id."
              },
              "name": {
                "type": "string",
                "description": "Workflow name."
              },
              "version": {
                "type": "integer",
                "description": "Version snapshotted into this alert."
              }
            },
            "required": [
              "id",
              "name",
              "version"
            ],
            "description": "The workflow that was started."
          },
          "steps": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "offset_min": {
                  "type": "integer",
                  "description": "Minutes from the first alert, not from the previous step."
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "message",
                    "call"
                  ],
                  "description": "Kind of step."
                },
                "channel": {
                  "type": "string",
                  "enum": [
                    "whatsapp",
                    "sms",
                    "call"
                  ],
                  "description": "The channel this step uses for the recipient."
                }
              },
              "required": [
                "offset_min",
                "kind",
                "channel"
              ]
            },
            "description": "The steps as they run for this recipient."
          },
          "recipient": {
            "type": "string",
            "description": "The person's name."
          },
          "require_ack": {
            "type": "boolean",
            "description": "Whether acknowledgement is on for this workflow."
          },
          "requires_acknowledgement": {
            "type": "boolean",
            "description": "Whether this alert asks for acknowledgement: the workflow's setting when it started."
          },
          "max_cost_cents": {
            "type": "integer",
            "description": "The most this alert can cost, in US cents, for information."
          },
          "deadline_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the alert ends if nothing else stops it (timestamp)."
          },
          "idempotent_replay": {
            "type": "boolean",
            "description": "true when this response repeats an earlier request with the same idempotency_key."
          },
          "next_step": {
            "type": "string",
            "description": "Guidance for the agent: \"Poll get_alert_status; do not call start_workflow again.\""
          },
          "notice": {
            "type": "string",
            "description": "Present once the account has 5 failed sends today (while that rule is switched on). It reads: \"From now on today, texts that carriers block as spam are charged at the normal price.\""
          }
        },
        "required": [
          "alert_id",
          "status",
          "workflow",
          "steps",
          "recipient",
          "require_ack",
          "requires_acknowledgement",
          "max_cost_cents",
          "deadline_at",
          "idempotent_replay",
          "next_step"
        ]
      },
      "errors": [
        "SETUP_INCOMPLETE",
        "INSUFFICIENT_BALANCE",
        "RATE_LIMITED",
        "RECIPIENT_NOT_FOUND",
        "RECIPIENT_AMBIGUOUS",
        "RECIPIENT_NOT_VERIFIED",
        "RECIPIENT_OPTED_OUT",
        "CHANNEL_UNAVAILABLE",
        "CONTENT_REJECTED",
        "IDEMPOTENCY_CONFLICT",
        "ACCOUNT_SUSPENDED",
        "PROVIDER_ERROR",
        "SERVICE_PAUSED",
        "WORKFLOW_NOT_FOUND",
        "TEMPLATE_MISMATCH"
      ],
      "example": {
        "request": {
          "name": "start_workflow",
          "arguments": {
            "workflow_id": "escalate",
            "message": "Checkout is failing.",
            "recipient": "owner",
            "agent_name": "Checkout monitor",
            "use_case": "checkout",
            "idempotency_key": "checkout-failing-2026-10-03T19-00"
          }
        },
        "response": {
          "alert_id": "A-9D5HX1",
          "status": "queued",
          "workflow": {
            "id": "escalate",
            "name": "Escalate",
            "version": 1
          },
          "steps": [
            {
              "offset_min": 0,
              "kind": "message",
              "channel": "whatsapp"
            },
            {
              "offset_min": 0,
              "kind": "call",
              "channel": "call"
            },
            {
              "offset_min": 1,
              "kind": "call",
              "channel": "call"
            },
            {
              "offset_min": 2,
              "kind": "call",
              "channel": "call"
            }
          ],
          "recipient": "owner",
          "require_ack": true,
          "requires_acknowledgement": true,
          "max_cost_cents": 0,
          "deadline_at": "2026-10-03T19:12:00Z",
          "idempotent_replay": false,
          "next_step": "Poll get_alert_status; do not call start_workflow again."
        }
      }
    },
    {
      "name": "get_alert_status",
      "description": "Returns the status of alerts you started: delivered, acknowledged, failed, expired or cancelled, with every attempt. Delivered is not acknowledged, and silence is not a confirmed failure. It sends nothing and costs nothing.",
      "scope": "alerts.read",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      },
      "cost": "No cost. Read-only.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "alert_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 32
            },
            "description": "1 to 20 alert ids (A-XXXXXX) returned by the send tools or start_workflow. With neither alert_ids nor event_reference, the open alerts are listed.",
            "minItems": 1,
            "maxItems": 20
          },
          "event_reference": {
            "type": "string",
            "description": "The event_reference sent with the alert: returns the alerts that carry it, newest first (at most 20). It takes the place of alert_ids.",
            "maxLength": 100,
            "minLength": 1
          }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "alerts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "alert_id": {
                  "type": "string",
                  "description": "Public alert id."
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "direct",
                    "workflow"
                  ],
                  "description": "Direct send or workflow run."
                },
                "workflow": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "enum": [
                        "inform",
                        "acknowledge",
                        "escalate"
                      ],
                      "description": "Workflow id."
                    },
                    "version": {
                      "type": "integer",
                      "description": "Workflow version snapshotted when the alert started."
                    }
                  },
                  "required": [
                    "id",
                    "version"
                  ],
                  "description": "The workflow this alert runs, or null for a direct send."
                },
                "recipient": {
                  "type": "string",
                  "description": "The person's name."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "queued",
                    "sent",
                    "delivered",
                    "acknowledged",
                    "failed",
                    "expired",
                    "cancelled"
                  ],
                  "description": "See the status values below."
                },
                "terminal": {
                  "type": "boolean",
                  "description": "true when the alert has ended."
                },
                "awaiting_ack": {
                  "type": "boolean",
                  "description": "true while delivered and waiting for an acknowledgement."
                },
                "requires_acknowledgement": {
                  "type": "boolean",
                  "description": "Whether the alert asks for acknowledgement: its workflow's setting when it started, or require_ack."
                },
                "outcome": {
                  "type": "string",
                  "enum": [
                    "queued",
                    "delivering",
                    "waiting_for_ack",
                    "acknowledged",
                    "answered",
                    "delivered",
                    "not_acknowledged",
                    "not_answered",
                    "failed",
                    "cancelled"
                  ],
                  "description": "What the alert reads as, the same as in the BreakPass app."
                },
                "outcome_text": {
                  "type": "string",
                  "description": "The words for outcome, for example \"Waiting for you to acknowledge\"."
                },
                "created_at": {
                  "type": "string",
                  "description": "When the alert was created (timestamp)."
                },
                "deadline_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the alert ends if nothing else stops it (timestamp)."
                },
                "next_attempt_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the next attempt is due (timestamp)."
                },
                "acknowledged_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the holder acknowledged (timestamp)."
                },
                "ack_via": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "whatsapp_button",
                    "dtmf",
                    "sms_link",
                    "portal"
                  ],
                  "description": "How the holder acknowledged."
                },
                "late_ack_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "An acknowledgement that arrived after the alert had expired. The status does not change (timestamp)."
                },
                "cancelled_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the alert was cancelled (timestamp)."
                },
                "cancelled_by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "agent",
                    "owner",
                    "system"
                  ],
                  "description": "Who cancelled."
                },
                "failure": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Failure code."
                    },
                    "reason": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The reason as the BreakPass app shows it, R01 to R15, or null when there is none."
                    },
                    "message": {
                      "type": "string",
                      "description": "Readable reason. Never a number, a code or alert text."
                    }
                  },
                  "required": [
                    "code",
                    "reason",
                    "message"
                  ],
                  "description": "Why the alert failed, or null."
                },
                "charged_cents": {
                  "type": "integer",
                  "description": "US cents charged so far."
                },
                "attempts": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "seq": {
                        "type": "integer",
                        "description": "Attempt number within the alert."
                      },
                      "offset_min": {
                        "type": "integer",
                        "description": "Minutes from the first alert."
                      },
                      "kind": {
                        "type": "string",
                        "enum": [
                          "message",
                          "call",
                          "fallback"
                        ],
                        "description": "Kind of attempt."
                      },
                      "channel": {
                        "type": "string",
                        "enum": [
                          "whatsapp",
                          "sms",
                          "call"
                        ],
                        "description": "Channel of the attempt."
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "scheduled",
                          "sending",
                          "sent",
                          "delivered",
                          "delivered_unconfirmed",
                          "read",
                          "ringing",
                          "answered",
                          "voicemail",
                          "no_answer",
                          "busy",
                          "failed",
                          "skipped"
                        ],
                        "description": "Attempt status."
                      },
                      "scheduled_at": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "When the attempt is due (timestamp)."
                      },
                      "sent_at": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "When it was sent or the call was placed (timestamp)."
                      },
                      "delivered_at": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "When delivery was confirmed (timestamp)."
                      },
                      "failure_code": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Set when the attempt failed or was skipped."
                      },
                      "failure_reason": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The reason as the BreakPass app shows it, R01 to R15."
                      },
                      "failure_message": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Readable reason for a failed or skipped attempt."
                      },
                      "outcome": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "enum": [
                          "not_picked_up"
                        ],
                        "description": "not_picked_up for a call nobody picked up (charged the reduced fee, not an error); otherwise null."
                      },
                      "charged_cents": {
                        "type": "integer",
                        "description": "US cents charged for this attempt."
                      }
                    },
                    "required": [
                      "seq",
                      "offset_min",
                      "kind",
                      "channel",
                      "status",
                      "scheduled_at",
                      "sent_at",
                      "delivered_at",
                      "failure_code",
                      "failure_reason",
                      "failure_message",
                      "outcome",
                      "charged_cents"
                    ]
                  },
                  "description": "Every attempt, in order."
                }
              },
              "required": [
                "alert_id",
                "kind",
                "workflow",
                "recipient",
                "status",
                "terminal",
                "awaiting_ack",
                "requires_acknowledgement",
                "outcome",
                "outcome_text",
                "created_at",
                "deadline_at",
                "next_attempt_at",
                "acknowledged_at",
                "ack_via",
                "late_ack_at",
                "cancelled_at",
                "cancelled_by",
                "failure",
                "charged_cents",
                "attempts"
              ]
            },
            "description": "One entry per alert found, under the key alerts."
          },
          "not_found": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Ids that weren't found on this account."
          }
        },
        "required": [
          "alerts",
          "not_found"
        ]
      },
      "errors": [
        "ALERT_NOT_FOUND",
        "CONTENT_REJECTED"
      ],
      "example": {
        "request": {
          "name": "get_alert_status",
          "arguments": {
            "alert_ids": [
              "A-9D5HX1"
            ]
          }
        },
        "response": {
          "alerts": [
            {
              "alert_id": "A-9D5HX1",
              "kind": "workflow",
              "workflow": {
                "id": "escalate",
                "version": 1
              },
              "recipient": "owner",
              "status": "acknowledged",
              "terminal": true,
              "awaiting_ack": false,
              "requires_acknowledgement": true,
              "outcome": "acknowledged",
              "outcome_text": "Acknowledged",
              "created_at": "2026-10-03T19:00:00Z",
              "deadline_at": "2026-10-03T19:12:00Z",
              "acknowledged_at": "2026-10-03T19:00:40Z",
              "ack_via": "dtmf",
              "charged_cents": 0,
              "attempts": [
                {
                  "seq": 1,
                  "offset_min": 0,
                  "kind": "message",
                  "channel": "whatsapp",
                  "status": "delivered",
                  "charged_cents": 0,
                  "outcome": null
                },
                {
                  "seq": 2,
                  "offset_min": 0,
                  "kind": "call",
                  "channel": "call",
                  "status": "answered",
                  "charged_cents": 0,
                  "outcome": null
                }
              ]
            }
          ],
          "not_found": []
        }
      }
    },
    {
      "name": "cancel_alert",
      "description": "Stops all unsent steps of an alert and releases the unused reservation. Calling it again is safe. An attempt already in flight, such as a call that is ringing, may finish.",
      "scope": "alerts.send",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": true
      },
      "cost": "No new charge. Balance not yet captured is released. Attempts that already connected or were delivered stay charged.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "alert_id": {
            "type": "string",
            "description": "The alert id (A-XXXXXX) to cancel.",
            "minLength": 1,
            "maxLength": 32
          }
        },
        "required": [
          "alert_id"
        ]
      },
      "outputSchema": {
        "type": "object",
        "description": "The final status of the alert, with the fields of one get_alert_status entry, not wrapped in a key."
      },
      "errors": [
        "ALERT_NOT_FOUND",
        "CONTENT_REJECTED"
      ],
      "example": {
        "request": {
          "name": "cancel_alert",
          "arguments": {
            "alert_id": "A-5F2VC8"
          }
        },
        "response": {
          "alert_id": "A-5F2VC8",
          "status": "cancelled",
          "terminal": true,
          "cancelled_at": "2026-10-03T19:02:10Z",
          "cancelled_by": "agent"
        }
      }
    }
  ],
  "rateLimitedReasons": [
    {
      "reason": "holder_per_hour",
      "message": "Too many alerts to this recipient in the last hour (the limit is 20 an hour).",
      "retry_after_s": "To the end of the hour",
      "details": null
    },
    {
      "reason": "holder_calls_per_hour",
      "message": "Too many calls to this recipient in the last hour (the limit is 10 calls an hour to one number). An account with a raised limit shows its own figure.",
      "retry_after_s": "600",
      "details": "limit"
    },
    {
      "reason": "call_in_progress",
      "message": "A call to this recipient is already in progress.",
      "retry_after_s": "60",
      "details": null
    },
    {
      "reason": "unbilled_budget",
      "message": "Too many sends from this account didn't go through recently, so sending is paused for this account for now. Try again later.",
      "retry_after_s": "Varies",
      "details": "channel, window (hour or day), limit"
    },
    {
      "reason": "unbilled_send_busy",
      "message": "Other sends from this account are still on their way. Try again in a moment.",
      "retry_after_s": "2",
      "details": "channel"
    },
    {
      "reason": "runaway_brake",
      "message": "This agent connection is paused for sending too fast.",
      "retry_after_s": "The seconds left of the 15 minutes",
      "details": null
    },
    {
      "reason": "account_per_minute, account_per_hour, account_per_day",
      "message": "Too many alerts for this account right now. (Accounts without a paid plan.)",
      "retry_after_s": "To the end of the window",
      "details": null
    },
    {
      "reason": "new_account_per_day",
      "message": "This account has reached its daily alert limit. Try again tomorrow.",
      "retry_after_s": "To the end of the day",
      "details": null
    },
    {
      "reason": "new_account_calls_per_day",
      "message": "This account has reached its daily call limit. Try again tomorrow.",
      "retry_after_s": "To the end of the day",
      "details": "limit (6)"
    },
    {
      "reason": "rate_cap",
      "message": "Too many alerts right now. (Fallback.)",
      "retry_after_s": "60",
      "details": null
    }
  ],
  "callScript": "Every call opens with \"This is BreakPass by X Labs, with an alert from {agent_name}.\", then the message (and \"Press 1 to acknowledge.\" when acknowledgement is asked), a 3-second pause, then \"To stop all BreakPass alerts to this number, press 9.\" On +1 numbers it adds \"To reach us, call 3 3 2, 2 8 7, 9 2 0 0.\" (+1 332 287 9200). Key 9 counts only from that sentence to the end of the call; it stops all BreakPass alerts to the number from every account, and the call says \"You will receive no more BreakPass alerts. Goodbye.\" Otherwise the call ends with \"Goodbye.\" or \"Acknowledged. Goodbye.\""
}
