SendaiDocs

Guides

View as Markdown

AI agents (MCP)

Connect Claude, Cursor, or any MCP client to your Sendai account — six tools over hosted HTTP, authenticated with your API key, nothing to install.

Sendai runs a hosted MCP server, so an AI agent can send and track messages from your account: the same API key, the same prepaid balance, the same delivery record and message log as everything else you do. There is nothing to install and nothing to run — you configure a URL and a key, and every message the agent sends shows up in your dashboard exactly as if your own code had sent it.

HostUse
https://mcp.sendai.co.zwProduction
https://mcp-staging.sendai.co.zwStaging

Agents send real messages. send_sms and send_bulk_sms deliver to real handsets and charge your prepaid balance, exactly as if you had called the REST API yourself. Both are marked destructive in the MCP metadata, so well-behaved clients ask before running them — but the enforcement that matters (approved sender, sufficient balance) happens server-side.

How it works

The server speaks MCP over plain HTTP: your client POSTs JSON-RPC to the host and gets the response back in the same request. There is no session and no state — each request carries your API key as a bearer token, the server forwards it to the REST API for the life of that one request, and nothing about you is stored on it.

  • The endpoint answers on both the bare host and /mcp — either URL works.
  • It accepts POST only; a GET on the endpoint returns 405, and any other path is a deliberate 404 so a mistyped URL fails loudly instead of half-working.
  • Authentication is a normal API key from Settings → Developer in the dashboard, sent as Authorization: Bearer …. No OAuth — browser and mobile connector UIs that expect an OAuth flow cannot connect; use a client that reads a config file.

Connect a client

Create an API key in the dashboard under Settings → Developer — ideally one dedicated to the agent (see Security) — then add the server to your client:

Connect
claude mcp add --transport http sendai https://mcp.sendai.co.zw \
  --header "Authorization: Bearer sk_your_key_here"

The same JSON shape works in any client that reads an mcpServers config file — VS Code included. The dashboard's Settings → Developer tab shows this exact configuration with a copy button.

The six tools

The tools are the same operations as the REST reference, so everything an agent does is visible in your dashboard's messages log and reports.

  • send_smswrite · charges the account
    Sends one SMS. Real message, real charge. Args: to (recipient MSISDN in international format, e.g. 263771000000), message (billed per GSM-7/UCS-2 segment), from (an approved sender ID — an unapproved value is rejected with 400). Returns 202 — accepted, priced and queued, not delivered; poll get_sms to confirm delivery.
  • send_bulk_smswrite · charges the account
    Sends the same body to many recipients, priced as one send. Real messages, real charges. Args: to (array of MSISDNs), message, from (approved sender ID), optional webhook_url (a delivery callback applied to every message in the send). Rejected outright with insufficient balance when the prepaid balance does not cover it — never partially delivered.
  • get_smsread-only
    Reads a message back by id. Args: id (from the send_sms response). status: success means the carrier accepted or confirmed it — delivered_at non-null is the confirmed handset delivery. There is no separate delivery-status field.
  • get_balanceread-only
    Prepaid wallet balance, one row per currency. No args. Worth calling before a bulk send — an underfunded send is rejected, not partially delivered.
  • list_sender_idsread-only
    Sender identities on the account. No args. Rows with usable_as_from: true are valid from values — an SMS identity that is both active and verified; the rest are listed so a rejected sender can be explained rather than guessed at.
  • list_api_keysread-only
    API keys on the account — ID, Name, Active, CreatedAt, LastUsedAt. Metadata only, never key material. No args.

One convenience the tools add over raw REST: every charge is decorated with a charge_display sibling ("0.045 USD"), so an agent reads four cents as four cents rather than as the API's raw ten-thousandths integer 450.

Deliberately not exposed: creating or revoking API keys. Minting a key returns the secret once, in plaintext — over MCP it would land in the model's context and the client transcript, and it would let an agent create credentials that outlive the session. Listing is safe (only metadata comes back), so only listing is here.

A worked example

A typical first session — you ask the agent to check the balance, then send a verification code and confirm it arrived:

Session// sample
Transcript
// sample — tool calls an agent makes for:
// "Check my Sendai balance, then text the code 4821 to 263771000000."

→ get_balance
← [{ "currency": "USD", "amount": 184500, "amount_display": "18.45 USD" }]

→ list_sender_ids
← [{ "from": "Sendai SMS", "channel": "sms", "usable_as_from": true }]

→ send_sms { "to": "263771000000", "from": "Sendai SMS",
             "message": "Your code is 4821" }
← { "id": "0f9c1b3a-…", "status": "enqueued", "charge": "450",
    "charge_display": "0.045 USD", "delivered_at": null }   // 202 — queued

→ get_sms { "id": "0f9c1b3a-…" }                            // a little later
← { "status": "success", "delivered_at": "2026-07-06T09:12:44Z" }

That sequence exercises the whole delivery story, and teaches the agent the same lesson the Quickstart teaches you: 202 is queued; delivered_at is delivered.

Security

  • Give the agent its own key. A key is the only credential the server sees, and it scopes every call to one account — a dedicated key means you can cut the agent off without touching your services. Create and revoke keys under Settings → Developer or with the API tokens endpoints; revocation takes effect on the next request.
  • Your key is never stored. Each request's bearer key is forwarded to the REST API for that one request and then gone — the MCP server keeps no key material and no per-tenant state.
  • The send tools spend money. send_sms and send_bulk_sms are flagged destructive so clients prompt first, but treat any agent holding a key as able to send: fund the account accordingly and watch the messages log.
  • Agents cannot mint keys. Key creation and revocation are excluded from the tool surface by design (see above).

Troubleshooting

SymptomCause and fix
401 Missing or malformed Authorization headerThe key is absent, not in Authorization: Bearer sk_… form, or revoked. Check the header in your client config, and that the key is still active under Settings → Developer.
400 unknown or unapproved sender idThe from value is not an approved sender ID on your account. Run list_sender_ids and use a row with usable_as_from: true — see Sender IDs.
404 No MCP endpoint at that pathThe URL has a typo. The server answers on the bare host and /mcp only.
405 This endpoint accepts POSTThe client is probing with GET. Configure it as an HTTP (streamable) MCP server, not SSE.
insufficient balance on a bulk sendThe prepaid balance does not cover the whole send. Check get_balance, top up in the dashboard, retry — nothing was partially sent.

Health

GET /health on the MCP host answers unauthenticated and says only that the server is up — nothing about your account.

Next steps