Skip to main content
Glama
textbee-mcp

textbee-mcp

Official

@textbee/mcp

npm version CI license

MCP server for textbee.dev, the open source SMS gateway that turns an Android phone into an SMS API. Gives Claude, Cursor, and any MCP client the ability to send and read SMS through your own phone and your own number.

Three tools, no per-message markup, works with self-hosted textbee instances.

Setup

You need a textbee account with a paired Android device and an API key from the dashboard. The key has full account access; treat it like a password.

claude.ai, Claude Desktop, and the Claude mobile apps (no install)

These use the hosted endpoint at https://mcp.textbee.dev/mcp, which runs the same tools from this package.

  1. In claude.ai or Claude Desktop, open Customize, then Connectors, then + Add and Add custom connector.

  2. Enter the name textbee and the URL https://mcp.textbee.dev/mcp, then click Continue twice.

  3. Choose Sign in now, leave the OAuth client on the recommended option, and click Add.

  4. Paste your API key on the textbee sign-in page and click Connect.

One connection works on the web, in Claude Desktop, and in the Claude mobile apps (the mobile apps cannot add connectors themselves). On Team and Enterprise plans, an owner adds the connector for the organization first. It lasts 90 days, then Claude asks you to reconnect. textbee checks the key and does not store it, but the key does pass through textbee's server. Revoke the key in the dashboard to disconnect. To keep the key on your machine, use the local setup below.

Claude Code

Local, with the key in your own config:

claude mcp add textbee -s user -e TEXTBEE_API_KEY=your-key -- npx -y @textbee/mcp

Or hosted, signing in with your key in the browser:

claude mcp add --transport http -s user textbee https://mcp.textbee.dev/mcp

Then run /mcp in Claude Code, select textbee, and choose Authenticate.

Claude Desktop (local)

Add to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, Windows: %APPDATA%\Claude\claude_desktop_config.json), then restart Claude Desktop:

{
  "mcpServers": {
    "textbee": {
      "command": "npx",
      "args": ["-y", "@textbee/mcp"],
      "env": { "TEXTBEE_API_KEY": "your-key" }
    }
  }
}

Cursor

The same object in ~/.cursor/mcp.json. Clients that support remote servers with headers can use https://mcp.textbee.dev/mcp instead and send the key as x-textbee-api-key or Authorization: Bearer <key>.

Full setup guide: textbee.dev/docs/agents/mcp.

Slow first start

npx downloads the package on first run. If your client times out waiting, install globally once and point the config at the binary:

npm install -g @textbee/mcp
{ "mcpServers": { "textbee": { "command": "textbee-mcp", "env": { "TEXTBEE_API_KEY": "your-key" } } } }

Related MCP server: clicksend-mcp

Tools

send_sms

Send an SMS to one or more phone numbers or short codes. International format with the country code (for example +15550100123) works everywhere. Local numbers and short codes only reach recipients in the sending phone's country. The sending phone is chosen automatically: your default device, otherwise the enabled device with the most recent heartbeat. Optional device_id, sim_subscription_id, and scheduled_at. Returns an sms_batch_id for delivery checks when the account uses the SMS queue.

get_messages

Read messages across every device on the account. Defaults to received messages, newest first. Filter by direction (received, sent, all), free-text search, sms_batch_id (per-recipient delivery status of a send), device_ids, and a from/to time window. Supports cursor pagination for polling without duplicates or gaps.

list_devices

The phones on the account: ids, enabled state, which one sends by default, last check-in, and message counts.

Self-hosted textbee

Point the server at your own instance:

"env": {
  "TEXTBEE_API_KEY": "your-key",
  "TEXTBEE_BASE_URL": "https://sms.example.com"
}

The /api/v1 suffix is optional and added automatically. Subpath deployments like https://example.com/textbee work too. An invalid URL is an error rather than a silent fallback, so a typo never sends your key to the public API.

Environment variables

Variable

Required

Default

Purpose

TEXTBEE_API_KEY

yes

none

API key from the textbee dashboard

TEXTBEE_BASE_URL

no

https://api.textbee.dev

Your instance's URL when self-hosting

TEXTBEE_TIMEOUT_MS

no

30000

Per-request timeout in milliseconds

Notes

  • Your key stays on your machine: this server talks only to the textbee API at the base URL above.

  • Sends count against your textbee plan quota, and the plan's rate limits apply server-side.

  • All diagnostics go to stderr; stdout is reserved for the MCP protocol.

Using it as a library

The package also exports its tool definitions for embedding in another MCP host (this is how the hosted remote endpoint reuses them):

import { createTextbeeMcpServer, staticCredentials, loadConfig } from '@textbee/mcp'

const server = createTextbeeMcpServer({
  credentials: staticCredentials(loadConfig(process.env)),
})

Credentials are resolved per tool call, so a multi-tenant host can inject a different key per request. See credentialsFromAuthInfoExtra.

License

MIT. Part of the textbee project.

Available Tools

3 tools
get_messagesRead messagesA
Read-only

Read the SMS messages on the user's textbee account, covering every device, no device id needed. direction defaults to "received": checking for a reply or a one-time code is the usual case. Pass direction "sent" to review what went out (each row carries its delivery status), or "all" for a conversation in order. Pass the sms_batch_id from a send to see that send's per-recipient delivery status. To poll for new messages without missing or repeating any: use order "asc" with a from bound, then keep calling with the next_cursor each result prints. from is inclusive and to is exclusive, so consecutive windows tile exactly. Reading does not consume the plan send quota. Messages reach textbee within a few seconds of arriving on the phone, so when waiting for a code, wait briefly and call again rather than tight-polling.

Inputs: to, from, limit, order, +5 more.

list_devicesList devicesA
Read-only

List the Android phones registered to this textbee account: id, name, enabled state, which one is the default sender, when each last checked in, and message counts. Call this when a send fails with a device error, when the user asks which phone will be used, or when you need a device_id. Takes no arguments and sends no SMS.

Inputs: no named parameters.

send_smsSend SMSA

Send an SMS through the user's own textbee account and Android phone. Recipients are phone numbers or short codes. Prefer international format with the country code, such as +15550100123. Local numbers and short codes are sent as given and only reach recipients in the sending phone's country. Sender names such as MYBANK cannot receive SMS. The sending phone is chosen automatically: the account default device, otherwise the enabled device with the most recent heartbeat. Only pass device_id when the user explicitly names a phone; ids come from list_devices. Sending costs the user a real message against their textbee plan quota, so do not send speculatively and do not retry a send that may already have gone out. When the account has SMS queueing enabled the result includes an sms_batch_id; pass it to get_messages as sms_batch_id to check per-recipient delivery status.

Inputs: message (required), recipients (required), device_id, scheduled_at, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.5/5.0

    Scored across 3 tools

    Disambiguation5/5

    Each tool maps to a distinct resource and action: sending an SMS, reading messages, and listing devices. There is no plausible overlap — send_sms is the only write path, get_messages the only read path, and list_devices the only device lookup, and the descriptions explicitly cross-reference which one to use for device ids and batch status.

    Naming Consistency5/5

    All three names follow the same snake_case verb_noun pattern (send_sms, get_messages, list_devices). Verbs are distinct and semantically accurate for the operation performed.

    Tool Count4/5

    Three tools is minimal but each covers a genuinely separate need, so nothing is redundant. It sits at the low end of the ideal range, and a small account/quota or device-admin tool would round the surface out without bloat.

    Completeness3/5

    The core send/read/status lifecycle is covered, including batch delivery status and cursor-based polling, so no dead ends in the main flow. However, device administration (enable/disable, set default sender) and message deletion or quota inspection are absent, leaving gaps an agent cannot work around through the API.

    Maintenance

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      AndroidAPI.net MCP Connector lets Claude send SMS, WhatsApp messages, and OTPs via your linked Android device or gateway credits. Features * 52 tools covering SMS, WhatsApp, OTP, Contacts, Android devices * Works with Claude Desktop and Claude Code * Install: npx -y androidapi-mcp Setup Set ANDROIDAPI_SECRET env var with your API key from AndroidAPI.net → Tools → API Keys
      52
      48 npm
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      Enables Claude to read, organize, and send SMS messages through your ClickSend account.
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI applications to send and receive real iMessage/SMS messages through a local MCP service, with tools for sending texts, checking new messages, browsing history, and querying line status.
      698 npm
      3
      MIT