Model Context Protocol

A phone verification MCP server for your AI agent

Connect it once and your agent can ask whether a number is a live mobile, who carries it, and whether it belongs to a known TCPA litigator, then act on the answer. Works in Claude Code, Cursor, Claude Desktop, VS Code and Windsurf with nothing but your API key.

No OAuth, just a Bearer key $0.20 a lookup, nothing for a bad number Open source, MIT Listed in the official MCP registry

What your agent gets

The endpoint is https://numberbroom.com/mcp, Streamable HTTP. It is a stateless proxy over the same REST API the developer docs describe, so auth, rate limits and billing are identical.

verify_phone_number

Takes one US number in any common format. Returns carrier-level line type (mobile, landline, VoIP, disconnected), carrier name, an activity score and whether the number is a known TCPA litigator, plus a keep or drop outcome the agent can act on. Does not check Do Not Call registries.

Unparseable number: $0
get_credit_balance

Remaining pre-paid balance on the connected account, with the number of lookups it covers. Lets an agent check before a run and stop cleanly instead of failing mid-list.

Free to call
What a turn looks like
youIs (902) 555-1234 safe to put on tomorrow's dial list?
agentcalls verify_phone_number { "phone": "(902) 555-1234" }
tool+19025551234: mobile on Verizon Wireless. Charged $0.2. { "isLitigator": false, "activityScore": 82, "outcome": "clean", "keep": true, ... }
agentYes. It is an active Verizon mobile, activity score 82, and it is not on the litigator list. Note that this did not check the National Do Not Call Registry.

Three steps, one of them in your editor

1

Create an account and add credit

Sign up with email or Google, then top up between $10 and $5,000 from Settings. Credit is pre-paid, never expires, and is the only thing you are ever billed.

2

Generate a key for this client

In Settings, API access. Label it after the client, like "Cursor on laptop", and make a separate key for each one, so a leak is one revoke. It starts with nb_live_ and is shown once; only a hash is stored.

3

Add the server to your client

Pick your client below and paste the snippet with your key in place of nb_live_YOUR_KEY. Then ask your agent to verify a number.

Claude Code

One command. Claude Code speaks Streamable HTTP natively and passes the header on every request.

  1. Run this in a terminal, with your key in place of the placeholder. Add --scope user to make it available in every project rather than the current one.

    terminal
    claude mcp add --transport http numberbroom https://numberbroom.com/mcp \
      --header "Authorization: Bearer nb_live_YOUR_KEY"
  2. Or, for a repo the whole team shares, commit a .mcp.json that reads the key from an environment variable so it never lands in git:

    .mcp.json
    {
      "mcpServers": {
        "numberbroom": {
          "type": "http",
          "url": "https://numberbroom.com/mcp",
          "headers": { "Authorization": "Bearer ${NUMBERBROOM_API_KEY}" }
        }
      }
    }
  3. Type /mcp inside Claude Code to confirm numberbroom shows as connected, then ask: "Verify (902) 555-1234 and tell me whether it is safe to dial."

If the key is wrong, Claude Code reports the connection as failed rather than falling back to an OAuth prompt. Re-check the header before anything else.

Cursor

Cursor reads MCP servers from a JSON file and supports a headers block on remote servers.

  1. Create or open ~/.cursor/mcp.json for every project, or .cursor/mcp.json inside one project, and add:

    mcp.json
    {
      "mcpServers": {
        "numberbroom": {
          "url": "https://numberbroom.com/mcp",
          "headers": { "Authorization": "Bearer nb_live_YOUR_KEY" }
        }
      }
    }
  2. In a project file that other people can see, write "Bearer ${env:NUMBERBROOM_API_KEY}" instead and export the variable in your shell. Cursor resolves ${env:NAME} inside headers.

  3. Open Cursor's MCP settings, check that numberbroom is enabled with two tools listed, and ask the agent to verify a number.

Claude Desktop

The "Add custom connector" dialog only takes a URL and optional OAuth credentials; it has nowhere to put an API key. Claude Desktop does still run local stdio servers from its config file, so the open source mcp-remote bridge carries the header for you. Needs Node.js installed.

  1. Open Settings, Developer, Edit Config. That opens claude_desktop_config.json: on macOS it lives in ~/Library/Application Support/Claude/, on Windows in %APPDATA%\Claude\.

  2. Add the server. The header value goes through an environment variable on purpose: Claude Desktop on Windows mangles a space inside an argument, and Authorization:${AUTH_HEADER} with no space avoids it.

    claude_desktop_config.json
    {
      "mcpServers": {
        "numberbroom": {
          "command": "npx",
          "args": [
            "mcp-remote",
            "https://numberbroom.com/mcp",
            "--transport", "http-only",
            "--header", "Authorization:${AUTH_HEADER}"
          ],
          "env": { "AUTH_HEADER": "Bearer nb_live_YOUR_KEY" }
        }
      }
    }
  3. Quit and reopen Claude Desktop. The tools icon under the message box lists numberbroom once the bridge is up.

This is the desktop app only. The claude.ai website, mobile apps and Cowork connect from Anthropic's cloud and cannot use this file; see the Claude.ai tab.

VS Code with GitHub Copilot

VS Code's MCP config supports HTTP servers with headers, and its inputs mechanism prompts for the key once and stores it as a secret instead of writing it into the file.

  1. Add this to .vscode/mcp.json in the workspace, or to your user-level file via the MCP: Open User Configuration command:

    .vscode/mcp.json
    {
      "inputs": [
        { "type": "promptString", "id": "numberbroom-key", "description": "NumberBroom API key (nb_live_...)", "password": true }
      ],
      "servers": {
        "numberbroom": {
          "type": "http",
          "url": "https://numberbroom.com/mcp",
          "headers": { "Authorization": "Bearer ${input:numberbroom-key}" }
        }
      }
    }
  2. Click Start above the server entry, paste the key when prompted, then use the tools from Copilot's agent mode.

Windsurf

Windsurf's Cascade reads remote servers from a JSON file with a serverUrl and a headers block.

  1. Open ~/.codeium/windsurf/mcp_config.json (Cascade's MCP settings has a button for it) and add:

    mcp_config.json
    {
      "mcpServers": {
        "numberbroom": {
          "serverUrl": "https://numberbroom.com/mcp",
          "headers": { "Authorization": "Bearer nb_live_YOUR_KEY" }
        }
      }
    }
  2. Refresh the server list in Cascade and confirm both tools appear.

Claude.ai, mobile apps and Cowork

Not supported today, and we would rather say so than hand you a snippet that fails.

Claude's custom connectors connect to a remote server from Anthropic's cloud and authenticate with OAuth or with nothing at all. The dialog has a URL field and optional OAuth Client ID and Secret, and no place for an API key. NumberBroom does not run an OAuth server, so there is no way to hand claude.ai your key.
  1. Use Claude Code or Claude Desktop instead. Both hold the key on your machine and send it as a header, which is exactly what this server expects. Their tabs are above.

  2. If your team needs this inside claude.ai specifically, tell us. An OAuth front for the server is a real piece of work, and knowing someone is waiting on it is what moves it up the list.

ChatGPT

ChatGPT's MCP connectors, in Developer mode, accept OAuth or no authentication, and OpenAI's own docs say ChatGPT cannot present custom API keys. So the MCP endpoint is not reachable from ChatGPT. The REST API is, through a custom GPT Action with API key auth, and it returns the same fields.

  1. Open the GPT editor, create a GPT, go to Configure, Actions, Create new action.

  2. Set Authentication to API Key, Auth Type to Bearer, and paste your nb_live_ key. OpenAI encrypts it at rest and it never appears in the chat.

  3. Paste this schema. It describes the two REST endpoints the MCP tools wrap:

    openapi.yaml
    openapi: 3.1.0
    info:
      title: NumberBroom phone verification
      version: "1.0"
    servers:
      - url: https://numberbroom.com/api
    paths:
      /v1/verify:
        post:
          operationId: verifyPhoneNumber
          summary: Verify one US phone number. Returns line type, carrier, activity score and TCPA litigator status. Costs $0.20; an unparseable number is free.
          requestBody:
            required: true
            content:
              application/json:
                schema:
                  type: object
                  required: [phone]
                  properties:
                    phone:
                      type: string
                      description: The number in any common US format.
          responses:
            "200":
              description: Verification result. valid is false when the input is not a US phone number.
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      e164: { type: string }
                      valid: { type: boolean }
                      lineType: { type: string }
                      carrier: { type: string }
                      isLitigator: { type: boolean }
                      activityScore: { type: number }
                      isLikelyDisconnected: { type: boolean }
                      outcome: { type: string }
                      keep: { type: boolean }
                      dncEvaluated: { type: boolean }
                      charged: { type: number }
                      creditsRemaining: { type: number }
      /v1/credits:
        get:
          operationId: getCreditBalance
          summary: Remaining pre-paid balance and how many lookups it covers. Free to call.
          responses:
            "200":
              description: Balance
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      credits: { type: number }
                      ratePerLookup: { type: number }
                      lookupsRemaining: { type: integer }
  4. Save, then test in the preview: "Verify (902) 555-1234." Every lookup spends the key owner's balance, so keep the GPT private to your team rather than publishing it to the store.

A GPT can use either apps or actions, not both, so this action lives in a GPT of its own. The full REST reference is on the developer page.

Any other MCP client

If your client can add a remote server over Streamable HTTP and attach a static header, it works. Most clients take a JSON block shaped like this; the field names vary slightly, the values do not.

  1. connection
    {
      "url": "https://numberbroom.com/mcp",
      "transport": "streamable-http",
      "headers": { "Authorization": "Bearer nb_live_YOUR_KEY" }
    }
  2. If the client only speaks stdio, run it through npx mcp-remote https://numberbroom.com/mcp --header "Authorization: Bearer nb_live_YOUR_KEY", the same bridge the Claude Desktop tab uses.

  3. Searching for numberbroom in a client that browses the official MCP registry finds the same server: it is published there as io.github.cameron-creations/numberbroom-mcp.

To check the endpoint is up without a client, POST an initialize request to it; the server answers with its name and version. Source and a test suite are at github.com/cameron-creations/numberbroom-mcp.

Same price as the API, because it is the API

No subscription and no per-seat fee. Your agent spends the balance you loaded, one lookup at a time.

Per lookup
$0.20

Line type, carrier, activity score and litigator flag, all in one call.

Top-up
$10 to $5,000

Pre-paid through Stripe. Credit does not expire.

Daily limit over MCP
500

Lookups a day per key through this server, unless you set the key's own limit, up to 5,000 lookups. Resets at midnight UTC.

Never charged
$0

Unparseable numbers, failed carrier lookups, and every balance check.

Before you connect

Do I need OAuth or a separate developer account?
No. The only credential is your NumberBroom API key, sent as a Bearer token in the connection's Authorization header. Generate it in Settings after adding credit. There is no OAuth flow, no app registration and no per-seat plan.
Does the MCP server store my key or the numbers I check?
It holds nothing. Each tool call forwards your Authorization header to the same REST API the developer docs describe and returns the answer; the worker has no database, no session and no OAuth flow, and a fresh server instance is built per request so nothing crosses between callers. The source is public under the MIT licence.
What does a lookup cost, and when am I not charged?
verify_phone_number costs $0.20 against your pre-paid balance, the same as one REST call. A number that does not parse as a US phone number is answered as valid: false and costs nothing, a lookup the carrier data provider cannot complete is refunded, and get_credit_balance is always free. Through this server a key stops at 500 lookups a day unless you give it its own limit in Settings, up to 5,000 lookups. Credit is topped up between $10 and $5,000 and does not expire.
What if an agent loops, or my key leaks?
Two limits hold. A key used through this server with no limit of its own stops at 500 lookups a day, which is $100 at most, and you can set any key lower in Settings, API access. Keys are one per client, up to 10, so revoking a leaked one takes effect on its next call and leaves your other clients working. A stolen key cannot raise its own limit or mint another: key management needs your signed-in account.
Can my agent scrub a whole list through MCP?
One number per call: there is no batch tool, because the REST API it wraps has no batch endpoint. An agent can call it in a loop for a handful of numbers, but for a file the CSV upload is the right door: the same line type, carrier and litigator checks on every row, priced per row with volume bands and a $5 minimum.
Does it check the Do Not Call registry?
No. Every response carries dncEvaluated: false so an agent never has to infer coverage it has not got. The litigator flag comes from a court-sourced database of known TCPA plaintiffs. Screening reduces risk; it does not eliminate it, and none of this is legal advice.
Why can I not add it in claude.ai or ChatGPT?
Both connect to remote MCP servers from their own cloud and authenticate with OAuth or nothing at all; neither has a field for an API key, and NumberBroom does not run an OAuth server. Claude Code, Claude Desktop, Cursor, VS Code and Windsurf hold the key on your machine and send it as a header, so they work today. ChatGPT users can reach the same lookups through a custom GPT Action against the REST API.

Give your agent a phone it can trust

Add credit, generate a key, paste one snippet. The first lookup is a minute away and costs twenty cents.