MyOTP.App

MCP Server

Give an AI agent the ability to send and verify one-time passcodes over SMS, WhatsApp and Telegram. Works with Claude, Codex, Cursor, and anything else that speaks the Model Context Protocol.

See the API it wraps

The MCP server is a thin layer over two endpoints. This is the whole round trip, recorded against production:

Send, then verify. return_otp is a testing flag so the round trip completes on screen; in production the code only reaches the handset.

Two ways to connect

Hosted no install

Point your agent at this URL and pass your MyOTP API key as a header. Nothing to install or keep running.

https://mcp.myotp.app/mcp

Every request carries its own X-API-Key, so the hosted server never holds anyone's key. It reads the key per request and forwards the call under it. Authorization: Bearer <key> works too, for clients that can only set a bearer token (Codex is one). Send whichever your client can actually set.

One setup step you cannot skip. MyOTP keys are bound to an IP allowlist, and with the hosted server the request reaches our API from 108.61.176.199, not from your machine. Add that address to your key's allowlist or every call comes back 403. If you would rather not, use the local option below, where calls originate from your own machine.

Local stdio

Runs on your machine, so calls come from your own IP and your key never leaves it.

npx @myotp/mcp

Use the scoped name. npx myotp-mcp is the binary name, not a package, and does not resolve.

Configure your agent

Claude Desktop or Claude Code

Add to your MCP config, using whichever of the two blocks you want:

{
  "mcpServers": {
    "myotp": {
      "command": "npx",
      "args": ["-y", "@myotp/mcp"],
      "env": { "MYOTP_API_KEY": "your-32-character-api-key" }
    }
  }
}

Cursor

Same shape, in .cursor/mcp.json at your project root.

Codex CLI

Codex reads TOML. Add to ~/.codex/config.toml:

[mcp_servers.myotp]
command = "npx"
args = ["-y", "@myotp/mcp"]

[mcp_servers.myotp.env]
MYOTP_API_KEY = "your-32-character-api-key"

Or point Codex at the hosted server instead of launching anything locally. It sends the token as Authorization: Bearer, which the endpoint accepts:

[mcp_servers.myotp]
url = "https://mcp.myotp.app/mcp"
bearer_token_env_var = "MYOTP_API_KEY"

On older Codex builds that only pick up stdio servers, add experimental_use_rmcp_client = true above the entry. If you use the hosted URL, the IP-allowlist note above applies.

Anything else

Windsurf, Zed, Continue, OpenClaw, Hermes and Grokbot all take the same stdio shape: npx, ["-y", "@myotp/mcp"], and MYOTP_API_KEY in the environment, written as JSON or TOML depending on the client. For a hosted client, point it at https://mcp.myotp.app/mcp with your key in either header.

What the agent can do

ToolWhat it does
generate_otpSend a passcode over SMS, WhatsApp or Telegram. Returns a message_id.
verify_otpCheck the code the person typed.
check_otp_statusDelivery report and whether the code is still live. Useful for debugging.
extend_otpGive someone longer before the code expires.
get_usage_reportTransaction history.
get_account_infoAccount and balance.

Getting a key

Sign up at myotp.app for 15 free credits, no card. Generate a key in the dashboard, then add the calling IP to that key's allowlist — your own address for the local server, or 108.61.176.199 for the hosted one.

Notes that save time

Phone numbers are digits only: no leading +, no trailing national prefix. 19876543210, not +1 (987) 654-3210.

A 403 almost always means the IP allowlist rather than a bad key. A 400 on a number that looks correct usually means there is no priced route to that country on that channel.

If you want delivery status pushed to you instead of polling check_otp_status, register a delivery webhook.