MCP server for PostalDataPI — postal code lookups for AI agents. Look up, validate, and search postal codes across 240+ countries and territories with rich metadata (timezone, admin regions, elevation, coordinates).
Five tools with clear verb-noun naming (lookup_, validate_, search_, get_). All have descriptions (194 - 280 chars, within baseline 34 - 392 range). Input schemas present with type definitions and parameter descriptions. However, output schemas are undocumented (tools return formatted strings, not structured objects), and error handling lacks recovery guidance. No tool annotations (readOnlyHint, etc.). Bulk validation tool has good batch semantics but output structure is opaque.
Get full metadata for a postal code including coordinates. Returns latitude, longitude, county/municipality, and all available country-specific fields. Use this when someone needs geographic coordinates, timezone, or detailed location data for a postal code.
Look up a postal code and get city, state, and region information. Works for ZIP codes (US), postcodes (UK), PLZ (Germany), and postal codes in 240+ countries and territories. Use this when someone asks about a postal code, wants to know what city a ZIP code belongs to, or needs address information.
Find all postal codes for a given city. Use this when someone has a city name and needs the postal codes that serve it. For US cities, provide the state name or 2-letter abbreviation.
Validate up to 1,000 postal codes in a single request. Use this when someone gives you a list of postal codes (especially mixed countries) and asks which are valid, or when cleaning up an address list. Far more efficient than calling validate_postal_code in a loop.
Check whether a postal code exists in a given country. Use this when someone wants to verify if a postal code is valid before processing an order, form, or address.
Output schemas undocumented. All tools return formatted strings (e.g., 'City: Beverly Hills\nState/Region: CA') instead of structured JSON objects. LLMs cannot reliably extract fields for downstream tool calls or data extraction tasks.
Error handling lacks recovery guidance. _format_error() returns 'Error: {msg}' with no actionable next steps. When API key is missing or balance exhausted, the LLM receives no hint on how to proceed (set env var, check account, retry later).
No tool annotations. Tools lack readOnlyHint, destructiveHint, or idempotentHint metadata. All five tools are read-only and idempotent, but this is not declared in the schema, forcing LLMs to infer safety properties.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | <=2025-11-25 | v2 |
validate_bulk_postal_codes output structure opaque. Description promises 'per-record validation results with normalized canonical forms and reason codes' but actual return is a single formatted string. LLMs cannot parse per-item success/failure.
No pagination or result limits documented. search_by_city could return hundreds of postal codes for large cities (e.g., 'Los Angeles, CA') with no limit or cursor guidance. Unbounded results risk context window exhaustion.