URBANKIT/STUDIO
    Sign inFREE TOOLS · NO SIGNUP
    URBANKIT/STUDIO · EST. 2026 · ONLINEFREE · BROWSER-ONLY · NO TELEMETRY · OPEN SOURCE
    For developers & AI agents

    Parcel atlas, npm SDK and MCP server

    The same county parcel data behind our tools, in three forms you can call from code: a TypeScript npm package for your own programs, an MCP server for Claude, Cursor, and other AI clients, and a hosted REST API that turns a US address into the owner of record. The SDK is MIT-licensed and needs no account. The MCP server's discovery tools need no key either. The hosted lookup API runs on a free key; theenrich_address action and bulk enrichment are on paid plans (from $19/mo) or pay-as-you-go.

    npm SDK

    @urbankitstudio/atlas v0.5.3. TypeScript, ESM + CJS, zero runtime deps.

    MCP server

    JSON-RPC 2.0, MCP spec 2025-06-18. Four tools via npm, six on the hosted endpoint, no key.

    Underlying data

    155 counties across 50 states, each with verified REST endpoints and searchable fields.

    npm SDK, @urbankitstudio/atlas

    A typed wrapper around the atlas, bundled offline so your code makes no runtime network call to resolve a county. Look up an endpoint by slug or FIPS, read its searchable fields, and build deep-links into the parcel-lookup tool. Works in Node 18+ and every modern bundler.

    npm i @urbankitstudio/atlas

    A real example

    Every function below ships in v0.5.3. findCountyByFips and findCounty return undefined on a miss rather than throwing, so you can branch on the result.

    import { findCountyByFips, listStates, atlas } from "@urbankitstudio/atlas";
    
    // 1. Resolve a 5-digit county FIPS to its parcel endpoint.
    const kane = findCountyByFips("17089"); // Kane County, IL
    if (kane) {
      const endpoint = kane.endpoints[0];
      console.log(endpoint.url);          // the live ArcGIS REST URL
      console.log(endpoint.searchFields); // [{ name: "PIN", searchable: true }, ...]
    }
    
    // 2. Discovery: which states are indexed, and how many counties each.
    const populated = listStates().filter((s) => s.populated);
    console.log(populated.length, "states");
    
    // 3. Coverage totals are on the bundled atlas root.
    console.log(atlas.totals); // { states, counties, endpoints }
    
    // Unknown / malformed input returns undefined. It never throws.
    EXPORTS

    listStates, findState, findCounty, findCountyByFips, listCountiesByState, buildParcelLookupDeepLink.

    SHAPE

    Dual ESM/CJS builds, full .d.ts types, sideEffects: false, zero runtime dependencies.

    MCP server, for AI agents

    The parcel atlas is available as a published npm MCP server you can run in any MCP-capable client with one command:

    npx -y @urbankitstudio/mcp-atlas

    It exposes four tools: list_counties, find_county, get_parcel_endpoint, and build_owner_query. The server is public and read-only. Your client pays its own LLM-token cost; there is no key to manage.

    Claude Desktop config

    Open claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/; Windows: %APPDATA%\Claude\) and merge in this block, then restart Claude Desktop.

    {
      "mcpServers": {
        "urbankit-atlas": {
          "command": "npx",
          "args": ["-y", "@urbankitstudio/mcp-atlas"]
        }
      }
    }

    Clients that connect by URL instead of spawning a subprocess can point at the remote HTTP endpoint: https://urbankitstudio.com/api/mcp. It exposes six public discovery tools plus two key-gated actions: enrich_address returns owner, APN, and mailing fields for one address, and radius_ownersreturns every owner parcel inside a radius. enrich_address runs on paid plans or pay-as-you-go and uses one unit when data is released; radius_owners is paid-plans-only and uses one unit per parcel row returned, with a caller-set cap and a count_only preview.

    The full MCP server page has the per-tool reference, an example conversation, a curl walkthrough, and setup notes for Cursor and other clients.

    Property owner lookup API

    The SDK and MCP server hand you the verified county endpoint to query. If you would rather send a US street address and get the owner back directly, the hosted /api/atlas/lookup endpoint is the property owner lookup API on top of the same 155-county atlas. One authenticated GET resolves the address to its county, the parcel endpoint, and the owner / APN / mailing fields that endpoint exposes, the address-to-owner API behind the parcel-lookup tool, and a practical skip-trace API alternative when the owner of record is all you need.

    curl "https://urbankitstudio.com/api/atlas/lookup\
    ?address=100 N Lake St, Aurora, IL" \
      -H "Authorization: Bearer uk_live_..."
    {
      "ok": true,
      "matched": true,
      "geocode": {
        "matchedAddress": "100 N LAKE ST, AURORA, IL, 60506",
        "countyName": "Kane",
        "stateAbbrev": "IL",
        "countyFips": "17089"
      },
      "atlas_indexed": true,
      "county": {
        "county_name": "Kane",
        "county_fips": "17089",
        "endpoints": [
          {
            "url": "https://.../MapServer/0",
            "searchable_fields": [
              { "name": "PIN",        "label": "Parcel number (APN)" },
              { "name": "OWNER_NAME", "label": "Owner of record" },
              { "name": "SITE_ADDR",  "label": "Site address" }
            ],
            "sample_query": ".../query?where=PIN='...'&outFields=*&f=json",
            "endpoint_status": "ok"
          }
        ]
      }
    }

    Machine-readable contract

    The whole public API is described in /openapi.json (OpenAPI 3.1): all four endpoints, the bearer scheme, the rate-limit headers, and the error shape. Point Postman, an SDK generator or an agent at it rather than reading this page and transcribing it by hand.

    It covers /api/atlas/lookup, /api/atlas/county, /api/atlas/radius and /api/atlas/bulk. A test fails the build if an endpoint ships without being documented there, so the contract cannot quietly fall behind the API it describes.

    Anonymous calls work up to 10 a day so you can try the response shape; a free key raises that to 500 a day, and the paid plans add bulk address-to-owner enrichment for whole lists. Owner data comes from each county's own public ArcGIS layer. When a county does not publish owner names, the response says so rather than guessing.

    SDK or MCP, which one?

    Reach for the npm SDK when

    • You are writing your own program and want county lookups inline, with no network round-trip and full TypeScript types.
    • You need deterministic, versioned data you can pin in package.json.
    • You are building a deep-link into the parcel-lookup tool from your own UI.

    Reach for the MCP server when

    • You want Claude, Cursor, or another AI client to resolve a parcel mid-conversation without copy-pasting.
    • You want address-to-APN and geocoding chained by the model, not wired by hand.
    • You do not want to ship or update a dependency. The endpoint tracks the latest atlas on its own.

    The data underneath

    Both surfaces read the same source: the County Parcel REST API Atlas, a hand-verified index of public ArcGIS endpoints. No hidden database sits behind them. The JSON files are the source of truth, and you can browse the whole set by state.