Skip to content
cleat.

For AI agents

A phone number your agent can actually read

An agent working in an account you already hold hits the same wall a person does: a six-digit code sent by text. Cleat gives it a real US mobile line and an MCP server to read that line. The code lands in the agent's context, not on someone's phone.

Point your client at it

The server speaks the Model Context Protocol over HTTP. Add it to any MCP client that can send an Authorization header. Create the key in your workspace settings, where it's shown once.

mcp.json
{
  "mcpServers": {
    "cleat": {
      "type": "http",
      "url": "https://cleat.so/api/mcp",
      "headers": { "Authorization": "Bearer clt_your_api_key" }
    }
  }
}

The key decides what the agent can reach. Left open, that is its own workspace's lines and nothing else. Narrow it when you create it — to named lines, and to a date it stops working — and the agent reaches only the line you meant: anything else answers 404, and after the date the key answers 401 with code key_expired. Revoke it and the agent is locked out on the next call. No password or session is affected.

The four tools

ToolWhat it does
list_linesThe workspace's numbers, newest first. Start here: every other tool takes a lineId from it.
list_messagesTexts received by one line, newest first. limit is 1 to 200, 20 by default.
latest_codeThe most recent verification code on a line, or found: false if none has arrived. Optional from and service narrow it to one sender.
wait_for_codeWaits for the *next* code and returns it. Up to 55 seconds; 30 by default. Takes the same optional from and service, and keeps waiting through a code that doesn't match.
Anything the key can't reach comes back as a readable tool error, not a crash, so the model can act on it.

Waiting beats polling

wait_for_code only counts texts that arrive after the call starts. A code left over from an earlier sign-in is never mistaken for this one. Call it immediately before the step that triggers the text, then submit the form. The tool is already listening.

Wait for the next code
curl https://cleat.so/api/mcp \
  -H "Authorization: Bearer $CLEAT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "wait_for_code",
      "arguments": { "lineId": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10", "timeoutSeconds": 45 }
    }
  }'
The answer
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "found": true,
      "id": "c9a7e0d2-5b1f-4e8a-9f3c-6d2b1a0e4f77",
      "line": { "id": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10", "phone": "13055550100", "label": "Agent line" },
      "from": "55512",
      "body": "Your verification code is 704 118",
      "code": "704118",
      "receivedAt": "2026-09-11T10:02:41.000Z",
      "service": null,
      "contact": null,
      "label": null
    },
    "content": [{ "type": "text", "text": "…the same JSON again, for the model to read" }]
  }
}

If nothing arrives in time it returns found: false with timedOut: true. That is an ordinary result the agent can retry, not an error.

Why the number has to outlast the sign-up

Most numbers sold for agent work are rented by the minute or the week and then returned to a pool. That fits one sign-up and fails an account the agent keeps. Even vendors selling the disposable kind make the argument against it: “If your agent creates an account and keeps operating it, a one-time number is a problem, because platforms periodically re-verify, and if the number is gone the account locks out.” And: “A dedicated number stays assigned to that agent's account, holds its verification history, and receives the new code whenever a platform re-checks” (GeeLark, 16 September 2026).

A Cleat line is the durable kind by construction. One number on a subscription, no rental clock, and no endpoint that rotates it. A re-check three months later lands on the same line, and a signed webhook can wake a process that isn't running to catch it. What Cleat doesn't sell is the other half of that pitch: pools of fresh numbers for provisioning accounts at volume. One line per subscription, one verified owner, for accounts that owner is entitled to hold.

What this is, and what it isn't

  • Receive only. Cleat Line receives texts. It cannot send them, and there is no tool that tries. It cannot place or answer a call either.
  • A code phoned in still lands. When a service reads a code out over an automated call, the call is transcribed. The transcript arrives as an ordinary message, code extracted, with the number that called in from. No field marks it as a call.
  • One number per subscription. Each line is $24.99 a month. Cleat isn't a pool of throwaway numbers, and there's no endpoint that rotates them.
  • A verified human owns every line. Identity is checked once, for the account, before any number is issued. An agent can't sign itself up.
  • 120 requests a minute per key. A wait_for_code that's waiting isn't spending requests.
  • A line on hold can't be read. If a subscription lapses, the number is held and its texts stay locked until it resumes.

If you'd rather not use MCP

The same data is a plain REST API with signed webhooks. It suits a long-running service better than an agent session: see Cleat for developers. To share codes with people instead of programs, use the team inbox. A real mobile line receives codes that an internet number never gets: see non-VoIP numbers and Google Voice and verification codes.

Questions

Which clients work?

Any MCP client that can reach an HTTP server and set an Authorization header. The server answers JSON-RPC over POST and returns ordinary JSON. There's no SSE to configure.

Can the agent send a text?

No. Cleat Line is receive-only, and no tool sends.

What if the service phones the code instead of texting it?

It still arrives. The call is transcribed and stored like a text, so latest_code and wait_for_code return its code and list_messages shows the calling number in from. The agent can't answer or return the call.

Can I give each agent its own number?

Yes. Add a line per agent in the same workspace, each its own $24.99 subscription and its own key. Then scope each key to that one line, so an agent can reach its own line and nothing else — a line outside a key's scope answers 404, exactly as another workspace's line does. An unscoped key does see every line in its workspace, so scope the ones you hand out.

What happens if two agents wait on the same line?

Both are told about the next code. The line is a shared inbox, not a queue, so give agents that must not collide their own lines.

Does an agent need to verify its identity?

The account does, once, and a person does it. Agents work under a verified account's key; they never sign up on their own.

Is there a free tier?

No. One line is $24.99 a month, cancel anytime.

Sources

Facts about other companies come from their own pages, checked in September 2026.

  1. GeeLark, how to give your AI agent a phone number https://www.geelark.com/blog/how-to-give-your-ai-agent-a-phone-number

Get a line your agent can read.

$24.99/month · cancel anytime

  • Every owner ID-verified
  • Texts private to your team
  • Cancel anytime