# io.github.andrew-sondgeroth/zipexplore-mcp

> US ZIP code intelligence: demographics, weather, tax, crime, housing, voting, and more.

- name: io.github.andrew-sondgeroth/zipexplore-mcp
- version: 1.0.0
- connection class: R1 (autonomous)
- trust: 69/100 flags: no-repository
- quality: 79/100 (good)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/io.github.andrew-sondgeroth%2Fzipexplore-mcp
- tools: https://api.protogrid.dev/v1/servers/io.github.andrew-sondgeroth%2Fzipexplore-mcp/tools

**An agent can connect on its own if it already holds `zipexplore_api_key`, `zipexplore_api_key`.** Remote endpoint behind a static API key or header. The registry never sees the value; the agent fills the placeholder.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "zipexplore-mcp": {
      "type": "http",
      "url": "https://mcp.zipexplore.com/mcp",
      "headers": {
        "x-api-key": "${zipexplore_api_key}",
        "Authorization": "${zipexplore_api_key}"
      }
    }
  }
}
```

Placeholders to fill: `${zipexplore_api_key}`, `${zipexplore_api_key}`.

## Trust

- hygiene: 80
- liveness: 99
- freshness: 65
- provenance: 35
- drivers: +reachable +uptime-97% ~updated-144d-ago -no-repository
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 79/100 (good)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-03-26; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 71 (weight 30)

- pass `tools.descriptions`: every tool has a description
- pass `tools.description_length`: descriptions are concise
- pass `tools.schemas`: every tool has an object input schema
- fail `tools.annotations`: no tool declares readOnlyHint or destructiveHint, so clients cannot tell safe calls from risky ones
- fail `tools.directory_hints`: no tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: get_census_profile (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); get_cost_profile (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); reverse_geocode (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); …
- pass `tools.token_cost`: about 2,524 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 100 (weight 15)

- pass `stability.changes`: no tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 22, about 2,524 tokens to load them all
- tool set hash: 5dc7fb97ebf6b721474e611104220930
- badge: [![protogrid quality](https://protogrid.dev/badge/io.github.andrew-sondgeroth/zipexplore-mcp.svg)](https://protogrid.dev/servers/io.github.andrew-sondgeroth/zipexplore-mcp)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Remotes

- https://mcp.zipexplore.com/mcp (streamable-http, auth api_key ${zipexplore_api_key}, reachable true, uptime30d 0.96581197)

## Packages

_none_

## Tools (22)

- `compare_zips`: Side-by-side full profiles for 2–5 ZIP codes. Use when the user has
        finalists and needs to choose between them. Returns the same profile
        shape as get_zip_profile for each ZIP.
        
- `get_air_quality_profile`: Detailed air quality data for one ZIP code. Use when get_zip_profile's
        air quality section isn't sufficient depth. Includes EPA AQS pollutant
        levels (PM2.5, PM10, ozone, NO2, SO2, CO) and AQI summary.
        
- `get_article`: Returns the full prose of a specific ZipExplore research article. Use this for editing, fact-checking, detailed analysis, or when get_research summaries aren't enough. Valid slugs: disappearing-towns, hazard-premium, snap-economy, wealthy-retirees. Each article includes all body sections and methodology notes exactly as published.
- `get_business_profile`: Detailed business and employment data for one ZIP code. Use when
        get_zip_profile's business section isn't sufficient depth. Includes
        top industries, sector breakdowns, total establishments, employment,
        and annual payroll from Census BDS/CBP data.
        
- `get_census_profile`: Detailed Census / demographics data for one ZIP code. Use when
        get_zip_profile's demographics section isn't sufficient depth.
        Includes population, housing, income distribution, education attainment,
        economic indicators, internet access, and public assistance rates.
        
- `get_cost_profile`: Detailed cost of living data for one ZIP code. Use when get_zip_profile's
        cost section isn't sufficient depth. Includes fair market rents, housing
        cost burden, regional price indices, and affordability metrics.
        
- `get_crime_profile`: Detailed crime data for one ZIP code. Use when get_zip_profile's crime
        section isn't sufficient depth. Includes violent crime rate, property
        crime rate, and data quality flags (coverage level, Bayesian shrinkage).
        
- `get_disaster_risk_profile`: Detailed natural disaster risk data for one ZIP code. Use when
        get_zip_profile's disaster risk section isn't sufficient depth. Includes
        FEMA NRI overall risk score, individual hazard scores (hurricane, tornado,
        earthquake, wildfire, flood, etc.), and expected annual loss estimates.
        
- `get_education_profile`: Detailed school data for one ZIP code. Use when get_zip_profile's
        education section isn't sufficient depth. Includes school counts,
        student-teacher ratios, graduation rates, per-pupil spending, Title I
        percentage, and budget breakdown (instruction vs. admin vs. capital).
        May reflect data from the nearest ZIP if no schools are in this ZIP.
        
- `get_healthcare_profile`: Detailed healthcare data for one ZIP code. Use when get_zip_profile's
        healthcare section isn't sufficient depth. Includes hospital count and
        ratings, nursing homes, beds per capita, primary care and mental health
        shortage area designations, pharmacy count, and urgent care count.
        
- `get_methodology`: Returns ZipExplore's data interpretation guide: reasoning guardrails (associations vs. causes, small-ZIP noise, averages hiding distributions, editorial score weights, drawing conclusions about people from geographic data), quality flag definitions, known data limitations, coverage gap explanations, and per-domain vintage summary. Call this when you have questions about data quality, what a quality_flag code means, why a ZIP has no data, or how to reason carefully about scores and correlations.
- `get_research`: Returns ZipExplore's published research articles — original data findings on topics including disaster risk vs. housing costs (the Hazard Premium), food insecurity in fully-employed communities (SNAP economy), economically declining towns vs. retirement communities, and income variation among America's oldest ZIP codes. Each entry includes the key finding, specific quantitative results, caveats, and a URL to the full article. Call this when a user asks about these topics or when published findings would add context to a live data lookup.
- `get_search_fields`: Lists every field name, type, and description available for search
        criteria. Call this when you're unsure what field names to pass to
        search_zips, or when the user asks what data ZipExplore has.
        
- `get_tax_profile`: Detailed tax data for one ZIP code. Use when get_zip_profile's tax
        section isn't sufficient depth. Includes state income tax, sales tax,
        property tax effective rates, excise taxes, and IRS income statistics.
        
- `get_transit_profile`: Detailed public transit data for one ZIP code. Use when get_zip_profile's
        transit section isn't sufficient depth. Includes bus stop count, subway
        station count, rail station count, light rail count, ferry terminal count,
        total transit stops, transit commute percentage, and nearest subway/rail
        distances.
        
- `get_voting_profile`: Detailed voting and political data for one ZIP code. Use when
        get_zip_profile's voting section isn't sufficient depth. Includes
        presidential election results, partisan lean, congressional and
        state legislative districts, and state officials.
        
- `get_weather_profile`: Detailed climate data for one ZIP code. Use when get_zip_profile's
        climate section isn't sufficient depth. Includes annual/monthly temperature
        averages, precipitation, humidity, and nearest weather station info.
        
- `get_zip_centroids`: Get the latitude/longitude centroid for one or more ZIP codes (max 200).
        Use when you need map coordinates for a set of ZIPs.
        
- `get_zip_profile`: Full location profile for one ZIP code across all 12 data domains:
        demographics, climate, tax, crime, cost of living, voting, education,
        healthcare, business, air quality, disaster risk, and transit. Use this
        to get detail on a ZIP after search, or when the user asks about a
        specific ZIP. For deeper data on one domain, use the domain-specific tools.
        
- `ping`: Returns server status and tool/resource counts. Use this to verify the ZipExplore MCP connection is live.
- `reverse_geocode`: Convert a latitude/longitude coordinate to a ZIP code. Use when the
        user provides an address or map coordinates rather than a ZIP code.
        
- `search_zips`: Find ZIP codes matching one or more criteria. Returns a ranked list with
        scores. Use this first when the user wants recommendations (e.g. "find a
        low-crime suburb near Denver"). Call get_search_fields first if you're
        unsure what field names to use.

        criteria: list of {"field": str, "level": "low"|"medium"|"high"}
        area_types: "CITY" | "SUBURB" | "SMALL_TOWN" | "RURAL"
        regions: "northeast" | "southeast" | "midwest" | "southwest" | "west"
        
