0.0 / 30
What changed in the harness
Selection accuracy 100→100, token cost up 4%, unconfirmed writes 0%→0%.
Category breakdown
Where the score comes from.
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
01Safety
02Legibility
18.7 / 30
03Economics
16.6 / 20
04Discoverability
11.8 / 20
Highest-impact fix
Estimated gain +30 pointsAdd explicit identity and permission preflight tools
Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.
Description evidence
Defects and rewrites.
26 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
virtualsms_list_proxy_catalog |
no_return_description |
Returns the proxy catalog: available pool types, the countries each pool covers, and the price per GB. Use this before buying proxy traffic to choose a pool_type for virtualsms_buy_proxy. |
virtualsms_rotate_proxy |
no_return_description |
Requests a fresh IP for an existing proxy and returns the updated endpoint with its new exit IP. Use it when the current exit IP is flagged or blocked by a target endpoint. |
virtualsms_get_proxy_usage |
no_return_description |
Returns cached GB used, GB remaining, and request count for one proxy. Cheap — no upstream call; it reads a value refreshed every ~5 minutes. |
virtualsms_get_proxy_usage_history |
no_return_description |
Returns a per-day series of traffic (GB) and request counts for one proxy over the last 7 or 30 days. Use the range parameter to choose the window (default 7d). |
virtualsms_set_proxy_targeting |
no_return_description |
Persists a default geo-targeting (country, and optionally cities/ASNs) on an existing proxy sub-user and returns the resulting stored default. Country-only is free; adding cities or ASNs bills your own GB at 2x on non-premium pools (free on residential_premium). This changes the STORED default — for a one-off connection string with any targeting including state/zip, use virtualsms_generate_proxy_endpoint instead. |
virtualsms_test_proxy |
no_return_description |
Makes one request through a proxy and returns the exit IP, country, city, ISP, and latency, proving the proxy works and which country it exits from. Consumes a small amount of the proxy's GB and is rate-limited to about once per 20 seconds per proxy. |
virtualsms_list_proxy_locations |
params_unexplained no_return_description |
Returns the available location_code values (cities, states, ASNs, or ZIP codes) for a pool type and country. Use this before calling virtualsms_generate_proxy_endpoint or virtualsms_set_proxy_targeting with sub-country targeting. pool_type selects the proxy class (residential, mobile, or datacenter; residential_premium is not supported). Public endpoint, no purchase required. |
virtualsms_generate_proxy_endpoint |
no_return_description |
Builds and returns ready-to-use proxy connection string(s) for an owned proxy — country/state/city/zip/asn targeting, rotating or sticky sessions, HTTP or SOCKS5, in host:port:user:pass, user:pass@host:port, or curl format. Nothing is purchased or changed server-side; this only composes a string from the proxy's existing credentials (same convention as the VirtualSMS dashboard generator). Sub-country targeting (state/city/zip/asn) bills the proxy's own GB at 2x on non-premium pools, free on residential_premium. |
virtualsms_list_services |
no_return_description |
Returns all available SMS verification services (Telegram, WhatsApp, Google, etc.) so you can discover valid service codes before buying a number. Optionally filter by name with the search parameter. |
virtualsms_list_countries |
no_return_description |
Returns all available countries for SMS verification so you can discover valid country codes before buying a number. Optionally pass a service to filter countries available for that service. |
virtualsms_get_price |
no_return_description |
Returns the price and availability for a specific service + country combination. Always check price before buying to confirm availability. |
virtualsms_get_balance |
no_return_description |
Returns your VirtualSMS account balance in USD, or in the currency passed to the currency parameter. Requires VIRTUALSMS_API_KEY to be set. |
virtualsms_list_orders |
no_return_description |
Returns your active orders with status, phone numbers, and related details. Essential for crash recovery: find pending orders, then use get_sms to retrieve codes. Optionally filter by status (pending, sms_received, cancelled, completed). |
virtualsms_start_manual_registration_session |
params_unexplained |
Beta, invite-only. Starts a country-matched cloud browser you drive yourself and returns a viewer_url (an authenticated live-viewer link to watch and drive the session), plus optional order phone number and timeline. Agent-driven navigation is handled by the separate opt-in session tools. prep_preset chooses a preparation template for the browser session (generic or telegram). Pair with create_order for OTP + browser in one agent flow. |
virtualsms_get_stats |
no_return_description |
Return your account usage stats aggregated from order history over the given lookback window: total orders, success rate, total spend, top services and countries, and a status breakdown. since_days sets the window in days (default: 30). |
virtualsms_get_profile |
no_return_description |
Return your full account profile as a single record containing email, Telegram link status, current balance, lifetime spend, total orders, active API keys, and account creation date. |
virtualsms_get_transactions |
no_return_description |
Return the account's transaction history as a paginated list, optionally filtered by type ("deposit", "purchase", "refund", "admin_credit") and by a created_at date range (from/to). Use limit (1-200, default 50) and offset (default 0) for pagination. |
virtualsms_rentals_pricing |
no_return_description |
Return the full list of active rental pricing tiers (Full Access tier: local SIM inventory, durations and prices). This is a raw catalog dump and may list rows that are not purchasable today, so confirm against rentals_available (authoritative per country) before creating a rental. Use rentals_price for platform-tier (per-country, per-service) pricing instead. |
virtualsms_rentals_available |
no_return_description |
Return a list of countries with rental stock, including available counts and pricing, optionally filtered by country, service (full_access tier only), or full_access sub-type. tier=full_access (default) shows local-SIM inventory; tier=platform shows countries available via the global supplier network with per-country service counts and popular services. Use this before creating a rental. |
virtualsms_rentals_services |
no_return_description |
Return the services available for platform-tier rental in the given country, each with its physical stock count and retail price. Platform-tier rentals are locked to ONE chosen service per number, so use this to pick a valid service code before creating one. country_code is required (ISO-2); duration_hours defaults to 24. |
virtualsms_rentals_price |
params_unexplained no_return_description |
Return the catalog-driven retail price for the given (service, country_code, duration_hours) platform-tier rental combo. duration_hours is the rental length in hours and determines the quoted price. All three parameters are required. |
virtualsms_create_rental |
no_return_description |
Rent a phone number for an extended period (as opposed to a one-off number via create_order) and return the created rental with its rental ID and assigned phone number. Two tiers: "full_access" = local SIM inventory, works across ANY service on that number. "platform" = sourced via our global supplier network, locked to ONE chosen service, durations 1/3/7 days only. Both tiers carry the same refund terms: a full refund within 20 minutes of purchase and before the first SMS arrives. Check rentals_available and rentals_price/rentals_pricing first to confirm country/service/duration and cost. |
virtualsms_get_rental |
no_return_description |
Return the full details of a specific rental by ID, including tier, phone number, country, service lock, status, expiry, and any received SMS. Use list_rentals first if you do not have the rental_id. |
virtualsms_extend_rental |
no_return_description |
Extend an active rental by an additional duration. Charges your balance at the current catalog price for that duration and returns the updated rental once the extension is applied. |
virtualsms_cancel_rental |
no_return_description |
Cancel a rental for a full refund. Only eligible within 20 minutes of purchase AND before any SMS has been received; works for either tier. Past that window a rental runs to its natural expiry. Returns confirmation of the cancellation (and of the refund applied when eligible). |
virtualsms_check_number |
no_return_description |
Return the carrier and line type (mobile/landline/VoIP) plus spam-risk indication for an arbitrary E.164 phone number. Public lookup that requires no API key. |
Selection evidence
Confusable tool pairs.
16 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
virtualsms_get_proxy_usage |
virtualsms_get_proxy_usage_history |
high | A task like "how much data has my proxy used" or "show me my proxy usage" fits both: the first returns cached current GB/requests for one proxy, the second a per-day usage series. Without an explicit 'over the last 7/30 days' or 'history' qualifier, the agent may pick the wrong one. |
virtualsms_cancel_order |
virtualsms_cancel_all_orders |
medium | A task like "cancel my orders" (plural, e.g. after a batch run) could map to cancel_all_orders even though the user means cancelling specific ones; conversely "cancel my order" is unambiguous only if singular. The shared cancel/order phrasing makes the singleton-vs-bulk intent genuinely selectable either way. |
virtualsms_list_proxy_catalog |
virtualsms_list_proxy_locations |
medium | Both answer 'where/what proxy locations are available': the catalog lists pool types, countries and price-per-GB, while locations lists cities/states/ASNs/ZIPs. A task like "show me the available proxy countries/locations" could select either since the catalog's country dimension and the locations tool's location dimension overlap. |
virtualsms_buy_proxy |
virtualsms_rotate_proxy |
medium | A task like "I need a fresh/new proxy IP" is ambiguous: rotate_proxy issues a new IP for an existing proxy, while buy_proxy purchases new traffic/proxy. 'Get me a new proxy' could resolve to either depending on whether the user means more GB or a rotated exit IP. |
virtualsms_cancel_order |
virtualsms_cancel_rental |
medium | Users commonly say 'cancel my order' for what is actually a rental purchase. Both tools take an id and issue a refund, so without distinguishing order vs rental the agent may pick cancel_order on a rental_id context or vice versa. |
virtualsms_create_order |
virtualsms_create_rental |
medium | A task like "buy/get/rent a phone number for service X" is ambiguous without a duration: create_order is a one-off SMS verification number while create_rental covers extended periods, so terminology alone (buy vs rent vs order) may select the wrong tool. |
virtualsms_get_balance |
virtualsms_get_profile |
medium | Both expose account balance: get_balance returns just the USD balance, while get_profile returns balance plus lifetime spend, orders, and account details. A task like "check my account/balance" could pick either, since profile also reports the current balance. |
virtualsms_get_stats |
virtualsms_get_transactions |
medium | A task like "show me my account history/activity" is ambiguous: get_stats returns aggregated usage (orders, spend, success rate) from order history, while get_transactions returns the financial record (deposits, purchases, refunds). Both read as 'history of my account'. |
virtualsms_list_orders |
virtualsms_list_rentals |
medium | Rentals are conceptually orders to an end user, so "list my orders/purchases/numbers" could map to either tool; each returns a different id type (order_id vs rental_id) and different lifecycle metadata, so picking wrong yields the wrong downstream object. |
virtualsms_list_services |
virtualsms_list_countries |
medium | Both are SMS verification discovery endpoints with an optional filter. A task like "what verification options are available" or "which services/countries can I use" doesn't clearly resolve to services vs countries, especially since list_countries accepts a service filter, making the two appear interchangeable. |
virtualsms_rentals_pricing |
virtualsms_rentals_available |
medium | Both return rental pricing: pricing is a raw catalog dump of tiers/durations/prices, while available returns per-country stock counts and pricing and is described as authoritative. A task like "show rental prices/availability" fits either, and descriptions explicitly warn to cross-check one against the other. |
virtualsms_rentals_available |
virtualsms_rentals_price |
medium | A task like "how much does it cost to rent a number in country X" is ambiguous: rentals_available reports per-country pricing and counts, while rentals_price computes the specific catalog price for a service/country/duration combo. Both answer a 'what's the price' question. |
virtualsms_rentals_pricing |
virtualsms_rentals_price |
medium | Near-identical naming: 'rentals pricing' vs 'rentals price'. A task like "get rental pricing" or "what do platform rentals cost" — depending on whether the user wants the tier catalog dump or a specific service/country/duration price — can select either. |
virtualsms_rentals_services |
virtualsms_rentals_price |
medium | Both concern platform-tier rental pricing for a country: rentals_services lists services with stock counts and retail price, while rentals_price returns the price for one service/country/duration pair. A task like "what platform rentals are available/priced in GR" could resolve to either. |
virtualsms_rentals_available |
virtualsms_rentals_services |
medium | A task like "list available rental services for country X" maps to both: rentals_available (platform tier) lists per-country service counts and popular services, while rentals_services lists the concrete services with stock and price for that country. Overlapping purpose and output. |
virtualsms_get_order |
virtualsms_get_rental |
low | A user may say "get the full details of my order/purchase" referring to what is actually a rental. Each tool requires its own id type (order_id vs rental_id), so picking wrong fails, though the descriptions are distinct enough that a careful agent usually disambiguates. |
Compare the field