SMS verification for AI agents

An agent can buy a number and read its code with no human in the loop.

No identity to supply

An account is a seed phrase the agent generates and keeps. Nothing to verify, nothing to hand over, nobody to be.

No card to hold

Funding is crypto. An agent with a wallet can pay for itself — no card number, no billing address, no human approving a checkout.

No page to read

Catalog, prices, purchase and delivery are all tool calls. Nothing here needs a browser or a screenshot to operate.

How do you connect the MCP server?

One endpoint, JSON-RPC 2.0 over streamable HTTP. No API key to request and nothing to install — the catalog tools work before an account exists, and only the tools that spend money need a seed.

https://otpdrop.com/mcp

Claude Code

claude mcp add --transport http otpdrop https://otpdrop.com/mcp

Cursor, Windsurf, VS Code and most others

Clients that speak HTTP natively take the same block. Cursor and Windsurf call the key mcpServers; VS Code calls it servers.

{
  "mcpServers": {
    "otpdrop": {
      "type": "http",
      "url": "https://otpdrop.com/mcp"
    }
  }
}
ClientWhere the config lives
Claude Codeclaude mcp add, or .mcp.json in the project
Claude DesktopSettings → Connectors → Add custom connector
Cursor~/.cursor/mcp.json, or .cursor/mcp.json per project
VS Code.vscode/mcp.json, under servers
Windsurf~/.codeium/windsurf/mcp_config.json

MCP clients move quickly and these paths change. If one does not match what you see, check that client's own documentation — the URL and transport above are the only parts that come from us.

What if the client only speaks stdio?

Some clients cannot open an HTTP MCP server directly. Bridge it locally:

{
  "mcpServers": {
    "otpdrop": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://otpdrop.com/mcp"]
    }
  }
}

What if you have no MCP client?

The server is a plain HTTP endpoint, so any language can call it. This lists the tools:

curl -s -X POST https://otpdrop.com/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Add Authorization: Bearer <seed> for the tools that need an account. If you would rather not speak JSON-RPC, the same operations are available as ordinary REST endpoints in the API reference.

What can an agent do on OTPDrop?

ToolDoesNeeds a seed
list_servicesEvery service with its code and categoryno
list_countriesEvery country with its dial codeno
list_catalogThe full catalog with the pricing matrixno
quoteThe price for one service and countryno
agent_helpIn-context instructions for using this serverno
create_accountGenerate a new account and its seedno
topupGet a deposit address and amount for a coinyes
topup_statusCheck whether a deposit has been creditedyes
buy_numberBuy a number, debiting the balanceyes
get_orderOrder details and current statusyes
get_smsThe verification code once it landsyes

Three read-only resources mirror the catalog for clients that prefer them: catalog://services, catalog://countries and catalog://pairs.

What does a complete run look like?

Five calls, start to finish. The only step that waits on the outside world is the deposit confirming on-chain.

  1. create_account — returns a seed. Store it; it is the only way back into the account, and it cannot be reset.
  2. topup — name a coin and an amount, get back an address, the exact amount to send, and an expiry. Send the funds from the agent's wallet.
  3. topup_status — poll until the deposit is credited to the balance.
  4. buy_number — name a service and country. The balance is debited and a number is issued immediately: no per-purchase address, no second wait.
  5. get_sms — poll until the code arrives. If none arrives before the order expires, the price returns to the balance automatically.

Fund once, buy many. A single top-up covers as many numbers as its balance allows, so only the first purchase in a session pays the confirmation wait.

What should you tell your agent?

  • The seed is unrecoverable. An agent that generates one and fails to persist it has thrown away the balance with it.
  • Deposits are credited after network confirmation, which is not instant — poll topup_status rather than assuming success.
  • Send only the coin and network named on the invoice. A wrong-network transfer cannot be recovered.
  • An arrived code completes the order and is billable, even if the destination service rejects it. See the Refund Policy.
  • Refunds return to the OTPDrop balance, never to a wallet.

Writing a conventional integration instead? The REST API documentation covers the endpoints, authentication and error codes.