mcp-nychousing
This MCP server provides tools to query NYC housing data from the NYC Open Data (Socrata) API, focusing on HPD violations, complaints, property ownership, landlord portfolios, litigation, and evictions — designed for tenant organizers, legal-aid intake, and Right-to-Counsel organizations.
building_violations: Retrieve HPD violations for a building, with a class summary (A: non-hazardous, B: hazardous, C: immediately hazardous, I: informational) and detailed records; filter by open status, class, and date.
building_complaints: Fetch HPD complaints and problems for a building, including open/closed counts and problem details; filter by open status and date.
who_owns: Identify the registered owner, head officer, officer, agent, and site manager for a building, with names and business addresses (useful for serving legal papers).
landlord_portfolio: Reverse-search by person or corporation name to find every building registered under that name (including officers/agents), exposing holdings hidden behind separate LLCs.
landlord_litigation: Search HPD litigations by building address or respondent name, returning case type, status, judgment, harassment findings, and penalties, with a by-status summary.
eviction_lookup: Find marshal-executed evictions by court index number or address/borough, returning execution date, marshal name, and residential/commercial flag. (No result does not mean no case was ever filed.)
Click on "Install 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., "@mcp-nychousingcheck violations for 123 Main St in 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.
mcp-nychousing
MCP server for NYC housing data over NYC Open Data (the Socrata / SODA API). Built for tenant organizers, housing-court legal-aid intake, and Right-to-Counsel orgs: pull a building's HPD violations and complaints, find out who actually owns it (to serve papers), map everything else registered under that owner or agent's name, check HPD litigation against the landlord, and look up marshal-executed evictions.
It wraps six city datasets and normalizes their raw columns (novdescription, violationstatus, registrationid, court_index_number, and so on) into documented tool outputs.
Tools
Tool | Arguments | Returns |
|
| HPD violations for a building ( |
|
| HPD complaints and problems for a building ( |
|
| HPD registration ( |
|
| Reverse of |
|
| HPD Housing Litigations ( |
|
| Marshal-executed evictions ( |
borough accepts Manhattan, Bronx, Brooklyn, Queens, or Staten Island (also MN/BX/BK/QN/SI or the codes 1 to 5). violation_class is one of A (non-hazardous), B (hazardous), C (immediately hazardous), I (informational). since is an ISO date (YYYY-MM-DD).
Related MCP server: civic-library-mcp
Data source and grounding
Base URL:
https://data.cityofnewyork.us/resource/<dataset-id>.jsonAuth: none. SODA is keyless. An optional Socrata app token (see below) only raises the per-IP rate limit.
Response: list and aggregate queries return a bare JSON array. Errors return
{ "error": true, "message": "..." }.Query language: SoQL via
$select,$where,$group,$order,$limit, withupper(...)andlikefor string matching and||for the first/last-name concatenation inlandlord_portfolio. All user text is escaped (a single quote becomes two) before it reaches a query.
Dataset ids and column notes:
Dataset | Id | Notes |
HPD Violations |
| Address columns |
HPD Complaints and Problems |
| The current combined dataset (the older |
HPD Registrations |
| Current registrations. Join key |
HPD Registration Contacts |
| Owner / agent / officer names. Joined by |
HPD Housing Litigations |
| Address columns |
Evictions |
| Marshal-executed only. Combined |
Field map (raw column to normalized output)
Raw column | Normalized field | Tool |
|
| building_violations |
|
| building_violations |
|
| building_complaints |
|
| who_owns |
|
| landlord_portfolio |
|
| landlord_litigation |
|
| eviction_lookup |
Install
Nothing to clone. Point your MCP client at it and npm fetches it on first run:
{
"mcpServers": {
"nychousing": {
"command": "npx",
"args": ["-y", "@haksanlulz/mcp-nychousing"],
"env": { "NYC_APP_TOKEN": "your-nyc-app-token" }
}
}
}git clone https://github.com/haksanlulz/mcp-nychousing
cd mcp-nychousing
npm install
npm run build # emits dist/; the published bin is dist/index.jsnpm start runs the TypeScript directly via tsx without building.
App token (optional)
Every tool works with no token. If you make heavy or bursty use, a free Socrata app token raises the rate limit. Create one from the developer settings on your NYC Open Data account. Docs: https://dev.socrata.com/docs/app-tokens.html
Expose it as NYC_APP_TOKEN and it is sent as the X-App-Token header:
export NYC_APP_TOKEN=your-token-here # macOS / Linux
setx NYC_APP_TOKEN your-token-here # Windows (new shells)The token is never logged.
MCP client config
Add an "env": { "NYC_APP_TOKEN": "your-token-here" } block only if you want the higher rate limit.
Example
Call building_violations with { "house_number": "1520", "street": "Sedgwick Avenue", "borough": "Bronx", "open_only": true, "limit": 1 }:
{
"query": {
"house_number": "1520",
"street": "Sedgwick Avenue",
"borough": "BRONX",
"open_only": true,
"violation_class": null,
"since": null
},
"summary": { "total_matching": 128, "by_class": { "A": 21, "B": 74, "C": 33 } },
"returned": 1,
"results": [
{
"violation_id": "19051745",
"apartment": "2D",
"story": "2",
"class": "C",
"description": "HMC ADM CODE: ... ABATE THE INFESTATION CONSISTING OF MICE ...",
"current_status": "NOTICE OF ISSUANCE SENT TO TENANT",
"is_open": true,
"rent_impairing": false,
"inspection_date": "2026-07-04T00:00:00.000",
"nov_issued_date": "2026-07-08T00:00:00.000",
"nov_type": "Original"
}
],
"record_scope": "HPD-issued violations: inspection findings on a date, with their own open/close workflow codes. Not court outcomes, and not a current condition report."
}The counts are illustrative and move as the city updates the data. The summary counts every match server-side; results is the most recent limit of them.
Every response carries a record_scope line stating what that specific dataset
does and does not establish. It is per-tool, because each one has a different
wrong reading available: landlord_litigation returns HPD workflow codes, not
rulings on the merits, and eviction_lookup covers marshal-executed
evictions only — so no matching row does not mean no case was ever filed.
Then take a name from who_owns output and reverse it. Call landlord_portfolio with { "name": "WFHA 1520 SEDGWICK LP" }:
{
"query": { "name": "WFHA 1520 SEDGWICK LP", "borough": null },
"found": true,
"summary": { "contact_matches": 1, "distinct_registrations": 1, "buildings_found": 1 },
"note": "Contacts reflect HPD registration filings. The same landlord may file each building under a separate LLC; officer and agent person names often connect what the LLC names hide.",
"returned": 1,
"buildings": [
{
"registration_id": "221729",
"building_id": "108415",
"building_address": "1520 SEDGWICK AVENUE",
"borough": "BRONX",
"zip": "10453",
"bin": "2009171",
"last_registration_date": "2025-09-05T00:00:00.000",
"registration_end_date": "2026-09-01T00:00:00.000",
"matched_contacts": [
{ "type": "CorporateOwner", "organization": "WFHA 1520 SEDGWICK LP", "person_name": null }
]
}
],
"record_scope": "Buildings matched by registered-party name. Name matching is approximate and distinct entities can share a name; this is not proof of common ownership."
}A single-building LLC like this one is itself the common NYC pattern; searching an officer or agent person name from the same who_owns output is how you connect the buildings the per-building LLC names hide.
Address matching
There is no geocoding here. Address matching is literal against how HPD stores addresses:
Street names are stored uppercase. The server uppercases and trims your
streetinput and matches it as a substring (upper(streetname) like '%YOUR STREET%'). SoSedgwick,sedgwick avenue, andSEDGWICK AVEall matchSEDGWICK AVENUE, but a very short input can over-match (5 Stwould also hit125 St). Pass the fuller street name when you can.House number is matched exactly (uppercased), so
1520is not1516-1520. Multi-address buildings can register under a range.Borough disambiguates same-numbered streets across boroughs, so it is required for the building tools. Litigations store a numeric borough code; evictions mix borough and county spellings (Brooklyn and Kings, Manhattan and New York, Staten Island and Richmond), and the borough filter expands to all of them.
landlord_portfoliomatches names the same way: uppercase substring againstcorporationname,firstname,lastname, and thefirstname || ' ' || lastnameconcatenation (so a pastedperson_namefromwho_ownsworks). LIKE wildcards (%,_) in your input are escaped. Pass the fullest name you have; a short fragment likeSMITHorLLCover-matches, and the response says how many contact records matched before any cap.who_owns,landlord_portfolio,landlord_litigation, and the datasets themselves reflect HPD filings, which can lag reality. Confirm anything you intend to act on (for example a name to serve) before relying on it.
Develop
npm test # vitest, fetch mocked (no network)
npm run smoke # one live call per tool against SODA (keyless, no setup)
npm run typecheckAI assistance
This project was built with AI assistance (Claude). Correctness was established by the mocked vitest suite, by running every tool live against NYC Open Data (npm run smoke; the Queens hyphenated-house-number, NY/NYC borough, and litigation-summary fixes all came from live behavior, not mocks), and by typecheck. The author reviews the code and is accountable for it.
License
MIT. See LICENSE. Data from NYC Open Data (public City of New York data) served via the Socrata SODA API. Unofficial, not affiliated with the City of New York, HPD, or Socrata.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for NYC real estate due diligence. Lets Claude query 22+ NYC public-record databases — DOB/HPD/ECB violations, ACRIS deeds, DOF sales, 311 complaints, FDNY incidents, NYPD complaints, marshal evictions, PLUTO, rent stabilization — in plain English.186MIT
- AlicenseAqualityBmaintenanceAn MCP server that gives AI agents clean, token-efficient access to US civic & property data — geocoding, census tracts, Opportunity Zones, ACS demographics, and FEMA flood zones — sourced entirely from free federal open data.5671MIT
- AlicenseAqualityBmaintenanceMCP server for HUD housing data, enabling Fair Market Rent lookups, Section 8 income limits, and ZIP-to-county crosswalk mapping for affordable housing assessments.6MIT
- AlicenseAqualityBmaintenanceMCP server over the U.S. Department of Labor Wage and Hour Division (WHD) enforcement dataset: employer wage-theft history, back wages owed, civil penalties, and affected-employee counts. Built for worker-justice nonprofits, legal-aid intake, and union researchers.4MIT
Related MCP Connectors
MCP server giving Claude AI access to 22+ NYC public-record databases for real estate due diligence
MCP server for nonprofit financials via ProPublica — IRS Form 990 data for 1.8M+ nonprofits.
MCP server for Mireye Earth — federal-source-cited geospatial data for any MCP-aware agent.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/haksanlulz/mcp-nychousing'
If you have feedback or need assistance with the MCP directory API, please join our Discord server