MCP server for CODASMS — receive one-time SMS/OTP verification codes (get a number, wait for the code, release) across 700+ services and 180+ countries via the CODASMS Reseller API.
Strong foundation with clear naming, comprehensive parameter descriptions, and proper schema definitions using Zod. All 7 tools follow verb_noun convention (get_*, list_*, wait_for_*, check_*, release). Descriptions are detailed and contextual (avg ~150 chars), exceeding the 10-1024 char baseline. Input schemas are well-typed with min/max constraints. However, output schemas are not formally documented, responses are text-only summaries without structured field definitions. Error handling uses a guard pattern but lacks actionable recovery guidance. Tool annotations (readOnlyHint, destructiveHint) are present and correct.
One-shot status check for an order (no waiting). Returns the current status and the code if it has arrived.
Return the reseller account's current balance (what you can spend on numbers).
Buy a phone number for a service in a country and return it. THIS CHARGES the reseller balance immediately (pay-per-code). If no code arrives within 20 minutes the order auto-refunds; you can also release() it early to refund now. Poll for the code with wait_for_otp using the returned order_id.
List countries that currently have buyable numbers. Optionally filter to a single service.
List buyable services with live price and stock. STRONGLY prefer filtering by `service` and/or `country` — the unfiltered catalog is very large. `service` is a code like "tg" (Telegram); `country` is a country code like "6".
Output schemas not formally documented. Tools return text-only responses (ok/fail helpers) without structured field definitions. LLMs cannot parse response fields for downstream chaining or data extraction.
Error responses lack actionable recovery guidance. Guard pattern catches errors but returns generic '__err' field. LLMs receive no hint about retry eligibility, user-fixable vs fatal classification, or next steps.
check_order and wait_for_otp descriptions do not clarify what fields are returned when code arrives. LLMs cannot plan downstream steps without knowing response structure.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
Cancel an order and refund it immediately (if not yet delivered). After refund, the number is released back to the pool.
Poll an order until its verification code arrives, it expires, or the timeout is hit. Returns the code when delivered. On timeout the number is still active — call again, or release() to refund now.
get_number description mentions 'price guard' and 'live cell price' but does not explain what happens if price exceeds cap, does it fail, return alternatives, or silently pick a cheaper option?
list_services and list_countries accept 'limit' but do not document pagination behavior. Do they return a total_count or next_cursor for continuation? How does an LLM fetch the next page?