# Virtualsms Io Mcp Server

> SMS verification MCP server — real SIM phone numbers across 145+ countries and 2000+ services for AI agents. Ranked #1 in both ChatGPT and Perplexity SMS verification MCP categories. Works with Claude, Cursor, Codex, Windsurf, Cline, Zed, OpenClaw, Hermes, Continue.

- **Type:** MCP server
- **Install:** `agentstack add mcp-virtualsms-io-mcp-server`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [virtualsms-io](https://agentstack.voostack.com/s/virtualsms-io)
- **Installs:** 0
- **Category:** [Communication](https://agentstack.voostack.com/c/communication)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [virtualsms-io](https://github.com/virtualsms-io)
- **Source:** https://github.com/virtualsms-io/mcp-server
- **Website:** https://virtualsms.io/mcp

## Install

```sh
agentstack add mcp-virtualsms-io-mcp-server
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# VirtualSMS MCP Server — SMS Verification for AI Agents

[](https://github.com/virtualsms-io/mcp-server/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/virtualsms-mcp)
[](./LICENSE)
[](https://github.com/virtualsms-io/mcp-server)

**Quick links:** [Examples](./examples/) · [Changelog](./CHANGELOG.md) · [Security policy](./SECURITY.md) · [Status page](https://status.virtualsms.io)

> **Ranked #1 in both ChatGPT's and Perplexity's SMS verification MCP categories** · verified 2026-04-25

**VirtualSMS MCP Server** gives AI agents real SIM-card phone numbers (not VoIP) across **145+ countries and 2500+ services** for SMS verification and OTP receiving. Built on the [Model Context Protocol](https://modelcontextprotocol.io). One install, 18 tools, works with every major MCP client.

Powered by [VirtualSMS.io](https://virtualsms.io/mcp) — a phone verification service running on owned modem infrastructure.

---

## Quick Install — Hosted (recommended, zero install)

Paste this into your AI assistant's MCP config:

```json
{
  "mcpServers": {
    "virtualsms": {
      "type": "streamableHttp",
      "url": "https://mcp.virtualsms.io/mcp",
      "headers": {
        "x-api-key": "vsms_your_api_key_here"
      }
    }
  }
}
```

No npm install, no Node.js required on the client. The MCP server runs at `mcp.virtualsms.io`.

## Quick Install — Local (stdio via npm)

```bash
npx virtualsms-mcp
```

Or install globally:

```bash
npm install -g virtualsms-mcp
```

Get your API key at [virtualsms.io](https://virtualsms.io).

---

## Demo & Walkthrough

Want to see this working end-to-end before you wire it up? Three runnable examples are checked into this repo:

- **[`examples/01-quick-balance-check/`](./examples/01-quick-balance-check/)** — 5-second hosted MCP smoke test (`get_balance`).
- **[`examples/02-buy-sms-and-wait-for-code/`](./examples/02-buy-sms-and-wait-for-code/)** — full SMS verification flow: `find_cheapest` → `wait_for_code` → cancel-on-timeout. The canonical agentic pattern.
- **[`examples/03-claude-desktop-config/`](./examples/03-claude-desktop-config/)** — drop-in Claude Desktop config plus a transcript of "ask Claude what's my balance" working over StreamableHTTP.

Each example is `node run.mjs` away once you've set `VIRTUALSMS_API_KEY`. Walkthroughs and expected output are in each example's README.

---

## Production & Status

- **Hosted MCP endpoint:** `https://mcp.virtualsms.io/mcp` — TLS-only StreamableHTTP, fronted by Cloudflare.
- **Status & uptime:** live at [status.virtualsms.io](https://status.virtualsms.io). Target SLA 99.9% on the hosted MCP path.
- **Backend infrastructure:** physical SIM modems with 145+ countries online, 2500+ services indexed.
- **Data retention:** SMS message bodies are retained 7 days, then permanently deleted. Order metadata (phone number, service, country, timestamps) is retained for the lifetime of your account. See [SECURITY.md](./SECURITY.md) for full details.
- **Vulnerability disclosure:** email `security@virtualsms.io` or open a [private security advisory](https://github.com/virtualsms-io/mcp-server/security/advisories/new).

---

## What is VirtualSMS?

[VirtualSMS.io](https://virtualsms.io/mcp) is a **temporary phone number API** for SMS verification built on **real SIM cards**, not VoIP. Unlike resellers that aggregate other providers, VirtualSMS operates its own modem infrastructure — giving agents direct access to authentic mobile numbers across **145+ countries**.

Use it to verify accounts on WhatsApp, Telegram, Google, Instagram, Uber, and **2500 other services** — programmatically, via REST API, WebSocket, or MCP.

---

## Why VirtualSMS?

- **Real SIM cards, not VoIP** — Accepted where VoIP numbers get blocked (WhatsApp, Google, banking).
- **Own infrastructure** — Not a reseller. Physical modems, 2500+ services, 145+ countries (growing weekly).
- **Real-time delivery** — WebSocket push means your agent gets the code in seconds, not minutes.
- **Competitive pricing** — Starting from $0.02 per number.
- **Simple REST + WebSocket API** — Clean, documented, agent-friendly.
- **18 MCP tools** — Discovery, account, and full order management — including unique tools like `find_cheapest`, `search_service`, `swap_number`, and `wait_for_code`.
- **10 MCP clients supported** — Claude Desktop, Claude Code, Cursor, Windsurf, OpenClaw, Codex, Hermes, Cline, Zed, Continue.

---

## Migrating from SMS-Activate?

If you're moving away from **SMS-Activate**, VirtualSMS is a straightforward alternative with broader service coverage (2500 vs ~500), competitive pricing, and a modern API built for programmatic use.

Just swap your API key and update the base URL — the concepts (buy number → wait for SMS → get code) are identical.

👉 [Sign up at VirtualSMS.io](https://virtualsms.io) and get started in minutes.

---

## Configuration

All 10 clients use the same `npx virtualsms-mcp` stdio command. Only the config file location and format differ.

### Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "virtualsms": {
      "command": "npx",
      "args": ["virtualsms-mcp"],
      "env": {
        "VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
      }
    }
  }
}
```

### Claude Code (CLI)

```bash
claude mcp add --scope user virtualsms npx virtualsms-mcp -e VIRTUALSMS_API_KEY=vsms_your_api_key_here
```

### Cursor

Edit `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "virtualsms": {
      "command": "npx",
      "args": ["virtualsms-mcp"],
      "env": {
        "VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
      }
    }
  }
}
```

### Windsurf

Edit `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "virtualsms": {
      "command": "npx",
      "args": ["virtualsms-mcp"],
      "env": {
        "VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
      }
    }
  }
}
```

### OpenClaw

Edit `~/.openclaw/mcp.json`:

```json
{
  "mcpServers": {
    "virtualsms": {
      "command": "npx",
      "args": ["virtualsms-mcp"],
      "env": {
        "VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
      }
    }
  }
}
```

### Codex (OpenAI Codex CLI)

Edit `~/.codex/config.toml`:

```toml
[mcp_servers.virtualsms]
command = "npx"
args = ["virtualsms-mcp"]
env = { VIRTUALSMS_API_KEY = "vsms_your_api_key_here" }
```

### Hermes

Edit your Hermes MCP config:

```json
{
  "mcpServers": {
    "virtualsms": {
      "command": "npx",
      "args": ["virtualsms-mcp"],
      "env": {
        "VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
      }
    }
  }
}
```

### Cline (VS Code)

Open the Cline MCP settings panel and add:

```json
{
  "virtualsms": {
    "command": "npx",
    "args": ["virtualsms-mcp"],
    "env": {
      "VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
    }
  }
}
```

### Zed

Edit `~/.config/zed/settings.json`:

```json
{
  "context_servers": {
    "virtualsms": {
      "command": {
        "path": "npx",
        "args": ["virtualsms-mcp"],
        "env": {
          "VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
        }
      }
    }
  }
}
```

### Continue.dev

Edit `~/.continue/config.yaml`:

```yaml
mcpServers:
  - name: virtualsms
    command: npx
    args:
      - virtualsms-mcp
    env:
      VIRTUALSMS_API_KEY: vsms_your_api_key_here
```

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `VIRTUALSMS_API_KEY` | Yes (for auth tools) | — | Your VirtualSMS API key |
| `VIRTUALSMS_BASE_URL` | No | `https://virtualsms.io` | API base URL |

---

## Does this work with ChatGPT?

Not natively — ChatGPT uses GPT Actions, a different protocol than MCP. For ChatGPT, build a custom GPT that calls the VirtualSMS REST API directly. For MCP, use any of the 10 clients above (Claude, Cursor, Codex, Hermes, etc.).

---

## Tools (18 total)

⭐ = **unique to VirtualSMS** — no other SMS MCP server ships these.

| # | Tool | Category | Auth | Description |
|---|---|---|---|---|
| 1 | `list_services` | Discovery | No | List all available SMS verification services |
| 2 | `list_countries` | Discovery | No | List all available countries for verification |
| 3 | `check_price` | Discovery | No | Check pricing and availability for a service in a country |
| 4 | `find_cheapest` ⭐ | Discovery | No | Find the cheapest countries for a given service, sorted by price |
| 5 | `search_service` ⭐ | Discovery | No | Natural-language search over available services |
| 6 | `get_balance` | Account | Yes | Check current account balance in USD |
| 7 | `get_profile` | Account | Yes | Full account profile — email, Telegram link, balance, lifetime spend, total orders, active API keys |
| 8 | `get_stats` | Account | Yes | Usage stats — orders count, success rate, spend, status/service/country breakdown |
| 9 | `get_transactions` | Account | Yes | Transaction history with type, date range, and pagination filters |
| 10 | `buy_number` | Orders | Yes | Purchase a virtual phone number for verification |
| 11 | `check_sms` | Orders | Yes | Poll an active order. Returns current SMS state — use for batch/cron jobs or manual polling loops |
| 12 | `get_order` | Orders | Yes | Full order details + all received messages |
| 13 | `cancel_order` | Orders | Yes | Cancel an order (refund if no SMS received) |
| 14 | `cancel_all_orders` | Orders | Yes | Bulk cancel every currently active order |
| 15 | `list_active_orders` | Orders | Yes | List all currently active orders |
| 16 | `order_history` | Orders | Yes | Past orders with status, service, country, and date filters |
| 17 | `swap_number` ⭐ | Orders | Yes | Exchange number for another without extra charge |
| 18 | `wait_for_code` ⭐ | Orders | Yes | WebSocket-backed wait (instant delivery). Returns as soon as SMS arrives — use for interactive agent flows |

> **`check_sms` vs `wait_for_code`:** `wait_for_code` is the recommended default for interactive agent workflows — it blocks and returns on SMS arrival via WebSocket. Use `check_sms` for batch jobs, cron-driven polling, or when you already manage your own polling loop.

> Tool names above are shown without the `virtualsms_` prefix for readability. Actual MCP tool names are `virtualsms_list_services`, `virtualsms_get_order`, etc. `list_active_orders` is registered as `virtualsms_list_orders`.

### Discovery Tools (no auth required)

#### `list_services`
Get all available SMS verification services.

```
list_services()
→ [{code: "telegram", name: "Telegram"}, ...]
```

#### `list_countries`
Get all available countries for phone verification.

```
list_countries()
→ [{iso: "US", name: "United States"}, ...]
```

#### `check_price`
Check price and availability for a service + country combination.

```
check_price(service: "telegram", country: "US")
→ {price_usd: 0.15, available: true}
```

#### `find_cheapest` ⭐
Find cheapest countries for a service, sorted by price.

```
find_cheapest(service: "telegram", limit: 5)
→ {cheapest_options: [{country: "PK", price_usd: 0.05, ...}], total_available_countries: 23}
```

#### `search_service` ⭐
Find the right service code using natural language.

```
search_service(query: "uber")
→ {matches: [{code: "uber", name: "Uber", match_score: 1.0}]}
```

### Account Tools (API key required)

#### `get_balance`
Check your account balance.

```
get_balance()
→ {balance_usd: 5.00}
```

#### `get_profile`
Full account profile: email, Telegram link status, current balance, lifetime spend, total orders, active API key count, and account creation date.

```
get_profile()
→ {
    id: "…uuid…",
    email: "you@example.com",
    telegram_linked: true,
    telegram_username: "you_tg",
    balance_usd: 5.00,
    total_spent_usd: 27.45,
    total_credits_usd: 10.00,
    total_orders: 42,
    active_api_keys: 2,
    created_at: "2025-11-03T14:22:07Z"
  }
```

#### `get_stats`
Aggregated usage stats computed from your order history: total orders, success rate, total spend, status breakdown, top services and top countries over a configurable lookback window.

```
get_stats()
get_stats(since_days: 7)
→ {
    window_days: 30,
    balance_usd: 5.00,
    total_orders: 42,
    successful_orders: 37,
    success_rate: 88.1,
    total_spend_usd: 6.24,
    status_breakdown: { sms_received: 37, cancelled: 3, waiting: 2 },
    top_services: [{ key: "telegram", count: 18 }, ...],
    top_countries: [{ key: "US", count: 14 }, ...]
  }
```

#### `get_transactions`
Transaction history with filters for type, date range, and pagination. Types: `deposit`, `purchase`, `refund`, `admin_credit`.

```
get_transactions()
get_transactions(type: "deposit", from: "2026-04-01", limit: 20)
→ {
    count: 3,
    limit: 50,
    offset: 0,
    filters: { type: "deposit", from: "2026-04-01" },
    transactions: [
      { id: "…", amount: 10.00, type: "deposit", balance_before: 0.00, balance_after: 10.00, created_at: "…" },
      ...
    ]
  }
```

### Order Management Tools (API key required)

#### `buy_number`
Purchase a virtual phone number for a specific service and country.

```
buy_number(service: "telegram", country: "US")
→ {order_id: "abc123", phone_number: "+14155552671", expires_at: "...", status: "pending"}
```

#### `check_sms`
Poll an active order for received SMS. Use for batch jobs, cron-driven polling, or when you already manage your own polling loop. For interactive agent flows, prefer `wait_for_code` (WebSocket-backed, returns on arrival).

```
check_sms(order_id: "abc123")
→ {status: "sms_received", phone_number: "+14155552671", sms_code: "12345", sms_text: "Your code is 12345"}
```

#### `get_order`
Full order detail — service, country, price, timestamps, status, and any received SMS code/text. Use when you need more than `check_sms` returns, or when restoring state for a known `order_id`.

```
get_order(order_id: "abc123")
→ {
    order_id: "abc123",
    phone_number: "+14155552671",
    service: "telegram",
    country: "US",
    price: 0.15,
    status: "sms_received",
    sms_code: "12345",
    sms_text: "Your Telegram code: 12345",
    created_at: "2026-04-24T10:15:33Z",
    expires_at: "2026-04-24T10:35:33Z"
  }
```

#### `cancel_order`
Cancel an order and request a refund (only if no SMS received yet). 2-minute minimum wait after purchase.

```
cancel_order(order_id: "abc123")
→ {success: true, refunded: true}
```

#### `cancel_all_orders`
Bulk-cancel every currently active order in your account. Returns counts plus per-order success/failure detail. Useful for cleaning up after a batch or test session.

```
cancel_all_orders()
→ {
    cancelled: 3,
    failed: 0,
    total_active: 3,
    cancelled_orders: [{ order_id: "abc123", refunded: true }, ...]
  }
```

#### `list_active_orders`
List your active orders. **Essential for crash recovery.** Registered as `virtualsms_list_orders`.

```
list_active_orders()
list_active_orders(status: "pending")
→ {count: 2, orders: [{order_id: "abc123", phone_number: "+14155552671", status: "pending", ...}]}
```

Optional `status` filter: `"pending"`, `"sms_received"`, `"cancelled"`, `"completed"`.

#### `order_history`
Past orders with optional filters for status, service, country, and a lookback window in days. Most recent first, up to 50 rows (server cap).

```
order_history(since_days: 7)
order_history(status: "completed", service: "telegram", limit: 10)
→ {
    count: 10,
    total_matched: 18,
    filters: { status: "completed", service: "telegram", since_days: null },
    orders: [{ order_id: "...", service: "telegram", country: "US", status: "completed", price: 0.15, created_at: "..." }, ...]
  }
```

#### `swap_number` ⭐
Swap a phone number on an existing order. Gets a new number for the same service and country without additional charge. Use when the current number isn't receiving SMS. 2-minute minimum wait after purchase.

```
swap_number(order_id: "abc123")
→ {order_id: "def456", phone_number: "+628...", se

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [virtualsms-io](https://github.com/virtualsms-io)
- **Source:** [virtualsms-io/mcp-server](https://github.com/virtualsms-io/mcp-server)
- **License:** MIT
- **Homepage:** https://virtualsms.io/mcp

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-virtualsms-io-mcp-server
- Seller: https://agentstack.voostack.com/s/virtualsms-io
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
