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, Cursor, and anything else that speaks the Model Context Protocol.

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.

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.

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.