IP risk and geolocation lookups from ip99.com: proxy / VPN / dial-up pool verdicts with the age of their evidence. Free, no key required.
Three tools with clear, concise descriptions (lookup, me, pulse). All have input schemas with type definitions. However, parameter descriptions are minimal (e.g., 'IPv4 or IPv6 address' lacks format/validation guidance). Output schemas are documented in TypeScript interfaces but not exposed in tool definitions. Error handling is present in the SDK but not surfaced to MCP clients. Tool names are action-oriented (lookup, me, pulse) but 'me' is vague, 'get_quota' or 'check_quota' would be clearer. No tool annotations (readOnlyHint, idempotentHint) despite all being read-only operations.
Risk verdict, network and location for one IPv4/IPv6 address.
Your current tier and remaining quota (needs a key).
Professional tier: same verdict plus per-evidence detail (`evidence[]` with captured_at); `at` is an RFC 3339 instant.
Tool 'me' has ambiguous name. Does not clearly convey 'get current quota/tier'. Should be 'get_quota', 'check_quota', or 'get_account_info'.
Parameter descriptions lack format/validation guidance. 'IPv4 or IPv6 address' does not specify accepted formats, length limits, or error handling for invalid IPs.
Output schemas (IPRisk, Me) documented in TypeScript but not exposed in MCP tool definitions. LLM cannot see expected response structure.
No tool annotations despite all tools being read-only and idempotent. Missing readOnlyHint and idempotentHint metadata.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | 2026-07-28+ | v2 |
Error handling (IP99Error class with code, status, retryAfter) exists in SDK but not documented in tool descriptions. LLM cannot anticipate rate limits or recovery strategies.