Skip to content

Integrations

MCP server

A Model Context Protocol server that lets AI agents list channels and templates, check delivery status and the balance, and send messages behind explicit safeguards.

Tools#

The package @omnimessage/mcp speaks stdio, for desktop clients, and streamable HTTP.

ToolKindWhat it does
list_channelsRead-onlyChannels with type, identifier, connection status and supported message types.
list_templatesRead-onlyWhatsApp templates of a channel.
get_message_statusRead-onlyStatus, error and status history of a message.
get_balanceRead-onlyWallet (micro-USD and USD) and remaining package credits.
send_messageSendsOne text, template or media message to one recipient.

Sending is guarded#

A sent message reaches a real person, costs money in live mode and cannot be undone. The server therefore:

  1. requires user_confirmed: true on every send_message call; the tool description tells the model to set it only after the user approved the recipient and the exact content;
  2. refuses to send with a live key unless the operator sets OMNIMESSAGE_MCP_ALLOW_LIVE_SEND=true;
  3. can restrict recipients to an allowlist (OMNIMESSAGE_MCP_ALLOWED_RECIPIENTS);
  4. holds back a message identical to one sent to the same recipient in the last five minutes, because agents repeat tool calls after timeouts, unless allow_duplicate is set;
  5. can run without the send tool at all (--read-only).

Quick start (stdio)#

Add the server to the MCP configuration of your client. With an om_test_ key nothing is delivered and nothing is billed; sandbox channels are named ch_test_<type>.

MCP client configuration
{
  "mcpServers": {
    "omnimessage": {
      "command": "npx",
      "args": [
        "-y",
        "@omnimessage/mcp"
      ],
      "env": {
        "OMNIMESSAGE_API_KEY": "om_test_..."
      }
    }
  }
}

Streamable HTTP#

Run over HTTP
OMNIMESSAGE_API_KEY=om_test_... OMNIMESSAGE_MCP_TOKEN=$(openssl rand -hex 24) npx @omnimessage/mcp --http --port 3920
# endpoint: http://127.0.0.1:3920/mcp   (clients send Authorization: Bearer <OMNIMESSAGE_MCP_TOKEN>)
  • Server-held key (OMNIMESSAGE_API_KEY set): every caller acts as that account and authenticates with OMNIMESSAGE_MCP_TOKEN. The server refuses to bind to a non-loopback address without a token.
  • Caller’s key (OMNIMESSAGE_API_KEY unset): each request carries the caller’s own OmniMessage API key as the bearer token, and the server stores nothing.
  • The endpoint is stateless (POST only, JSON responses). On loopback it rejects requests whose Host or Origin is not a loopback name, which stops web pages from reaching a local server through DNS rebinding. Behind a reverse proxy, add the public host names with OMNIMESSAGE_MCP_ALLOWED_HOSTS and terminate TLS in the proxy.

Configuration#

VariableDefaultMeaning
OMNIMESSAGE_API_KEY—API key. Required for stdio.
OMNIMESSAGE_BASE_URLhttps://api.omnimessage.co/v1API base URL.
OMNIMESSAGE_MCP_ALLOW_LIVE_SENDfalseAllow send_message with a live key.
OMNIMESSAGE_MCP_ALLOWED_RECIPIENTS—Comma-separated recipients send_message may reach.
OMNIMESSAGE_MCP_READ_ONLYfalseDo not expose send_message (same as --read-only).
OMNIMESSAGE_MCP_DUPLICATE_WINDOW_SECONDS300Hold back identical sends for this long; 0 disables.
OMNIMESSAGE_MCP_TOKEN—HTTP mode: the bearer token clients must present.
OMNIMESSAGE_MCP_ALLOWED_HOSTS—HTTP mode: extra Host names to accept.

Give the server a key with messages:write, messages:read, channels:read and billing:read, not full access. Create it in the console under API keys with selected scopes.

Use as a library#

Embed the server
import { createServer, configFromEnv } from '@omnimessage/mcp';

const server = createServer({ config: configFromEnv(process.env) });

    Loading