
Hail
Phone, SMS and email for AI agents.
Connector by hail-hq · GitHub account verified by the MCP Registry
Install
Works with Claude Code, VS Code, Cursor, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install connector/hail-hq-hail-mcp
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Remote endpoint
https://mcp.hail.soRemote (HTTP)
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: voice-agents, email
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this server can do and what it asks for, from its tool list, install config and code. Checked Oct 25, 2026.
- Tools
- 24 read · 9 write · 5 delete
- Secrets
- None asked for
- Install scripts
- Nothing to install (hosted)
- Runs as
- Hosted (remote endpoint)
Tools by what they do 38
From the running server's own tool list (tools/list) on Oct 25, 2026.
Read 24 · Look things up without changing anything.
get_agentget_callget_emailget_email_attachmentget_email_eventsget_email_rawget_email_statsget_eventsget_numberget_smsget_verificationget_verification_requirements
Show 12 more tools
list_agentslist_callslist_contactslist_email_domainslist_emailslist_number_regionslist_numberslist_smslist_verificationslookup_contactquote_numberswhoami
Write 9 · Create, change, send or run things.
confirm_verificationcreate_agentcreate_contactplace_callroute_numbersend_emailsend_smsupdate_agentupload_email_attachment
Delete 5 · Delete, drop, revoke or wipe things.
acquire_numbercancel_verificationdelete_agentrelease_numbersubmit_verification
Network hosts it talks to 4
github.com· found in codeglama.ai· found in codehail.so· found in codemcp.hail.so· found in remote endpoint, install command, code
Files it touches
- Any path the agent passes to its tools
Tools (38)
As the server listed them on Oct 25, 2026. Descriptions are the server’s own words; hidden characters are shown as [U+…].
acquire_numberBuy a phone numbercan change or delete dataBuys a real phone number. It charges the setup fee and the first month now and renews monthly. Call quote_numbers first. Pass the offer's quote_id, country_code, number_type, and confirm_total_cents = monthly_cents + setup_cents from that offer. If the quote expired or the price changed (409) you get an error: quote again. Only buy when your user asked for this number. After buying, call route_number to point it at an agent. A quote buys at most one number. After a timeout, retry with the same quote_id and idempotency_key, or che…
cancel_verificationCancel a verificationcan change or delete dataCancel a verification that has not been sent for review, or dismiss a rejected one (needed before submitting a new one for the same country and number type). The draft is discarded. Works in state ``awaiting_review`` or ``rejected``, and for an ``approved`` US SMS registration (``purpose: "sms"``): its numbers leave the campaign, US-to-US texts from them fail again, and its monthly fee stops after the current month. Some registrations bill at least 3 monthly fees from approval, so cancelling sooner can still charge 3 months. Ask …
confirm_verificationConfirm a verification with a codeWhen a registration shows confirmation 'code', ask the person for the code the carrier texted and submit it here. ``verification_id`` comes from submit_verification or list_verifications. ``code`` is 4 to 10 characters. A wrong or expired code is an error naming ``code``; the carrier sends a new one after a day. On success the registration moves on; poll get_verification until ``approved``. A ``confirmation`` of ``reply`` means the person answers the carrier's text instead; nothing is entered here. Returns the verification or ``…
create_agentCreate an agentSave an agent. Then call ``route_number`` so a number answers with it, or pass its id as ``agent_id`` to ``place_call``. ``system_prompt`` is what the agent follows. ``first_message`` is spoken after the AI line; omit it to let the caller speak first. ``ai_disclosure_line`` replaces the workspace AI line for this agent; ``{org}`` becomes the organization name. ``language`` is a lowercase ISO 639-1 code. ``max_duration_seconds`` is 60..3600. ``handover_max_duration_seconds`` (60..3600, default 1800) is the call limit once a handov…
create_contactCreate a contactSave a new contact for the workspace. Provide at least one of ``phone_e164`` (E.164, e.g. ``+14155551234``) or ``email`` — the API rejects (422) a contact with neither. A duplicate phone or email on an existing contact returns 409. Example: create_contact(name="Maya Chen", phone_e164="+14155551234") Returns the created contact entry as a dict. On failure returns ``{"error": "<message>"}`` instead.
delete_agentDelete an agentcan change or delete dataDelete a saved agent. DESTRUCTIVE. Ask the user before calling this. Numbers that used the agent stop answering with it: calls ring out and texts reach webhooks only. Reroute them first with ``route_number`` if that matters. ``confirm_name`` must equal the agent's ``name``. The tool reads the agent first and refuses with ``{"error": ...}`` on a mismatch, without deleting anything. To stop an agent without deleting it, use ``update_agent`` with ``status="paused"``. Returns ``{"deleted": true, "agent_id", "name"}``, or ``…
get_agentGet an agentread-onlyFetch one saved agent by id. ``agent_id`` comes from ``list_agents`` or ``create_agent``. Returns the ``AgentResponse`` as a dict (``name``, ``system_prompt``, ``first_message``, ``ai_disclosure``, ``voice_config``, ``tools``, ``voice_enabled``, ``sms_enabled``, ``status``, ...), or ``{"error": "<message>"}``.
get_callGet a callread-onlyFetch the current state of one call by id. Use this after ``place_call`` (or to check on any prior call) to read the call's latest ``status`` and timing fields. Returns the API's ``CallResponse`` as a dict, or ``{"error": "call not found"}`` for an unknown id.
get_emailGet an emailread-onlyFetch the full record of one email by id. Returns the complete row — including ``body_text`` / ``body_html`` and (for inbound mail) the ``in_reply_to`` / ``message_id`` headers and ``spam``/``virus``/``spf``/``dkim``/``dmarc`` verdicts. Use this after ``list_emails`` to read a received reply's body. Returns the API's ``EmailResponse`` as a dict, or ``{"error": "resource not found"}`` for an unknown id.
get_email_attachmentGet an email attachmentread-onlyGet a fetchable URL for one inbound email attachment. ``attachment_id`` comes from an item in ``get_email``'s ``attachments`` list. Returns ``{"url": "<presigned-s3-url>"}`` — a short-lived (~5 minute) link to the attachment bytes, fetchable directly with no auth header. Unknown ids return ``{"error": "resource not found"}``.
get_email_eventsGet email eventsread-onlyDelivery/engagement timeline (sent→delivered→opened…) for one email. Chronological lifecycle events for a single email — use this to see exactly what happened to one message (bounced? opened? clicked?) rather than the account-wide aggregates ``get_email_stats`` returns. Returns ``{"items": [...], "next_cursor": ...}`` where each item has ``kind`` (one of sent, delivered, delivery_delayed, bounced, complained, rejected, opened, clicked), ``payload``, and ``occurred_at``. ``opened`` and ``clicked`` only occur for emails sent with …
get_email_rawGet raw emailread-onlyGet a fetchable URL for an email's original MIME source. Returns ``{"url": "<presigned-s3-url>"}`` — a short-lived (~5 minute) link to the full raw RFC822 message. Fetch the URL directly to read the complete original; it needs no auth header. Raw source exists for **inbound** mail only — outbound ids return ``{"error": "resource not found"}``.
get_email_statsGet email statsread-onlyAccount-level email deliverability stats (counts, rates, time series). Aggregates across your whole organization's outbound mail over a window — use this for "how's deliverability doing" rather than one message's history (``get_email_events`` covers that). ``from_`` / ``to`` are ISO 8601 timestamps (defaults: last 7 days ending now). ``bucket`` is ``"day"`` (default) or ``"hour"`` — ``"hour"`` is limited to an 8-day span; any range is capped at 92 days. Returns ``{"from": ..., "to": ..., "bucket": ..., "totals": {...}, …
get_eventsGet eventsread-onlyPage through events from across the org or one resource. Pass ``id="<type>:<uuid>"`` to narrow to a single resource — supported types are ``call``, ``email``, and ``sms`` (e.g. ``id="sms:<uuid>"`` after ``send_sms``). When narrowed to a call, the response includes a ``call_status`` field reflecting the call's current state. Without ``id``, returns events from across the whole org. ``kind`` filters server-side by event kind (``state_change``, ``agent_turn``, ``user_turn``, ``tool_call``, ``error``, ...). This is **not** a…
get_numberGet a numberread-onlyFetch one dedicated number by id: its state, capabilities and which agents answer its calls and texts. ``number_id`` comes from ``list_numbers``. Returns the ``PhoneNumberResponse`` as a dict, or ``{"error": "<message>"}``.
Show 23 more tools
get_smsGet a text messageread-onlyFetch the current state of one SMS by id. Use this after ``send_sms`` to check delivery status. Example: get_sms(sms_id="...")
get_verificationGet a verificationread-onlyFetch one verification and its state. Use it to poll. There is no notification, and review takes business days. Poll every few minutes to hours, not every few seconds; the state refreshes from the carrier at most once a minute. On ``approved``: call quote_numbers again. The offer is now ``ready``; then acquire_number. On ``rejected``: read ``rejection_reason``, ask the user, dismiss it with cancel_verification, then submit a new one. ``verification_id`` comes from submit_verification or list_verifications. Returns ``{"i…
get_verification_requirementsGet verification requirementsread-onlyRead what the carrier needs to verify the organization before it can buy a number. Call this when quote_numbers shows an offer with ``readiness == "verification_required"``. Read-only. ``country_code`` is ISO alpha-2 (for example ``"GB"``). ``number_type`` is ``local``, ``mobile``, ``national`` or ``toll_free``. ``subject_type`` is required: ``person`` (the user) or ``business`` (the user's company). Never guess it: ask the user "you or your company?". The result's ``subject_types`` lists what the carrier accepts. The organizatio…
list_agentsList agentsread-onlyList the workspace's saved agents: the brains that answer calls and texts on its numbers, and that ``place_call`` can use via ``agent_id``. Returns ``{"items": [{"id", "name", "system_prompt", "first_message", "ai_disclosure", "ai_disclosure_line", "voice_config", "tools", "max_duration_seconds", "handover_max_duration_seconds", "voice_enabled", "sms_enabled", "status", "handover_contacts"}, ...]}``.
list_callsList callsread-onlyList recent calls in your organization, newest first. Cursor-paginated: pass the previous response's ``next_cursor`` to fetch the next page. ``status`` (one of queued, dialing, ringing, in_progress, completed, failed, busy, no_answer, canceled) and ``to`` (E.164) are optional server-side filters. Returns a dict ``{"items": [...], "next_cursor": <str|None>}``.
list_contactsList contactsread-onlyList the workspace's contacts: org members (with their phone/email) plus manually saved contacts. Use ``lookup_contact`` for name searches. ``q`` optionally filters server-side (matches name/email/phone). ``limit`` caps the page (server default 100, max 500). Returns ``{"items": [{"id", "kind", "name", "phone_e164", "email", "role"}, ...]}`` — ``kind`` is ``"member"`` (id ``member:<user_id>``, ``role`` set) or ``"manual"`` (id is the contact's UUID, ``role`` null).
list_email_domainsList email domainsread-onlyList the addresses this workspace can send email from. Call this BEFORE ``send_email`` when you do not already know the ``from_`` address — do not guess a domain. Returns ``{"items": [...], "next_cursor": ..., "default_from": ...}``. Each item carries ``domain``, ``kind`` (``"custom"`` or ``"hail_mail"``) and ``verification_status``; only ``"verified"`` rows can send. A ``custom`` item's ``domain`` is a bare DNS name that accepts any local-part (``sales@acme.com``); a ``hail_mail`` item's ``domain`` is already a full address. …
list_emailsList emailsread-onlyList emails in your organization, newest first. Cursor-paginated: pass the previous response's ``next_cursor`` to fetch the next page. Two optional server-side filters: * ``direction`` — ``outbound`` or ``inbound``. Pass ``direction="inbound"`` to read replies and other received mail. * ``status`` — one of ``queued``, ``sent``, ``failed``, ``bounced``, ``complained``, ``received``. Items are trimmed summaries (no message body). Call ``get_email`` with an item's ``id`` to read the full body. Example: lis…
list_number_regionsList number search regionsread-onlyList the US state and Canadian province codes that quote_numbers accepts as ``region`` (optional, with ``city``). Returns ``{"regions": [{"country_code", "code", "name"}]}``, such as ``{"country_code": "US", "code": "AZ", "name": "Arizona"}``, or ``{"error": "<message>"}``.
list_numbersList numbersread-onlyList the workspace's dedicated phone numbers, newest first. ``limit`` is 1..200 (default 50). Pass the returned ``next_cursor`` as ``cursor`` for the next page. Returns ``{"items": [{"id", "e164", "country_code", "number_type", "capabilities", "provisioning_state", "voice_agent_id", "sms_agent_id", ...}], "next_cursor"}``, or ``{"error": "<message>"}``.
list_smsList text messagesread-onlyPage through recent SMS messages for your organization. ``status`` filters to one of: queued, sent, delivered, failed, undelivered, received. ``to`` filters to messages sent to a specific E.164 number. Paginate with the returned ``next_cursor``.
list_verificationsList verificationsread-onlyList the organization's carrier verifications, newest first. ``purpose`` is ``number`` or ``sms``; only that kind is listed. Omit to see every registration. ``purpose='sms'`` lists the registrations to text US numbers from a US number. Returns ``{"items": [{"id", "country_code", "number_type", "subject_type", "subject_name", "purpose", "state", "rejection_reason", "created_at", "updated_at", "submitted_at", "approved_at", "confirmation"}]}``. ``state`` is ``awaiting_review``, ``submitting``, ``submitted``, ``approved``, …
lookup_contactLook up a contactread-onlyFind a contact by name, email, or phone fragment. Resolve a person to their ``phone_e164``/``email`` BEFORE calling ``place_call``, ``send_sms``, or ``send_email`` — do not guess a contact's number. Returns up to 10 matches, same item shape as ``list_contacts``. Example: lookup_contact(query="maya")
place_callPlace a phone callOriginate an outbound phone call. Provide ``system_prompt`` (mode A — Hail's bundled fallback LLM uses this prompt) or ``llm`` (mode B — bring your own OpenAI-compatible endpoint as ``{"base_url": ..., "api_key": ..., "model": ...}``), or both, or ``agent_id`` (a saved agent from ``list_agents`` supplies the prompt, first message, AI line, voice and tools; fields you pass here win). At least one is required. Passing both runs your prompt on your own endpoint: it receives Hail's voice preamble plus your prompt as the leadi…
quote_numbersQuote phone numbersread-onlyCompare live phone-number offers from the carriers. Read-only: it buys nothing and charges nothing. ``country_code`` is an ISO alpha-2 code such as ``"US"``. ``capabilities`` is ``["voice"]``, ``["sms"]`` or both (default). ``number_type`` is ``local``, ``mobile``, ``national`` or ``toll_free``; omit it to compare all types. ``area_code`` is an area code or the first digits of the number, as dialed in the country: ``"020"`` (London), ``"480"`` (Arizona). ``city`` is a city name such as ``"London"``. Each offer has ``local…
release_numberRelease a numbercan change or delete dataRelease a phone number. DESTRUCTIVE and permanent. Calls and texts to the number stop. This month's fee and any earlier months are still billed. There is no refund. The number may not be recoverable. Ask the user before calling this. ``confirm_e164`` must equal the number's ``e164`` (for example ``"+14155550100"``). The tool reads the number first and refuses with ``{"error": ...}`` on a mismatch, without releasing anything. A number whose order is still pending cannot be released (409). A number whose order failed was n…
route_numberRoute a number to an agentChoose which agent answers a number's calls and texts. ``voice_agent_id`` makes the number answer calls with that agent (Hail registers it for inbound at the carrier and LiveKit); ``clear_voice=True`` stops answering calls. ``sms_agent_id`` makes the agent reply to texts; ``clear_sms=True`` stops that. A field left out keeps its value. ``number_id`` comes from GET /numbers. Returns the updated ``PhoneNumberResponse`` as a dict, or ``{"error": "<message>"}``.
send_emailSend an emailSend 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 ``repl…
send_smsSend a text messageSend 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 retur…
submit_verificationSubmit a verificationcan change or delete dataSend the user's personal or company details and identity documents to the carrier for verification. IRREVERSIBLE: once submitted it cannot be cancelled, and the carrier keeps the documents. ``attest_authorized``: pass true only if the person or company named in these details and documents asked for this submission and gave you the details and files in this conversation. Never invent, guess, infer or reuse personal data or documents. Anything else: pass false (the call then sends nothing). ``purpose`` is ``number`` (default) or `…
update_agentUpdate an agentChange a saved agent. Safe to repeat: the same call gives the same result. Only the fields you pass change; a field left out keeps its value. ``status`` is ``"live"`` or ``"paused"``; a paused agent does not answer. ``language`` is a lowercase ISO 639-1 code. Pass ``language`` or ``voice_id`` alone: the other value is kept. ``max_duration_seconds`` and ``handover_max_duration_seconds`` are 60..3600. ``handover_contacts`` replaces the whole list: ``[{contact_id, note}]`` (max 10) as in ``create_agent``; ``[]`` removes every contac…
upload_email_attachmentUpload an email attachmentUpload a file to attach to a future outbound email. ``content_base64`` is the file's raw bytes, base64-encoded. Returns ``{"id": ..., "filename": ..., "content_type": ..., "size_bytes": ...}`` — pass ``id`` in ``send_email``'s ``attachment_ids`` list. The id is reusable across many sends and expires in 24h if never used. Files over 25MB (combined with the message body and any other attachments, per send) are rejected — host large files externally and link to them in the body instead.
whoamiWho am Iread-onlyIdentify the human whose credentials this session runs under. Use it to sign or route mail as that person: pass their address as ``send_email(reply_to=...)`` so replies reach them rather than the sending domain, which is often an unattended ``noreply@``. Returns ``{"auth_kind", "organization_id", "user_id", "email", "name"}``. ``user_id``/``email``/``name`` are null when the server runs on a shared operator key (``auth_kind="shared"``) — there is no human behind it, so send without a ``reply_to``. Example: whoami() …
Compare and alternatives
Featured in
Signals
- Stars
- 32
- Forks
- 12
- Open issues
- 3
- Contributors
- 3
- Last commit (this folder)
- Oct 23, 2026 (5 days ago)
- Last release
- Oct 23, 2026 (6 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- Registry name
io.github.hail-hq/hail-mcp- Version
- 0.1.1
- Auth
- Auth not stated
- License
- AGPL-3.0
- Repository
- github.com/hail-hq/hail
- Website
- hail.so/mcp
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
Cite this page
Hail MCP server. Agent Mart. https://agentmart.dev/connectors/hail-hq-hail-mcp (last updated 2026-10-24)