MCP.so
ログイン

PermitIntel MCP Server認証済み注目

@PermitIntel.ai

基本情報

トランスポート

streamable-http

認証方式

APIキー

カテゴリ

データと分析

作者

PermitIntel.ai

投稿者

PermitIntel

PermitIntel MCP Server について

Building permit data and Florida contractor license checks over MCP. 81.8M permit records from the cities and counties that issue them, across 51 states. Four tools: verify_license, search_permits, lookup_contractor, roof_lookup.

#permits#building-permits#permit-data#contractor#license-verification#construction#real-estate#government#api#florida

接続情報

https://permitintel.ai/api/mcp

セットアップ

claude mcp add permitintel --transport http https://permitintel.ai/api/mcp

PermitIntel MCP Server のツール

31

Wraps GET /api/v1/verify/license. Verify one contractor license against the Florida DBPR record: status, license type, effective and expiration dates, whether it is currently active, days to expiry, and the qualifier. Call it with `license` for an exact number, or with `name` (and optionally `county`) to resolve a business name to its license. Costs 1 record on a hit and 0 records on a miss. License status reflects PermitIntel's most recent DBPR sync, refreshed daily, and is for B2B verification of a licensed business, not consumer underwriting. Florida only.

Wraps GET /api/v1/permits. Search ingested building-permit records. SIX modes, exactly one of which is required: `address` for permits at a street address; `contractor` for a contractor's permit history by name or license number; `zip` for one 5-digit ZIP, newest first; `city` together with `state` for one city, newest first; `jurisdiction` for one jurisdiction code, newest first; or `updated_since` for the change feed — every permit whose RECORD changed at or after a timestamp, oldest change first, paged with the opaque `cursor` from meta.next_cursor. Use the feed, not from/to, to keep a copy in sync: a permit ingested today carrying a 2019 issue date is invisible to a from/to poll. To answer "what permits are in this place", start from `zip` or from `city`+`state` — do NOT invent an address. `zip` is an exact match on the permit's own ZIP and `city` answers from the jurisdiction codes we maintain for that place (the response states both in `query.zip_match` / `query.city_match` and names the codes in `query.jurisdictions`; city_match=jurisdiction_codes_place_alias means the name was folded to reach the stored code, e.g. "Saint Petersburg" -> ST_PETERSBURG or "Miami" -> MIAMI_CITY; an exact match always wins over a fold), so neither is a complete census of a postal area. Both order newest first and therefore exclude permits with no issue date (`query.undated_excluded`). `county` is a filter, not a mode: a prefix range cannot be walked in date order. An empty geo page always carries `zero_row_reason`; read that field before reporting an absence, because "we hold no code for this city" and "nothing matched inside the window" are different facts and only one of them is about the place. Costs 1 record per permit returned; `limit` defaults to 50 and caps at 200, so one call costs at most 200 records. Results are a FLOOR and a SCOPE, never a complete record of all permits at an address or by a contractor — permit offices publish on their own schedules and some publish almost nothing. Report counts as "at least N on record", never as a total filed.

Wraps GET /api/v1/contractors. Look up Florida contractors with their permit activity rolled up: permit count, declared value, activity in the last 12 months, first and last permit dates, top trades, top jurisdictions, plus canonical contact, a workers-compensation-on-record signal and EPA Lead-Safe certification. Call with `license` for one profile, `name` or `specialty` to search, or `sort`/`min_permits`/`min_permits_12mo` to rank by permit activity. Costs 1 record per contractor returned; `limit` defaults to 25 and caps at 100. Activity is a FLOOR built from the permits PermitIntel has ingested, not a complete record of everything the contractor filed. This endpoint returns positive and neutral public record only — it exposes no disciplinary history and no negative flags.

Wraps GET /api/v1/roof/{address}. Roof state for one property address: roof age in years derived from the most recent roof permit on record, the date of that permit, and roof material with its source and confidence. The address can be the street line or a full one-line mailing address (street, city, state, ZIP, with or without a unit); a ZIP in the address disambiguates exactly as `zip` does. Pass `zip` when the same street address exists in more than one covered city. Costs 1 record when the address matches and 0 records when it does not. Every answer carries a per-jurisdiction coverage_grade (A, B or C). A miss means the address is NOT IN COVERED DATA — it never means no roof work occurred. Where no reroof permit is on record the age may be an estimated floor from the county year-built; roof_age_source says which, and an estimate must never be reported as a confirmed reroof.

Wraps GET /api/v1/rollups. Grouped permit totals for a place instead of a list of permits: set `group` to `county` (with `state`), `zip` (with `county`) or `jurisdiction` (with `state` or `county`), and each row carries permits, permits in the trailing 12 months, declared value for both windows, how many permits resolved to a contractor license, and the most recent issue month. Narrow with `trade` (roofing, hvac, electrical, plumbing, pool, solar, windows_doors, fence, general, or a rollup category such as ev_charger) at county and ZIP grain. `window` is `12mo` or `all` and decides which number ranks the rows. Costs ONE RECORD PER GROUP ROW returned, not one per underlying permit; `limit` defaults to 200 and caps at 1000. County and ZIP rows come from a rollup aggregate of permits carrying an issue month; jurisdiction rows come from the published coverage file, count every permit whatever its dates and carry no declared value, so the two bases do not agree about the same county and every row names its `basis`. Totals are a FLOOR and a SCOPE, never a complete record of all permits in a county or ZIP. Report them as "at least N on record", never as all permits filed.

Wraps GET /api/v1/supply/accounts. Ranks Florida-licensed contractors in ONE territory as supplier sales accounts: permits and declared value in the trailing 12 months, momentum (last 90 days versus the prior 90), an activity grade A to D, a territory rank, and contacts. Pick the territory with EITHER `county` OR `zip`. `county` accepts the county code the other tools use (FL-MIAMI_DADE) or the county name (Miami-Dade, Miami Dade); a county that cannot be resolved answers unknown_county with did_you_mean, so never read it as an empty market. `zip` is a 5-digit ZIP and ranks the contractors whose permits issued in the last 12 months sit in that ZIP (issue-dated permits only; each account carries zip_activity). Narrow with `trade`, `grade`, `momentum`, `min_permits_12mo` and order with `sort`; in ZIP mode these read the account's Florida-wide 12-month figures, the ZIP decides membership. Costs ONE RECORD PER ACCOUNT returned; `limit` defaults to 50 and caps at 500. Demand figures are permit-activity proxies, a FLOOR and not a complete record, and the grade is a sales-prioritization signal, not a credit score. Growth and up.

Wraps GET /api/v1/permits/{id}. One permit by the numeric `id` that search_permits puts on every row, with the matched contractor and its contact included by default. The id is the internal id, NOT the permit number: permit offices number independently, so a permit number is not unique — to find a permit by its number use search_permits with `jurisdiction`. Costs 1 record on a hit and 0 records on a 404. A 404 means the permit is not in servable covered data, not that it was never filed.

Wraps GET /api/v1/contractors/{license}. One contractor profile keyed by DBPR license number, the same profile lookup_contractor returns for `license`, plus `recent_permits` (the 10 newest permits on record, a sample and never the history) and `links.permits` for the full history. Costs 1 record for the profile plus 1 record per recent permit returned (at most 11 records); 0 on a 404. Activity is a FLOOR built from ingested permits, not a complete record, and the profile carries positive and neutral public record only — no disciplinary history.

Wraps GET /api/v1/jurisdictions. The jurisdiction codes you can pass to search_permits `jurisdiction` and `county`, so a code is never guessed. Narrow with `state` (two letters), `county` (a code prefix such as FL-MIAMI_DADE) or `q` (a substring of the code); page with `limit` (default 50, max 1000) and `offset`. Each row carries the code, state, county, total permits on file, the trailing-12-month count, license-resolved permits and last ingest. Costs 0 records on any plan; with a key you get the code list, without one only the counts. Counts are a FLOOR on what is held, not a completeness claim.

Wraps GET /api/v1/usage. What the calling key has spent this month: tier, records used, the monthly records limit and what remains, when it resets, and the requests-per-minute limit. Costs 0 records and keeps answering after the records ceiling is hit, so an agent holding a 402 records_limit_exceeded can see why and when it clears.

Wraps GET /api/v1/coverage. The machine-readable /coverage page: the headline totals and the per-state counts for everyone, and with a key the per-jurisdiction place list. Costs 0 records on any plan. Every count is a FLOOR of ingested records, never a completeness claim — a jurisdiction missing from the list is not covered, which says nothing about whether permits were filed there.

Wraps GET /api/v1/verify/insurance. Coverage status and lapse intel for one licensed business: workers' compensation status (`wc_status`), carrier, policy effective and expiration dates and cancellation, from the state coverage records PermitIntel ingests (FL DWC, TX DWC, CA CSLB workers' comp; WA L&I and OR CCB general liability and surety bond, returned in `coverage[]` under their own coverage_type and never folded into wc_status). Pass `state` only to disambiguate a license number held in more than one state. Costs 1 record per call, found or not. Starter and up; a trial key gets the 403 back. A not_found means no matched coverage record is held — it is not evidence the business is uninsured. B2B verification of a licensed business only, never individual underwriting.

Wraps GET /api/v1/verify/certifications. Compliance badges for one licensed business in a single call: EPA RRP lead-safe renovation certification and Florida OSD minority or disadvantaged business designation, matched to the DBPR license. Costs 1 record per call. Starter and up; a trial key gets the 403 back. A status of not_found means no matched record is held; it is not evidence the business is uncertified and must not be used to decline or disqualify anyone.

Wraps GET /api/v1/properties/{address}/risk-insurance. A property-condition and insurance-risk summary for one address derived from the permit history held: roof age, last roof permit date, major-system permits in the last five years, open permits, last declared value, last activity date and the building systems worked on. Narrow with `city` or `zip`. Costs 1 record, or 0 when the address has no permits on file. Starter and up. These are property public-record EVENTS, a FLOOR and a SCOPE for B2B property risk — never a consumer report, a distress score or an individual underwriting input; an address with no permits on file is not in covered data, not a property with no work done.

Wraps GET /api/v1/roof/{address}/evidence. The citation layer behind roof_lookup: the roof permit records on file for one address, each with permit number, jurisdiction, issue date, status, contractor and declared value — proof an underwriter or inspector can file. Same address rules as roof_lookup; pass `zip` to disambiguate. Costs 1 record per permit returned, 0 when none. All tiers including trial. A list with no permits means the address is NOT IN COVERED DATA for roof permits, never that no roof work occurred.

Wraps GET /api/v1/roof/coverage. The coverage table behind roof coverage grades: without a key the totals and the A/B/C histogram, with a key the per-jurisdiction rows (property counts, roof-age fill rate, material fill rate, freshness and grade). Filter with `state`, `county` or `grade`. Costs 0 records on any plan. Fill rates describe the data held, not the housing stock.

Wraps GET /api/v1/roof/structure. Roof geometry — hip, gable, complex, flat or unknown — the signal Florida wind-mitigation credits price off. Look up by `address` (+ `zip`) or by `parcel` + `jurisdiction`. Only high- and medium-confidence hip/gable is returned as a label; anything weaker is `unknown`, never a guess. `insurance=true` on a paid key queues an aerial classification on a cache miss and answers `pending` with retry_after_seconds; trial keys are read-only. Costs 1 record only when a structure label is returned; a status that is not ready costs 0. Starter and up.

Wraps POST /api/v1/roof/batch. Roof age and material for a book of addresses in one call: `items` is 1 to 1,000 objects of { address, zip? } (street line or full one-line address). Costs 1 record per address scored, misses included, ON TOP of the roof product's monthly batch volume / prepaid roof credits (a 402 batch_volume_exhausted says how many remain). Growth and up; trial and starter keys get the 403 upgrade_required back. A miss means the address is NOT IN COVERED DATA, never that no roof work occurred, and an estimated age is not a confirmed reroof.

Wraps GET /api/v1/monitors. The calling key's always-on license monitors: id, license, the events watched, webhook URL and whether it is active. Costs 1 record per monitor returned. Growth and up; a trial key gets the 403 back.

Wraps POST /api/v1/monitors. WRITE — creates (or reactivates) an always-on monitor on one license for the calling key. `events` is a subset of license_lapse, insurance_lapse, new_permit, cert_expiry (default the first three). With an https `webhook_url` deliveries are HMAC-signed and the signing secret is returned ONCE in this response; without one, poll monitor_events. Costs 0 records: the response echoes your own input. Growth and up, capped per tier (a 429 monitor_cap_reached says the cap).

Wraps DELETE /api/v1/monitors/{id}. WRITE (destructive) — removes one monitor owned by the calling key, by the id list_monitors or create_monitor returned. Costs 0 records. Growth and up.

Wraps GET /api/v1/monitors/{id}/events. The events one of the calling key's monitors has detected (license lapse, insurance lapse, new permit, certification expiry), for callers without a webhook. `since` is an ISO timestamp; `limit` defaults to 100 and caps at 500. Costs 1 record per event returned. Growth and up. No events means nothing was DETECTED in covered data, not that nothing happened.

Wraps GET /api/v1/supply/book. The saved accounts in the calling key's supplier book of business, each enriched with live supply intelligence. Filter with `status` (prospect, contacted, active, won, lost), `rep_id` or `watch=true`. Costs 1 record per account returned. Growth and up. Activity figures are permit-activity FLOORS, not a complete record.

Wraps POST /api/v1/supply/book. WRITE — saves one contractor license to the calling key's book of business, with optional pipeline `status`, owning `rep_id`, `notes`, and `watch=true` to monitor it (new permits, license and insurance lapses; optional https `webhook_url`). Costs 0 records: the response echoes your own input. Growth and up.

Wraps PATCH /api/v1/supply/book. WRITE — updates one saved account by `license`: any of `status`, `rep_id`, `notes`, `watch`, `webhook_url`; fields you omit are left unchanged. Costs 0 records. Growth and up.

Wraps DELETE /api/v1/supply/book. WRITE (destructive) — removes one account from the calling key's book by `license`, and tears down its watch. Costs 0 records. Growth and up.

Wraps GET /api/v1/supply/reps. The calling key's sales reps, oldest first, each with the `id` you pass as `rep_id` to a book entry or territory. Costs 1 record per rep returned. Growth and up.

Wraps POST /api/v1/supply/reps. WRITE — adds one sales rep (`name`, optional `email`) to the calling key's organization. Costs 0 records: the response echoes your own input. Growth and up.

Wraps GET /api/v1/supply/territories. The calling key's saved territories — named, reusable supply_accounts filters (county, trade, momentum, grade, minimum permits, owning rep). A territory stores the filter, not a snapshot: pass its fields to supply_accounts for the live ranked list. Costs 1 record per territory returned. Growth and up.

Wraps POST /api/v1/supply/territories. WRITE — saves one named territory: a reusable supply_accounts filter of `county`, `trade`, `momentum`, `grade` and `min_permits_12mo`, optionally owned by `rep_id`. Costs 0 records: the response echoes your own input. Growth and up.

Wraps DELETE /api/v1/supply/territories. WRITE (destructive) — deletes one saved territory by `id`. Costs 0 records. Growth and up.

概要

What is PermitIntel

A remote MCP server for building permit data. It answers the questions an agent cannot get anywhere else without scraping a few hundred municipal portals: what permits exist at this address, what has this contractor pulled and how recently, is this Florida license active or did it lapse, how old is the roof on this property.

Scope, measured October 3, 2026: 81,884,842 permit records, 51 states, 1,236 published jurisdictions, 5,273,921 permits issued in the trailing twelve months. Florida holds 28,647,136 of those records across 260 jurisdictions, with DBPR licenses matched to their permit records.

Tools

  • verify_license - Florida DBPR license status, expiration, and the business behind it
  • search_permits - by address, by contractor, or as a change feed since a timestamp
  • lookup_contractor - a contractor's permit history by name or license number
  • roof_lookup - roof age and material for a property

Connect

Endpoint: https://permitintel.ai/api/mcp (streamable HTTP, protocol 2025-06-18). Manifest: https://permitintel.ai/.well-known/mcp.json. A GET returns 405 by design; POST.

{
  "mcpServers": {
    "permitintel": {
      "type": "http",
      "url": "https://permitintel.ai/api/mcp",
      "headers": { "Authorization": "Bearer pmit_your_key" }
    }
  }
}

tools/list needs no key. Calls need a key. 14-day trial at https://permitintel.ai/trial, no card. When you reach your plan's included volume, upgrade or wait for your renewal date.

Two honest limits

Counts are floors. We hold what the permit offices publish, and every response carries a disclosure field, so phrase answers as "at least N on record". License verification is Florida only; the permit data is national, the DBPR join is not.

Docs: https://permitintel.ai/docs#mcp. Examples and client configs: https://github.com/gsan12345/permitintel-mcp

よくある質問

1

PermitIntel のリモート MCP サーバーとは何ですか?

PermitIntel のリモート MCP サーバーは、https://permitintel.ai/api/mcp にホストされた Model Context Protocol エンドポイントです。AI アシスタントはローカルに何もインストール・実行することなく接続できます。

2

PermitIntel の MCP サーバーにはどう接続しますか?

エンドポイント https://permitintel.ai/api/mcp を Claude Code、Cursor、VS Code など任意の MCP 対応クライアントに追加してください。このページのセットアップ手順で各クライアントを一度に設定できます。

3

PermitIntel の MCP サーバーは認証が必要ですか?

はい。PermitIntel は API キーが必要です——取得方法は公式ドキュメントを確認し、クライアントの設定に追加してください。

4

PermitIntel の MCP サーバーはどのトランスポートを使用しますか?

PermitIntel は streamable-http エンドポイントを公開しており、これはリモート MCP サーバーで広く使われ、主要な MCP クライアントがサポートするトランスポートです。

コメント