Developers

The same tools behind this site, as an MCP server.

Agents and the website call one code path. Every response carries a plain-language brief, a coverage block saying what is and isn’t included for the area, and a derived list naming any field the system inferred rather than read.

Endpoint

https://permitdigest.app/mcp

Model Context Protocol, Streamable HTTP transport, stateless. POST JSON-RPC. GET returns 405 with a pointer here.

Auth

Authorization: Bearer pd_live_… with an API key from your account. Anonymous calls get coverage and a capped search_permits (5 results, last 7 days). permit_detail and watch_area need a key. Base includes a monthly call allowance; over-allowance calls return allowance_exceeded with the reset date.

Claude Desktop, Cursor, or any MCP client

{
  "mcpServers": {
    "permitdigest": {
      "url": "https://permitdigest.app/mcp",
      "headers": {
        "Authorization": "Bearer pd_live_YOUR_KEY"
      }
    }
  }
}

Example call

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_permits",
    "arguments": {
      "jurisdiction": "chicago",
      "trade": "roofing",
      "days": 7,
      "limit": 10
    }
  }
}

Shape of a response

{
  "brief": "41 roofing permits issued in Chicago in the last 7 days, $1.2M permit-declared over 37 with a reliable value. Largest: 2112 S ARCHER AVE, $158,000. Chicago publishes no site ZIP; use community area.",
  "summary": { "count": 41, "total_declared_value": 1204500, "declared_value_note": "...", "top": [ ... ], "data_quality_note": "..." },
  "data": [ { "public_id": "chicago/B200517005", "address_std": "3740 N SAYRE AVE", "trade": "roofing", "trade_confidence": 0.9, "trade_method": "rule", "declared_value": 23762, "declared_value_flag": "ok", ... } ],
  "coverage": { "jurisdictions": [ { "slug": "chicago", "status": "ok", "refresh_cadence": "daily", "weekly_volume": 620, ... } ], "not_included": [ "site ZIP (Chicago publishes none)" ] },
  "derived": [ "address_std", "contractor_id" ],
  "data_quality_note": "4 of 41 permits have no reliable declared value and are excluded from the total"
}

Tools

search_permits

Permits by area (jurisdiction, ZIP, community area), trade, minimum permit-declared value, date range and confidence floor, with a short brief.

Input
{ jurisdiction?, zip?, community_area?, trade?: "roofing"|"solar"|"hvac", min_value?, from?, to?, days?: 1|7|30, min_confidence?, limit?: ≤50 }
Returns
Matching permits plus a short summary: count, total permit-declared value, top items, data-quality note.

permit_detail

Scope, permit-declared value, status, dates, contractor and the raw source fields for one permit.

Input
{ id: "chicago/B200517005" }
Returns
Scope, permit-declared value with flag and raw, status, every lifecycle date with its source column, contractor, change history and the raw source fields.

coverage

Which jurisdictions are covered, how fresh each is, and approximate weekly permit volume.

Input
{ jurisdiction? }
Returns
Which jurisdictions are covered, their health, refresh cadence, approximate weekly volume and which fields each city publishes.

watch_area

A standing watch on the same criteria that delivers each day's new permits.

Input
search_permits criteria + { name, delivery: "email"|"none" }
Returns
A standing watch that delivers each day’s new permits as a digest. Requires an API key.

JSON mirror

The same handlers answer plain HTTP for scripts and spreadsheets, with the same auth header and the same response shape.

Rules we keep

Discovery: /llms.txt · /sitemap.xml · coverage