nyrezone-mcp
Read-only MCP server for looking up public NYC lot zoning and MapPLUTO facts from NYRezone.
Look up a tax lot by 10-digit BBL or house-number address; get recorded zoning districts, overlays/special districts, FAR fields, lot and building area, year built, land use, units, and floors. Owner and assessment data are omitted.
Retrieve NYRezone-published rules for a zoning district code such as R6A, C4-2, or M1-2/R6A, including FAR, height/bonus rules, citywide lot counts, and average built FAR.
List the 51 zoning districts NYRezone documents, optionally filtered by family such as R6 or C4.
Use it for informational research only: it does not calculate legal capacity, unused development rights, or zoning compliance, and results include source/disclaimer data.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@nyrezone-mcpWhat's the zoning and unused FAR for 123 Atlantic Ave, Brooklyn?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
nyrezone-mcp
Read-only MCP server that gives AI assistants recorded NYC lot fields from public NYRezone pages and APIs: zoning districts, MapPLUTO FAR fields, lot and gross building area, and district summaries as published by NYRezone.
The legacy stdio package is separate from NYRezone's hosted ChatGPT facts app. Version 0.2.0 removes the previous floor-area calculations. Recorded parcel data and scraped district summaries do not determine parcel-specific legal capacity, unused development rights or zoning compliance, or certify that every district rule is current.
It exposes only data that is already public and unauthenticated. No owner names, no assessed values, no paid report data, no account access.
Install
Requires Node 20+.
npx -y nyrezone-mcpClaude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"nyrezone": { "command": "npx", "args": ["-y", "nyrezone-mcp"] }
}
}Claude Code
claude mcp add nyrezone -- npx -y nyrezone-mcpRelated MCP server: Dilix MCP
Tools
All tools are read-only (readOnlyHint: true).
Tool | Input | Returns |
|
| Recorded zoning district(s), overlays, special districts and FAR fields, lot/gross building area, year built and land use. Deprecated capacity calculation fields are retained as null. Ambiguous or unknown address matches return an error. |
|
| FAR, height rules and bonuses as NYRezone publishes them, citywide lot counts, average built FAR. Unknown code returns the list of valid codes. |
| optional | The 51 districts NYRezone documents, each with its district-family description. |
Every successful result includes a source line and disclaimer. The MapPLUTO release
label for lot lookups is reported by NYRezone's methodology page; district lookups
use the label on the district page. Neither is independently validated for the
returned parcel or result. A missing or unavailable release stamp is unknown. District rules are parsed from NYRezone's pages, not fetched directly
from the Zoning Resolution. The visible Public lot map link and legacy full_report_url field both open
the public lot map; neither returns paid report data.
Not included: a borough-level "underbuilt" summary. NYRezone publishes that only as web pages, not as a data endpoint.
Example
lookup_lot with bbl: "3052410015" returns, in part: recorded zoning R7A,
lot area 4,675 sq ft, gross building area 2,606 sq ft, built FAR 0.56 and a
MapPLUTO residential FAR field of 4.0. It does not calculate capacity from those
fields. Its unused_floor_area compatibility object includes:
{
"estimate_sqft": null,
"allowed_floor_area_sqft": null,
"governing_far": null,
"overbuilt": null,
"basis": "not determined from recorded parcel data"
}The object also includes caveats describing the limits below.
Capacity is not determined
The previous release multiplied recorded FAR by lot area and subtracted gross building area. Version 0.2.0 removes that arithmetic for every lot, including split-zoned lots and records with multiple districts but no split-zone flag. The four deprecated fields above remain present and always null; their output schema accepts null. Consumers that assumed a numeric estimate or boolean flag must handle null.
Gross building area is not zoning floor area. Recorded FAR fields alone do not establish applicable FAR or legally permitted floor area. District boundaries, split-zone geometry, applicable uses, special districts, overlays, bonuses, zoning-lot history and current rules require separate verification. The tool returns the recorded district and FAR facts without deciding capacity, unused development rights or compliance.
Data sources and what leaves your machine
nyrezone.com (
/api/pluto,/zoning,/zoning/<code>,/methodology): lot data and district pages. The lot endpoint supplies MapPLUTO fields; HTML district summaries are NYRezone's presentation, not direct Zoning Resolution verification. Release labels and check stamps are reported by the site, not independently validated for each returned parcel.NYC Planning Labs Geosearch (
geosearch.planninglabs.nyc): used only to turn a street address into a BBL, because NYRezone has no address endpoint. This is the one third-party host; the address you ask about is sent to it. BBL lookups and district lookups never contact it.
The owner name and owner type that NYRezone's lot API returns are dropped in this server and never appear in a tool result.
Limits and politeness
Descriptive
User-Agent(nyrezone-mcp/<version> (+repo URL)).Requests are serialized, at least 1 second apart, capped at 20 upstream requests per minute, with a 10 second timeout and a 2 MB response cap.
Responses are cached in memory for 1 hour (not persisted).
Input is validated before any request: addresses 5-150 characters starting with a house number; BBLs must be 10 digits starting 1-5. Everything sent upstream is URL-encoded.
Disclaimer
Informational only. Not legal, architectural, or zoning-compliance advice. Confirm with the NYC Department of City Planning or a licensed professional before relying on it. Not affiliated with the City of New York.
Development
npm install
npm test # builds, then runs node:test against recorded fixtures (no live network)Fixtures in fixtures/ are recorded public responses; the lot fixtures keep the raw owner fields on purpose so the tests prove they are dropped. Environment variables NYREZONE_MCP_BASE_URL, NYREZONE_MCP_GEOSEARCH_URL and NYREZONE_MCP_MIN_INTERVAL_MS exist for the end-to-end test only.
License
MIT. See LICENSE.
Available Tools
3 toolsget_zoning_districtGet an NYC zoning districtARead-onlyIdempotent
Get the HTML district summary NYRezone publishes for one NYC zoning district code (e.g. R6A, C4-2, M1-2/R6A): max FAR, base and maximum height, bonuses, citywide lot counts and average built FAR. Values are scraped NYRezone summaries, not independently verified against the Zoning Resolution or applied to a parcel. An unknown code returns the list of valid codes.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Zoning district code such as R6A, R7-2, C4-2 or M1-2/R6A (case-insensitive). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | |
| code | Yes | |
| rules | Yes | |
| stats | Yes | |
| source | Yes | |
| summary | Yes | |
| boroughs | Yes | |
| rules_note | Yes | |
| dataVintage | Yes | |
| dataCheckedOn | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive), and the description adds material context they cannot: the data is scraped from NYRezone and not verified against the Zoning Resolution or applied to a parcel. It also discloses the error behavior for an unknown code.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences, front-loaded with the action and resource, then the returned fields, then the provenance caveat and error behavior. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return structure need not be explained; the description covers the remaining gaps an agent would care about: data provenance, verification limits, and what happens with an invalid code.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage and a single parameter, the schema already carries the semantics; the description reinforces them with concrete examples including a composite district (M1-2/R6A), which is a modest value-add over the schema's own example list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get the HTML district summary ... for one NYC zoning district code') and enumerates exactly what the response contains (max FAR, heights, bonuses, lot counts, average built FAR). This clearly distinguishes it from list_zoning_districts (enumeration) and lookup_lot (parcel-level).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The singular 'one ... district code' framing plus the unknown-code fallback ('returns the list of valid codes') gives a clear usage context and a self-recovery path. It does not explicitly name list_zoning_districts or lookup_lot as alternatives, so routing is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_zoning_districtsList NYC zoning districtsARead-onlyIdempotent
List the NYC zoning district codes NYRezone documents, each with a one-line summary (its district family description). Optionally filter by family, e.g. R6 or C4.
| Name | Required | Description | Default |
|---|---|---|---|
| family | No | Optional family filter such as R6, C4, M1. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| source | Yes | |
| districts | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety and idempotency profile is fully covered. The description adds only the shape of each result item (a one-line family summary), which is modest context and partly overlapped by the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the resource defined first and the optional filter second – well front-loaded. The example values in the second sentence slightly duplicate the schema's examples, a minor redundancy rather than bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, all-optional listing tool with an output schema and full annotation coverage, the essentials are present. It stops short of routing between the sibling tools or indicating what family values exist, which would fully close the gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% – the 'family' parameter is already documented in the schema with examples (R6, C4, M1). The description restates the same filter and the same example values ('R6 or C4') without adding format or matching semantics above what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('NYC zoning district codes NYRezone documents'), and clarifies what each entry contains ('one-line summary / district family description'). It implicitly separates itself from the singular get_zoning_district sibling via plural enumeration, but never names or contrasts with siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Optionally filter by family' tells the agent how to narrow the list, but there is no guidance on when to prefer this over get_zoning_district or lookup_lot. Usage is implied (enumerate districts / browse families) rather than stated with alternatives or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_lotLook up an NYC tax lotARead-onlyIdempotent
Look up one NYC tax lot by street address OR 10-digit BBL (borough-block-lot). Returns recorded zoning district(s), MapPLUTO FAR fields, lot and gross building area, year built and land use via NYRezone. Does not determine development capacity, unused development rights, applicable FAR or zoning compliance; deprecated calculation fields are null. Provide exactly one of address or bbl. Addresses must start with a house number and should include the borough; an ambiguous or unknown address returns an error instead of a guess. Owner and assessment data are never returned.
| Name | Required | Description | Default |
|---|---|---|---|
| bbl | No | 10-digit BBL, e.g. 3052410015 (1 Manhattan, 2 Bronx, 3 Brooklyn, 4 Queens, 5 Staten Island). | |
| address | No | Street address starting with a house number, e.g. "1187 Ocean Ave, Brooklyn". |
Output Schema
| Name | Required | Description |
|---|---|---|
| lot | Yes | |
| source | Yes | |
| resolved_from | Yes | |
| district_pages | Yes | |
| full_report_url | Yes | Legacy field name: public lot map URL; no paid report data |
| matched_address | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only/idempotent annotations, it discloses null semantics for deprecated calculation fields, error-on-ambiguity behavior, and a hard data exclusion ('Owner and assessment data are never returned'). These are behavioral facts not present in the annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then return contents, then exclusions, then input rules, then error behavior. Every sentence carries a distinct constraint; there is no padding or repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't document return shape, and it still covers inputs, error cases, nullability, and excluded data. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds a constraint the schema does not encode: exactly one of the two optional parameters must be supplied. It also reinforces the address format (leading house number, include borough).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('look up one NYC tax lot') and enumerates exactly what is returned (zoning districts, FAR fields, lot/building area, year built, land use). The two accepted keys (address or BBL) make it immediately distinguishable from the zoning-district siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly bounds usage: 'Provide exactly one of address or bbl', address must start with a house number and include borough, and ambiguous addresses error rather than guess. It also lists what it does not do (development capacity, unused rights, compliance). It stops short of naming when to prefer the sibling zoning-district tools, which is the only routing gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.2.0- Changed
lookup_lot9 fields changed- added
Output schema / properties / full_report_url / descriptionAdded value: +"Legacy field name: public lot map URL; no paid report data" - added
Output schema / properties / lot / properties / unused_floor_area / properties / allowed_floor_area_sqft / descriptionAdded value: +"Deprecated; legally permitted floor area is not determined." - changed
Output schema / properties / lot / properties / unused_floor_area / properties / allowed_floor_area_sqft / typePrevious value: -[ - "number", - "null" -]New value: +"null" - added
Output schema / properties / lot / properties / unused_floor_area / properties / estimate_sqft / descriptionAdded value: +"Deprecated; capacity is not determined from recorded parcel data." - changed
Output schema / properties / lot / properties / unused_floor_area / properties / estimate_sqft / typePrevious value: -[ - "number", - "null" -]New value: +"null" - added
Output schema / properties / lot / properties / unused_floor_area / properties / governing_far / descriptionAdded value: +"Deprecated; applicable FAR is not determined." - changed
Output schema / properties / lot / properties / unused_floor_area / properties / governing_far / typePrevious value: -[ - "number", - "null" -]New value: +"null" - added
Output schema / properties / lot / properties / unused_floor_area / properties / overbuilt / descriptionAdded value: +"Deprecated; zoning compliance is not determined from gross building area." - changed
Output schema / properties / lot / properties / unused_floor_area / properties / overbuilt / typePrevious value: -"boolean"New value: +"null"
3 tool updates
v0.1.0- First observed
get_zoning_district - First observed
list_zoning_districts - First observed
lookup_lot
TDQS
Scored across 3 tools
Each tool targets a distinct resource+action: enumerate district codes, fetch one district's detail, or resolve a single tax lot by address/BBL. The list_zoning_districts vs get_zoning_district pair is the classic list/detail split, and the descriptions explicitly contrast the one-line summary with the full HTML summary so misselection is unlikely.
All names are snake_case verb_noun (list_zoning_districts, lookup_lot, get_zoning_district), which is readable and predictable. The only minor deviation is mixing 'lookup' with 'get' for the two single-record fetches, though the different verbs usefully signal lookup-by-identifier vs fetch-by-code.
Three tools is lean but fits a narrow, read-only zoning reference service where each tool covers a clearly different lookup. It is slightly under what one might expect (e.g. no borough/neighborhood browse), but nothing feels redundant or padded.
The surface covers the core lifecycle for a reference server: list district codes, inspect a district's parameters, and resolve a parcel's recorded zoning. Gaps are minor-to-moderate — no spatial/coordinate lookup, no listing lots within a district, and no bulk queries — but agents can work around these by chaining the existing tools.
Maintenance
Related MCP Connectors
Zoning, ADU eligibility, flood zone, setbacks, and buildability intelligence for U.S. parcels.
Human-reviewed zoning answers with ordinance citations for covered US municipalities.
Public records for any NYC property by address or BBL: permits, violations, sales, owners.
Zoning, homes per lot, short-term rentals, tax and flood for any property in Austin and Nashville.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides AI access to Korea's land use planning, urban regulations, and permit information through natural language queries. It integrates tools for land analysis, regulation verification, and public notice scraping to prevent hallucinations in property-related AI applications.818MIT
- AlicenseAqualityDmaintenanceOpen-source MCP server providing real estate regulatory intelligence (zoning, permits, entitlements, deal scoring) for US properties, enabling AI agents to access 10 callable tools.128 npmMIT
- AlicenseAqualityDmaintenanceProvides Claude with access to NYC public property data including property details, sales history, comparable sales, tax benefits, and rent stabilization analysis using natural language.7MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI agents and developers to look up zoning, land-use, and development records for Gwinnett County, Georgia through five public read-only tools: resolving an address to its actual governing jurisdiction, searching and retrieving county zoning cases, fetching ordinance code sections, and listing jurisdictions. It exposes the same operations over a REST API so questions about setbacks, permits, and case histories can be answered from indexed source records rather than guesses.-