virtualsms-mcp 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +48 -19
- package/dist/client.js.map +1 -1
- package/package.json +6 -3
- package/ARCHITECTURE.md +0 -140
- package/ROADMAP.md +0 -48
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) o
|
|
|
68
68
|
"command": "npx",
|
|
69
69
|
"args": ["virtualsms-mcp"],
|
|
70
70
|
"env": {
|
|
71
|
-
"VIRTUALSMS_API_KEY": "
|
|
71
|
+
"VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -86,7 +86,7 @@ Edit `~/.cursor/mcp.json`:
|
|
|
86
86
|
"command": "npx",
|
|
87
87
|
"args": ["virtualsms-mcp"],
|
|
88
88
|
"env": {
|
|
89
|
-
"VIRTUALSMS_API_KEY": "
|
|
89
|
+
"VIRTUALSMS_API_KEY": "vsms_your_api_key_here"
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -217,6 +217,13 @@ On timeout, returns `order_id` for recovery:
|
|
|
217
217
|
|
|
218
218
|
---
|
|
219
219
|
|
|
220
|
+
|
|
221
|
+
## Number Rentals (Coming Soon)
|
|
222
|
+
|
|
223
|
+
Need to keep the same phone number for days or weeks? VirtualSMS supports **number rentals** for recurring verifications — perfect for long-running automations, dev testing, and accounts that require re-verification with the same number.
|
|
224
|
+
|
|
225
|
+
Rental tools (`rent_number`, `extend_rental`, `list_rentals`) are coming in v1.1. Stay tuned for updates.
|
|
226
|
+
|
|
220
227
|
## How It Works
|
|
221
228
|
|
|
222
229
|
### WebSocket vs Polling
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IA4C5C,aAAa,IAAI,IAAI;IASf,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IA4C5C,aAAa,IAAI,IAAI;IASf,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAWlC,aAAa,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAWnC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAa5D,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAS9B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAM7D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAMzC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAMnD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAM9C,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAkBnD,SAAS,IAAI,MAAM,GAAG,SAAS;IAI/B,UAAU,IAAI,MAAM;CAGrB"}
|
package/dist/client.js
CHANGED
|
@@ -17,7 +17,7 @@ export class VirtualSMSClient {
|
|
|
17
17
|
// Add auth header if API key is set
|
|
18
18
|
this.http.interceptors.request.use((config) => {
|
|
19
19
|
if (this.apiKey) {
|
|
20
|
-
config.headers['
|
|
20
|
+
config.headers['X-API-Key'] = this.apiKey;
|
|
21
21
|
}
|
|
22
22
|
return config;
|
|
23
23
|
});
|
|
@@ -51,53 +51,82 @@ export class VirtualSMSClient {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
async listServices() {
|
|
54
|
-
const res = await this.http.get('/api/v1/services');
|
|
55
|
-
|
|
54
|
+
const res = await this.http.get('/api/v1/customer/services');
|
|
55
|
+
// API returns: {services: [{service_id, service_name, base_price, ...}], success: true}
|
|
56
|
+
const raw = res.data?.services ?? res.data;
|
|
57
|
+
return raw.map((s) => ({
|
|
58
|
+
code: String(s.service_id ?? s.code ?? ''),
|
|
59
|
+
name: String(s.service_name ?? s.name ?? ''),
|
|
60
|
+
icon: s.icon ? String(s.icon) : undefined,
|
|
61
|
+
}));
|
|
56
62
|
}
|
|
57
63
|
async listCountries() {
|
|
58
|
-
const res = await this.http.get('/api/v1/countries');
|
|
59
|
-
|
|
64
|
+
const res = await this.http.get('/api/v1/customer/countries');
|
|
65
|
+
// API returns: {countries: [{country_id, country_name, min_price, services:[...]}, ...], success: true}
|
|
66
|
+
const raw = res.data?.countries ?? res.data;
|
|
67
|
+
return raw.map((c) => ({
|
|
68
|
+
iso: String(c.country_id ?? c.iso ?? ''),
|
|
69
|
+
name: String(c.country_name ?? c.name ?? ''),
|
|
70
|
+
flag: c.flag ? String(c.flag) : undefined,
|
|
71
|
+
}));
|
|
60
72
|
}
|
|
61
73
|
async checkPrice(service, country) {
|
|
62
74
|
const res = await this.http.get('/api/v1/price', {
|
|
63
75
|
params: { service, country },
|
|
64
76
|
});
|
|
65
|
-
|
|
77
|
+
// API returns: {price: 0.9, country: "GB", service: "wa", success: true}
|
|
78
|
+
const raw = res.data;
|
|
79
|
+
return {
|
|
80
|
+
price_usd: Number(raw.price ?? raw.price_usd ?? 0),
|
|
81
|
+
currency: String(raw.currency ?? 'USD'),
|
|
82
|
+
available: raw.available !== undefined ? Boolean(raw.available) : true,
|
|
83
|
+
};
|
|
66
84
|
}
|
|
67
85
|
async getBalance() {
|
|
68
86
|
this.requireApiKey();
|
|
69
|
-
const res = await this.http.get('/api/v1/balance');
|
|
70
|
-
|
|
87
|
+
const res = await this.http.get('/api/v1/customer/balance');
|
|
88
|
+
const raw = res.data;
|
|
89
|
+
return {
|
|
90
|
+
balance_usd: Number(raw.balance_usd ?? raw.balance ?? 0),
|
|
91
|
+
};
|
|
71
92
|
}
|
|
72
93
|
async createOrder(service, country) {
|
|
73
94
|
this.requireApiKey();
|
|
74
|
-
const res = await this.http.post('/api/v1/
|
|
95
|
+
const res = await this.http.post('/api/v1/customer/purchase', { service, country });
|
|
75
96
|
return res.data;
|
|
76
97
|
}
|
|
77
98
|
async getOrder(orderId) {
|
|
78
99
|
this.requireApiKey();
|
|
79
|
-
const res = await this.http.get(`/api/v1/order/${orderId}`);
|
|
100
|
+
const res = await this.http.get(`/api/v1/customer/order/${orderId}`);
|
|
80
101
|
return res.data;
|
|
81
102
|
}
|
|
82
103
|
async cancelOrder(orderId) {
|
|
83
104
|
this.requireApiKey();
|
|
84
|
-
const res = await this.http.
|
|
85
|
-
action: 'cancel',
|
|
86
|
-
});
|
|
105
|
+
const res = await this.http.post(`/api/v1/customer/cancel/${orderId}`);
|
|
87
106
|
return res.data;
|
|
88
107
|
}
|
|
89
108
|
async completeOrder(orderId) {
|
|
90
109
|
this.requireApiKey();
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
});
|
|
94
|
-
return res.data;
|
|
110
|
+
// No separate "complete" endpoint — just return the current order status
|
|
111
|
+
return this.getOrder(orderId);
|
|
95
112
|
}
|
|
96
113
|
async listOrders(status) {
|
|
97
114
|
this.requireApiKey();
|
|
98
115
|
const params = status ? { status } : {};
|
|
99
|
-
|
|
100
|
-
|
|
116
|
+
try {
|
|
117
|
+
const res = await this.http.get('/api/v1/customer/orders', { params });
|
|
118
|
+
const raw = res.data;
|
|
119
|
+
// Handle both array and {orders: [...]} shapes
|
|
120
|
+
return Array.isArray(raw) ? raw : (raw?.orders ?? []);
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
// Endpoint may not exist yet — return empty list gracefully
|
|
124
|
+
const message = err.message;
|
|
125
|
+
if (message.includes('Not found') || message.includes('404')) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
throw err;
|
|
129
|
+
}
|
|
101
130
|
}
|
|
102
131
|
getApiKey() {
|
|
103
132
|
return this.apiKey;
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAsCzD,MAAM,OAAO,gBAAgB;IACnB,IAAI,CAAgB;IACpB,MAAM,CAAU;IAChB,OAAO,CAAS;IAExB,YAAY,OAAe,EAAE,MAAe;QAC1C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,QAAQ,EAAE,kBAAkB;aAC7B;SACF,CAAC,CAAC;QAEH,oCAAoC;QACpC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC5C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "virtualsms-mcp",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "MCP server for VirtualSMS — receive SMS verification codes with AI agents. Virtual phone numbers for WhatsApp, Telegram, Google & 200+ services. SMS-Activate & DaisySMS alternative.",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "MCP server for VirtualSMS — receive SMS verification codes with AI agents. Virtual phone numbers and number rentals for WhatsApp, Telegram, Google & 200+ services. SMS-Activate & DaisySMS alternative.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"virtualsms-mcp": "dist/index.js"
|
|
@@ -30,7 +30,10 @@
|
|
|
30
30
|
"temporary-phone-number",
|
|
31
31
|
"whatsapp-verification",
|
|
32
32
|
"telegram-verification",
|
|
33
|
-
"virtualsms"
|
|
33
|
+
"virtualsms",
|
|
34
|
+
"phone-number-rental",
|
|
35
|
+
"long-term-virtual-number",
|
|
36
|
+
"sms-rental"
|
|
34
37
|
],
|
|
35
38
|
"author": "VirtualSMS",
|
|
36
39
|
"license": "MIT",
|
package/ARCHITECTURE.md
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# VirtualSMS MCP Server — Architecture
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
The VirtualSMS MCP server is a **stdio-transport MCP server** written in TypeScript. It wraps the VirtualSMS REST API and WebSocket gateway, exposing them as 11 MCP tools that AI agents can call directly.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## How MCP stdio Transport Works
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
Claude Desktop / Cursor
|
|
13
|
-
│
|
|
14
|
-
│ stdin/stdout (JSON-RPC 2.0)
|
|
15
|
-
▼
|
|
16
|
-
virtualsms-mcp process (Node.js)
|
|
17
|
-
│
|
|
18
|
-
├──► REST API calls (axios)
|
|
19
|
-
│ https://virtualsms.io/api/v1/
|
|
20
|
-
│
|
|
21
|
-
└──► WebSocket connection (ws)
|
|
22
|
-
wss://virtualsms.io/ws/orders
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The MCP client (Claude Desktop, Cursor) spawns `virtualsms-mcp` as a child process and communicates via stdin/stdout using JSON-RPC 2.0. The server is persistent — it stays alive for the lifetime of the AI session, which is why it can hold WebSocket connections.
|
|
26
|
-
|
|
27
|
-
**Important:** Never write to stdout except via the MCP SDK. Any `console.log()` would corrupt the JSON-RPC stream. Use `process.stderr` for debug output.
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## Client → API Flow
|
|
32
|
-
|
|
33
|
-
All REST calls go through `VirtualSMSClient` (src/client.ts):
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
Tool Handler → VirtualSMSClient → axios → https://virtualsms.io/api/v1/
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
The client:
|
|
40
|
-
- Attaches `Authorization: Bearer {apiKey}` to all authenticated requests
|
|
41
|
-
- Normalizes errors into human-readable messages
|
|
42
|
-
- Handles 401/403 with clear "set VIRTUALSMS_API_KEY" guidance
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## Auth Flow
|
|
47
|
-
|
|
48
|
-
1. User sets `VIRTUALSMS_API_KEY=vms_xxxxx` in their MCP config
|
|
49
|
-
2. On startup, the MCP server reads `process.env.VIRTUALSMS_API_KEY`
|
|
50
|
-
3. Every API call includes `Authorization: Bearer vms_xxxxx`
|
|
51
|
-
4. The backend validates the key by SHA-256 hash lookup in `api_keys` table
|
|
52
|
-
5. For WebSocket, the key is passed as `?api_key=vms_xxxxx` query param
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## WebSocket Connection Lifecycle (`wait_for_code`)
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
1. buy_number() → REST POST /api/v1/order → {order_id, phone_number}
|
|
60
|
-
|
|
61
|
-
2. Connect WebSocket:
|
|
62
|
-
wss://virtualsms.io/ws/orders?order_id={id}&api_key={key}
|
|
63
|
-
|
|
64
|
-
3. Server sends: {type: "connected", order_id: "...", phone_number: "...", status: "pending"}
|
|
65
|
-
|
|
66
|
-
4. When SMS arrives, server pushes:
|
|
67
|
-
{type: "sms", code: "12345", full_text: "Your code is 12345", sender: "..."}
|
|
68
|
-
|
|
69
|
-
5. MCP server resolves with the code, closes WebSocket.
|
|
70
|
-
|
|
71
|
-
6. If WebSocket fails (network error, server unreachable):
|
|
72
|
-
→ Fallback to polling GET /api/v1/order/{id} every 5s
|
|
73
|
-
|
|
74
|
-
7. If timeout:
|
|
75
|
-
→ Return {success: false, order_id: ...} so user can recover
|
|
76
|
-
→ Do NOT cancel automatically (user may still want the code)
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**Reconnect logic:** If the WebSocket disconnects unexpectedly (not on error/timeout), the client reconnects once after 1 second before falling back to polling.
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## Error Handling Strategy
|
|
84
|
-
|
|
85
|
-
All tool errors are wrapped as `McpError` to prevent server crashes:
|
|
86
|
-
|
|
87
|
-
| Error type | McpError code |
|
|
88
|
-
|------------|---------------|
|
|
89
|
-
| Zod validation | `InvalidParams` |
|
|
90
|
-
| Missing API key | `InvalidRequest` |
|
|
91
|
-
| Network/API errors | `InternalError` |
|
|
92
|
-
| Unknown tool name | `MethodNotFound` |
|
|
93
|
-
|
|
94
|
-
This means the AI agent always gets a structured error it can act on, rather than a crash.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## File Structure
|
|
99
|
-
|
|
100
|
-
```
|
|
101
|
-
virtualsms-mcp/
|
|
102
|
-
├── src/
|
|
103
|
-
│ ├── index.ts # MCP server setup, tool routing, startup
|
|
104
|
-
│ ├── client.ts # VirtualSMSClient — REST API wrapper
|
|
105
|
-
│ └── tools.ts # Tool definitions (schemas) + handlers
|
|
106
|
-
├── dist/ # Compiled output (from tsc)
|
|
107
|
-
│ ├── index.js # Has #!/usr/bin/env node shebang
|
|
108
|
-
│ ├── client.js
|
|
109
|
-
│ └── tools.js
|
|
110
|
-
├── package.json
|
|
111
|
-
├── tsconfig.json
|
|
112
|
-
├── README.md
|
|
113
|
-
├── ROADMAP.md
|
|
114
|
-
└── ARCHITECTURE.md
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Adding a New Tool
|
|
120
|
-
|
|
121
|
-
1. Add input schema (zod) to `src/tools.ts`
|
|
122
|
-
2. Add tool definition to `TOOL_DEFINITIONS` array
|
|
123
|
-
3. Add handler function `handleXxx()` to `src/tools.ts`
|
|
124
|
-
4. Add case to switch in `src/index.ts`
|
|
125
|
-
5. Export schema + handler from `src/tools.ts`
|
|
126
|
-
6. `npm run build`
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## Local Development
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
npm install
|
|
134
|
-
npm run build # compile TypeScript
|
|
135
|
-
npm run dev # watch mode (tsc --watch)
|
|
136
|
-
node dist/index.js # test startup (exits immediately — needs MCP client)
|
|
137
|
-
|
|
138
|
-
# Test with MCP Inspector:
|
|
139
|
-
npx @modelcontextprotocol/inspector node dist/index.js
|
|
140
|
-
```
|
package/ROADMAP.md
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# VirtualSMS MCP Server — Roadmap
|
|
2
|
-
|
|
3
|
-
Current version: **v1.0.0** — Core tools, WebSocket delivery, crash recovery.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## v1.1 — Smart Features
|
|
8
|
-
|
|
9
|
-
- **`smart_verify`** — Auto-retry with different countries on failure. Finds cheapest country, buys number, waits for SMS, and if it times out, cancels and tries next country automatically. (Held from v1.0 pending refund mechanics verification.)
|
|
10
|
-
- **`recommend_country`** — ML-based country recommendation based on historical success rate analytics per service.
|
|
11
|
-
- **`price_compare`** — Show VirtualSMS price vs competitors for a given service/country.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## v1.2 — Batch & Automation
|
|
16
|
-
|
|
17
|
-
- **`batch_verify`** — Buy multiple numbers in parallel for bulk verification workflows.
|
|
18
|
-
- **`webhook_mode`** — Register a callback URL to receive SMS codes instead of waiting synchronously.
|
|
19
|
-
- Notification preferences: get notified via email or Telegram when a code arrives.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## v1.3 — Multi-Provider Aggregation
|
|
24
|
-
|
|
25
|
-
- Aggregate numbers across multiple upstream SMS providers.
|
|
26
|
-
- Auto-route to cheapest/fastest provider based on real-time availability.
|
|
27
|
-
- Unified service code mapping across providers (different providers use different codes for the same service).
|
|
28
|
-
- Provider health monitoring — skip providers with high failure rates.
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## v2.0 — Remote Transport
|
|
33
|
-
|
|
34
|
-
- **SSE/Streamable HTTP transport** — zero-install, just add a URL to your MCP config.
|
|
35
|
-
- Hosted at `https://mcp.virtualsms.io`.
|
|
36
|
-
- OAuth2 auth flow for MCP clients (no more copying API keys).
|
|
37
|
-
- Usage dashboard for MCP users — see spend, history, success rates.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Future Ideas
|
|
42
|
-
|
|
43
|
-
- **Number reputation scoring** — flag numbers with low verification success rates.
|
|
44
|
-
- **Success rate analytics** — per-service, per-country historical success rates exposed via API.
|
|
45
|
-
- **Rate limiting per API key tier** — different quotas for free, pro, enterprise.
|
|
46
|
-
- **Rental numbers** — keep a number for days or weeks (not just one-time verification).
|
|
47
|
-
- **Number recycling preferences** — opt out of recycled numbers for higher success rates.
|
|
48
|
-
- **Operator filtering** — prefer specific carriers per country for higher deliverability.
|