Skip to main content
Glama
hail-hq

hail

Official

Send an email

send_email

Send an outbound email through your configured SES sender.

Instructions

Send an outbound email through your configured SES sender.

    ``to`` is a non-empty list of RFC-style email addresses. At
    least one of ``body_text`` / ``body_html`` is required (both
    is fine — multipart-alternative). Prefer including
    ``body_html``: open and click tracking only works for emails
    with an HTML body. A plain-text-only email still gets sent,
    delivered, and bounce events, but opens and clicks are never
    tracked. ``cc``, ``bcc``, and
    ``reply_to`` are optional and follow the usual mail
    conventions. Hail sets no ``reply_to`` of its own — to have
    replies reach the human running this session, call ``whoami``
    and pass their ``email``.

    ``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 email 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 email (this
    additionally requires a non-empty ``consent_source`` describing
    how/where consent was obtained) — leave as the default
    ``"informational"`` for transactional/service email.

    ``from_`` is optional only while the workspace has one verified
    sender identity. With several, omitting it returns 422 listing
    them — call ``list_email_domains`` and pass one. With none, the
    server auto-mints a per-org hail-mail address of the form
    ``<user>+<org>@<base>`` if the operator configured
    ``HAIL_MAIL_BASE_DOMAIN`` (the ``<org>`` part is derived from your
    organization id; the ``<user>`` part comes from ``HAIL_MAIL_FROM``
    / ``HAIL_MAIL_DEFAULT_USER_PREFIX``, or an explicit row created
    via ``POST /email-domains``). When supplied, ``from_`` must match
    a verified row already in ``email_domains`` (register one with
    the website console or ``POST /email-domains``).

    ``from_name`` is an optional display name rendered on the
    From: header ("Acme Billing <billing@acme.com>"). Control
    characters are rejected.

    ``metadata`` is free-form JSON attached to the email record.

    ``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. A new key
    is a new message.

    ``attachment_ids`` are ids returned by ``upload_email_attachment``
    — upload a file first, then pass its id(s) here to attach it.

    Example:
        send_email(to=["alice@example.com"],
                   subject="Welcome",
                   recipient_consent=True,
                   body_text="Thanks for signing up.")

    Returns the ``EmailResponse`` dict (id, status, from_address,
    to_addresses, sent_at, provider_message_id, ...). On failure
    returns ``{"error": "<message>"}`` instead.
    

Input Schema

NameRequiredDescriptionDefault
ccNo
toYes
bccNo
from_No
subjectYes
metadataNo
reply_toNo
body_htmlNo
body_textNo
from_nameNo
message_typeNoinformational
attachment_idsNo
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.8/5.0
Behavior5/5

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

Annotations only declare the safety profile (non-read-only, open-world, non-destructive, non-idempotent); the description adds substantial behavioral context beyond that — the 422 consent rejection, that Hail does not verify consent, tracking limitations for text-only mail, the auto-minted per-org sender address, and the from_ resolution failure mode. The 'new key is a new message' note is consistent with idempotentHint=false rather than contradicting it.

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?

Front-loaded with the core action, then organized one paragraph per parameter group, with a compact example. It is long but nearly every sentence corresponds to a real decision the caller must make; the operator-configuration detail about HAIL_MAIL_BASE_DOMAIN is the one stretch that could be trimmed.

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

Completeness5/5

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

For a 16-parameter, non-idempotent, consent-gated outbound mutation, the description covers preconditions, failure modes, collaboration steps, and even restates the success/error return shape despite an output schema existing. An agent has everything needed to invoke it correctly on the first attempt.

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 across 16 params, the description carries nearly the full burden and does so well: it explains the to/body_text/body_html constraint, cc/bcc/reply_to conventions, the strict boolean type of recipient_consent, consent_source's conditional requirement, from_ resolution rules, and attachment_ids sourcing. The notable gap is consent_obtained_at, which is never mentioned, and subject is left implicit.

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

Purpose5/5

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

Opens with a specific verb+resource+transport: 'Send an outbound email through your configured SES sender.' It also names the collaborating siblings (upload_email_attachment, list_email_domains, whoami), making it easy to distinguish from get_email/list_emails in the sibling set.

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

Usage Guidelines5/5

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

Gives explicit conditional guidance throughout: prefer body_html because tracking requires it, use message_type="marketing" only for promotional mail, call whoami to obtain a reply_to, upload attachments first, and retry with the same idempotency_key. It names alternatives and the conditions that select them rather than leaving routing to inference.

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