PermitStack MCP
An official MCP server provided by PermitStack that allows AI agents to query U.S. building permit data, including searches by address, contractor, or category, and retrieve property histories and contractor information without scraping.
Endpoint and access
No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.
https://mcp.permit-stack.com/mcpWhat you can do with it
- Search permits by city, state, ZIP, or category
- Look up permit history for a specific property address
- Find contractors by name or trade classification
- Retrieve coverage data and freshness status
Source and maintenance
Protocol and capabilities
- Server
- permitstack 0.1.0
- MCP protocol
- 2025-06-18
- Tools
- 6 advertised
- Resources
- Not advertised
- Resource templates
- Not advertised
- Prompts
- Not advertised
{
"tools": {}
}Tools
6 advertised
search_permits — Search building permits
Search U.S. building permits by location (city, state, ZIP code, or a lat/lng radius), category, status, property type, filing or issue date range, estimated project value, contractor name, or free text. Returns up to 25 permits per call with address, dates, category, status, estimated value, contractor and description, plus the total number of matches. Response fields: `total` is exact unless `total_capped` is true, in which case it is a lower bound; when `total_unknown` is true the count could not be computed and `total` is null. `account_window_clamped`, `account_window_days` and `account_window_from` are set when the connected account covers a limited date range, and the results then cover only that range. Category HVAC also matches MECHANICAL, and MECHANICAL also matches HVAC. date_after/date_before match whichever date a permit has (issued, else filed), for feeds that publish only one of the two. Results carry no property owner name, owner mailing address or permit applicant name fields.
{
"type": "object",
"properties": {
"q": {
"type": "string",
"description": "Free-text search over description, address, and permit number"
},
"lat": {
"type": "number",
"description": "Latitude for radius search (use with lng)"
},
"lng": {
"type": "number",
"description": "Longitude for radius search (use with lat)"
},
"city": {
"type": "string",
"description": "City name, e.g. 'Austin', 'Boston', 'Miami-Dade County'"
},
"page": {
"type": "integer",
"default": 1,
"minimum": 1,
"description": "Page number, 1-based (default 1)"
},
"start": {
"type": "integer",
"minimum": 1,
"description": "Instead of page: 1-based position of the first result to return, e.g. start=24 continues after result 23 (as named in `_notes`)"
},
"state": {
"type": "string",
"description": "Two-letter US state code, e.g. 'TX', 'MA', 'FL'"
},
"status": {
"type": "string",
"description": "Permit status, e.g. 'ISSUED', 'FINAL', 'EXPIRED', 'FILED'"
},
"category": {
"type": "string",
"description": "Permit category (case-insensitive). Common values: SOLAR, ROOFING, HVAC, NEW_CONSTRUCTION, POOL, ELECTRICAL, PLUMBING, DEMOLITION, MECHANICAL, RENOVATION."
},
"per_page": {
"type": "integer",
"default": 25,
"maximum": 25,
"minimum": 1,
"description": "Results per page (default 25, max 25)"
},
"zip_code": {
"type": "string",
"description": "5-digit ZIP code"
},
"max_value": {
"type": "number",
"description": "Maximum estimated project value in dollars"
},
"min_value": {
"type": "number",
"description": "Minimum estimated project value in dollars"
},
"date_after": {
"type": "string",
"description": "ISO date (YYYY-MM-DD): only permits dated on or after this date, using the issue date, else the filing date"
},
"date_before": {
"type": "string",
"description": "ISO date (YYYY-MM-DD): only permits dated on or before this date, using the issue date, else the filing date"
},
"filed_after": {
"type": "string",
"description": "ISO date (YYYY-MM-DD): only permits filed on or after this date"
},
"filed_before": {
"type": "string",
"description": "ISO date (YYYY-MM-DD): only permits filed on or before this date"
},
"issued_after": {
"type": "string",
"description": "ISO date (YYYY-MM-DD): only permits issued on or after this date"
},
"jurisdiction": {
"type": "string",
"description": "Jurisdiction name or partial name, e.g. 'Wake County', 'Tacoma'"
},
"radius_miles": {
"type": "number",
"description": "Radius in miles for lat/lng search (max 50, default 5)"
},
"issued_before": {
"type": "string",
"description": "ISO date (YYYY-MM-DD): only permits issued on or before this date"
},
"property_type": {
"type": "string",
"description": "Property type, one of: residential, commercial, industrial, mixed_use, institutional, unknown (case-insensitive)"
},
"contractor_name": {
"type": "string",
"description": "Filter by contractor name (partial match supported)"
}
},
"additionalProperties": false
}{
"title": "Search building permits",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}get_permit — Look up a permit by number
Look up a permit by the permit number assigned by the issuing jurisdiction, optionally narrowed by city and state. The number is matched exactly (ignoring case), and the same number can exist in several jurisdictions, so up to 5 matching permits are returned; give the city or state to tell them apart. If nothing matches exactly and a city or state was given, permits in that place whose number contains the text are returned instead, and `match` says "partial". When the connected account covers a limited date range, `account_window_from` is set and only permits from that date onward are searched. Results carry no property owner name, owner mailing address or permit applicant name fields.
{
"type": "object",
"required": [
"permit_number"
],
"properties": {
"city": {
"type": "string",
"description": "City where the permit was issued (optional, narrows the match)"
},
"state": {
"type": "string",
"description": "Two-letter state code (optional, narrows the match)"
},
"permit_number": {
"type": "string",
"description": "The permit number from the issuing jurisdiction"
}
},
"additionalProperties": false
}{
"title": "Look up a permit by number",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}get_property_history — Property permit history
Permit history for one property, looked up by street address (house number and street name, e.g. '123 Main St'). Optional city, state and ZIP narrow the match when the same street address exists in several places. Returns a property profile (permit timeline, category breakdown, contractors) and up to 25 permit records per page, newest first; `has_more` says whether the next page has more. Covers all permit categories. When the connected account covers a limited date range, the profile and records cover only that range, `account_window_from` is set, and `_notes` says so: the result is then not the property's full permit history. Results carry no property owner name, owner mailing address or permit applicant name fields.
{
"type": "object",
"required": [
"address"
],
"properties": {
"zip": {
"type": "string",
"description": "Optional ZIP code (prefix-matched)"
},
"city": {
"type": "string",
"description": "Optional city, to tell identical street addresses apart"
},
"page": {
"type": "integer",
"default": 1,
"minimum": 1,
"description": "Page number, 1-based (default 1)"
},
"start": {
"type": "integer",
"minimum": 1,
"description": "Instead of page: 1-based position of the first result to return, e.g. start=24 continues after result 23 (as named in `_notes`)"
},
"state": {
"type": "string",
"description": "Optional two-letter state code"
},
"address": {
"type": "string",
"description": "Street address with house number, e.g. '123 Main St' (min 3 characters)"
},
"per_page": {
"type": "integer",
"default": 25,
"maximum": 25,
"minimum": 1,
"description": "Results per page (default 25, max 25)"
}
},
"additionalProperties": false
}{
"title": "Property permit history",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}search_contractors — Search contractors
Search contractors by name, city, state or specialty. Returns up to 25 contractors per call with the contractor UUID, name, licence number and licence state, home city and state, total permit count, first and last permit dates, specialties and activity score (0-100), sorted by activity score (highest first). Project values are not included; get_contractor_permits lists a contractor's permits with their estimated values.
{
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City where the contractor has worked"
},
"name": {
"type": "string",
"description": "Contractor name (partial match)"
},
"page": {
"type": "integer",
"default": 1,
"minimum": 1,
"description": "Page number, 1-based (default 1)"
},
"start": {
"type": "integer",
"minimum": 1,
"description": "Instead of page: 1-based position of the first result to return, e.g. start=24 continues after result 23 (as named in `_notes`)"
},
"state": {
"type": "string",
"description": "Two-letter state code"
},
"per_page": {
"type": "integer",
"default": 25,
"maximum": 25,
"minimum": 1,
"description": "Results per page (default 25, max 25)"
},
"specialty": {
"type": "string",
"description": "Specialty/trade to filter by, e.g. 'solar', 'roofing', 'hvac'"
},
"min_permits": {
"type": "integer",
"minimum": 0,
"description": "Only contractors with at least this many permits"
}
},
"additionalProperties": false
}{
"title": "Search contractors",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}get_contractor_permits — Contractor's permits
List the permits pulled by one contractor, identified by the contractor UUID from search_contractors. Returns up to 25 permits per page with the contractor's work history fields (dates, categories, values). Results carry no property owner name, owner mailing address or permit applicant name fields.
{
"type": "object",
"required": [
"contractor_id"
],
"properties": {
"page": {
"type": "integer",
"default": 1,
"minimum": 1,
"description": "Page number, 1-based (default 1)"
},
"start": {
"type": "integer",
"minimum": 1,
"description": "Instead of page: 1-based position of the first result to return, e.g. start=24 continues after result 23 (as named in `_notes`)"
},
"per_page": {
"type": "integer",
"default": 25,
"maximum": 25,
"minimum": 1,
"description": "Results per page (default 25, max 25)"
},
"contractor_id": {
"type": "string",
"description": "Contractor UUID from search_contractors results"
}
},
"additionalProperties": false
}{
"title": "Contractor's permits",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}get_coverage — Data coverage
Describe PermitStack's coverage: total permits, jurisdictions (active, archive, frozen) and states. On a signed-in connection it also lists covered jurisdictions with their permit counts, county and `data_through` (the date of the newest permit held), filterable by state and by name, up to 25 per call, largest first. Without sign-in it returns the platform totals only.
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Optional text matched against jurisdiction names, e.g. 'Austin' or 'County'"
},
"state": {
"type": "string",
"description": "Optional two-letter state code to list only that state's jurisdictions"
}
},
"additionalProperties": false
}{
"title": "Data coverage",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}Prompts
Not advertised
Resources
Not advertised
30-day availability
Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.
- Successful checks
- 1 of 1 (100%)
- Average latency
- 616 ms
- 95th percentile latency
- 616 ms
Maintenance history
Public check and source-refresh events. Editorial and ownership records remain private.
- · probe · passed · 616 ms · metadata changed · 6 tool(s)
Connect from your client
Each snippet registers the same endpoint; pick the client you use.
Claude Code
claude mcp add --transport http permitstack-mcp https://mcp.permit-stack.com/mcpCodex
codex mcp add permitstack-mcp --url https://mcp.permit-stack.com/mcpCursor
{
"mcpServers": {
"permitstack-mcp": {
"url": "https://mcp.permit-stack.com/mcp"
}
}
}Cline
{
"mcpServers": {
"permitstack-mcp": {
"type": "streamableHttp",
"url": "https://mcp.permit-stack.com/mcp",
"disabled": false
}
}
}VS Code
{
"servers": {
"permitstack-mcp": {
"type": "http",
"url": "https://mcp.permit-stack.com/mcp"
}
}
}Gemini CLI
gemini mcp add --transport http permitstack-mcp https://mcp.permit-stack.com/mcpClaude Desktop
{
"mcpServers": {
"permitstack-mcp": {
"url": "https://mcp.permit-stack.com/mcp"
}
}
}Windsurf
{
"mcpServers": {
"permitstack-mcp": {
"serverUrl": "https://mcp.permit-stack.com/mcp"
}
}
}Let your agent find its tools
Find servers like PermitStack MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.
Other data and analytics servers
Do you run PermitStack MCP?
Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.