Skip to main content
Glama
hail-hq

hail

Official

Send a text message

send_sms

Sends an outbound SMS to an E.164 number with required recipient consent; supports sender ID selection, marketing vs informational texts, and idempotency keys for safe retries.

Instructions

Send an outbound SMS.

    ``to`` must be E.164 (e.g. ``+14155551234``). ``body`` is the
    message text. With no ``from_``: destinations where the sender-ID
    carrier delivers a dynamic alphanumeric sender ID unchanged (about
    110 countries, see core/hailhq/core/sender_id_corridors.py) use
    your organization's sender ID
    (or ``HAIL``, the platform default); Australia (+61) may use
    ``HAIL`` instead; every other destination,
    including the US and Canada,
    uses your organization's oldest active SMS-capable number and the
    API returns 422 when there is none.
    SMS never uses the shared voice-call pool.

    ``recipient_consent`` is required and must be the JSON boolean
    ``true`` (strings and numbers are refused): attest that you (the caller
    triggering this request) have obtained the lawful consent needed
    to text this recipient. The API rejects the request (422) if
    this is not ``true`` — Hail does not verify consent for you. Set
    ``message_type="marketing"`` for promotional texts (this
    additionally requires a non-empty ``consent_source``) — leave as
    the default ``"informational"`` for transactional/service texts.

    ``idempotency_key`` defaults to a fresh UUID and is returned in
    the response under ``idempotency_key`` — pass the same value on
    a retry to replay rather than re-send.

    Example:
        send_sms(to="+14155551234", body="Your order shipped!",
                 recipient_consent=True)

    Returns the ``SmsResponse`` dict (id, status, from_e164,
    to_e164, segment_count, ...). On failure returns
    ``{"error": "<message>"}`` instead.
    

Input Schema

NameRequiredDescriptionDefault
toYes
bodyYes
from_No
metadataNo
message_typeNoinformational
consent_sourceNo
idempotency_keyNo
recipient_consentYes
consent_obtained_atNo

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.29.0

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes far beyond annotations by detailing consent requirements, error cases (422), sender-ID routing, idempotency replay behavior, and return format. Annotations already cover safety hints (readOnlyHint, destructiveHint, openWorldHint), and the description adds critical operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is fairly long but dense with necessary information. It is front-loaded with the core action and includes an example and return details, though some sections (e.g., the sender-ID logic) could be tightened. Overall, every sentence earns its place given the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 9 parameters and an output schema, the description covers the most critical aspects: consent, sender-ID behavior, idempotency, and error handling. It omits metadata and consent_obtained_at, but given the output schema exists and annotations carry safety hints, the description is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description must compensate and does so for most parameters: it explains to (E.164), body, from_ (dynamic routing), recipient_consent (must be boolean true), message_type (marketing vs informational), consent_source, and idempotency_key. However, it omits metadata and consent_obtained_at entirely, leaving two parameters undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (send) and resource (outbound SMS), making the tool's function immediately clear. It does not explicitly differentiate from siblings like send_email or place_call, but the resource distinction is obvious from the name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides some usage context, such as setting message_type for marketing and the behavior when from_ is omitted, but it never states when to use this tool versus alternatives (e.g., send_email or place_call). The guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.