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 two different ways (HPD's registration filings, and the property record itself: the assessment roll, recorded deeds and mortgages, and Speculation Watch List), map everything else registered under that owner or agent's name, check HPD litigation, Department of Buildings records, 311 heat complaints, and marshal-executed evictions — or pull the whole picture in one building_profile call.
It wraps seventeen 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 ( |
|
| One-call profile across nine datasets: registration + contacts, violation counts by class, complaint counts by status, litigation counts by status, executed-eviction count, AEP status ( |
|
| Ownership from the property record rather than HPD's filings: the DOF assessment-roll owner (PLUTO |
|
| Department of Buildings records — a different agency from HPD: DOB violations ( |
|
| 311 service requests ( |
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 |
DOB Violations |
|
|
DOB Complaints |
| NO borough column at all; the |
311 Service Requests |
| ~40M rows; a bare |
Bedbug Filings |
| Borough uppercase text. Infested / eradicated / re-infested unit counts per filing period. |
AEP (Alternative Enforcement) |
|
|
Vacate Orders |
|
|
HWO Emergency-Repair Charges |
| Handyman Work Orders billed to landlords. Borough uppercase text. |
PLUTO Tax Lots |
|
|
ACRIS Legals / Master / Parties |
| The recorded-instrument chain: borough/block/lot -> document ids -> doc type/date/amount -> named parties. Text-typed columns, quoted comparisons. Staten Island is NOT in ACRIS (Richmond County Clerk). |
Speculation Watch List |
| Qualifying flip-risk purchases; matched by block/lot with the row's own |
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 |
|
| true_owner (PLUTO) |
|
| true_owner (ACRIS) |
| same names | building_311 |
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) first — and on a zero, the per-building tools automatically retry spelling variants:
120 15and12015are re-tried as120-15(Queens numbers get the digit-split form), and the response'snotenames every spelling tried, so a hyphenation zero never silently reads as a clean building. Multi-address buildings can still register under a range (1516-1520).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.
Available Tools
6 toolsbuilding_complaintsA
HPD complaints and problems for one building (dataset ygpa-z7cr; one row per reported problem within a complaint). Give the house number, street, and borough. Returns an open/closed count summary plus the most recent matching problems (category, status, dates). Street is matched as an uppercase substring; house number exactly. Keyless.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max detail rows to return (1-500, default 100). The status summary counts all matches. | |
| since | No | Only problems received on/after this ISO date (YYYY-MM-DD). | |
| street | Yes | Street name (matched case-insensitively as a substring). | |
| borough | Yes | NYC borough: Manhattan, Bronx, Brooklyn, Queens, or Staten Island (also accepts MN/BX/BK/QN/SI or 1-5). | |
| open_only | No | Only complaints still open (default false). | |
| house_number | Yes | Building house number, e.g. "1520". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses key behavioral details like substring matching and exact match for house number, and states 'Keyless', but no annotations exist to supplement. Could mention data freshness or pagination.
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 efficient sentences, front-loaded with purpose and output, no fluff.
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?
Covers purpose and output structure, but lacks guidance on sibling tools, error cases, or detailed output field descriptions. Adequate for a simple lookup.
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 description adds limited value. It reiterates required parameters and matching details, but doesn't enrich semantics beyond schema.
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?
The description clearly identifies the tool as retrieving HPD complaints for a building, specifies the dataset, and distinguishes it from siblings like building_violations by focusing on complaints.
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 instructs to provide house number, street, and borough, and describes the output. Lacks explicit when-not-to-use or comparisons with siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
building_violationsA
HPD Housing Maintenance Code violations for one building (dataset wvxf-dwi5). Give the house number, street, and borough. Returns a server-side per-class count summary (class A non-hazardous, B hazardous, C immediately hazardous, I informational) plus the most recent matching violations. Street is matched as an uppercase substring; house number is matched exactly. Keyless; an optional NYC_APP_TOKEN only raises the rate limit.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max detail rows to return (1-500, default 100). The class summary counts all matches. | |
| since | No | Only violations inspected on/after this ISO date (YYYY-MM-DD). | |
| street | Yes | Street name, e.g. "Sedgwick Avenue" (matched case-insensitively as a substring). | |
| borough | Yes | NYC borough: Manhattan, Bronx, Brooklyn, Queens, or Staten Island (also accepts MN/BX/BK/QN/SI or 1-5). | |
| open_only | No | Only violations still open (default false). | |
| house_number | Yes | Building house number, e.g. "1520". | |
| violation_class | No | Filter to one class: "A", "B", "C", or "I". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses: returns a server-side per-class count summary plus most recent violations, street matched as uppercase substring, house number matched exactly, keyless, optional token raises rate limit. This is excellent behavioral detail.
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?
The description is relatively long but every sentence adds value. It front-loads the purpose and dataset ID, then explains parameters and behavior. Could be slightly more concise, but no extraneous information.
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 no output schema, the description compensates by explaining the two-part return (class count summary + recent violations). It also covers matching behavior, required parameters, and optional token. For a tool with 7 parameters, this is complete and leaves no major gaps.
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%, providing a baseline of 3. However, the description adds significant semantic value beyond schema: explains matching logic for street and house_number, clarifies the class summary, and notes that the optional token only affects rate limits. This greatly aids correct invocation.
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?
The description clearly states it returns HPD Housing Maintenance Code violations for one building, with a specific dataset reference. It distinguishes from siblings by focusing on violations and mentioning the class count summary and recent violations. The verb 'get' is implied, and the resource is explicitly 'violations for one building'.
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 description tells users to provide house number, street, and borough, and mentions an optional token. It does not explicitly state when to use this tool versus siblings like building_complaints or who_owns, but the purpose is clear enough that an agent can infer it is for violations only.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eviction_lookupA
Marshal-executed evictions (dataset 6z8x-wfk4). IMPORTANT: this dataset lists evictions a city marshal actually CARRIED OUT, not filings, warrants, or pending housing-court cases. Look up by court index number OR by address and/or borough. At least one is required. Returns court index number, address, executed date, marshal, and residential/commercial flag. Address is matched as a case-insensitive substring of the combined eviction address. Keyless.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max rows to return (1-500, default 50). | |
| since | No | Only evictions executed on/after this ISO date (YYYY-MM-DD). | |
| address | No | Address substring to match, e.g. "123 Example Avenue" (matched within the combined eviction address). | |
| borough | No | NYC borough: Manhattan, Bronx, Brooklyn, Queens, or Staten Island (also accepts MN/BX/BK/QN/SI or 1-5). | |
| court_index_number | No | Housing-court index number to match exactly, e.g. "123456/24". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It lacks explicit statements about read-only nature, rate limits, or auth requirements. While the function is implied non-destructive, these traits are not disclosed.
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?
The description is succinct, front-loads the key purpose and distinction, then explains parameters and output. Every sentence adds value with no redundancy.
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?
Covers the main purpose, required parameter combinations, matching behavior, and output fields. Missing pagination details and the meaning of 'Keyless' is unclear, but overall sufficient for a lookup tool with no output schema.
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% but the description adds valuable constraints: at least one of court_index_number or address/borough is required, and address matching is case-insensitive substring. It also lists the return fields, which is not in the schema.
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?
The description clearly states the tool looks up marshal-executed evictions from a specific dataset, distinguishing it from filings or pending cases. It specifies the lookup methods and return fields, making it distinct from sibling tools which cover other property records.
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 description explicitly warns against using this for filings, warrants, or pending cases, and states that at least one of court index number or address/borough is required. It provides clear context for when to use, though it doesn't compare directly with siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
landlord_litigationA
HPD Housing Litigations (dataset 59kj-x8nc): HPD-initiated cases against landlords plus tenant actions. Look up by building (house_number + street + borough) OR by respondent (landlord/owner) name. At least one is required. Returns case type, open date, status, judgement, any harassment finding, penalty, and respondent, with a by-status summary. Respondent and street are matched as case-insensitive substrings. Keyless.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max cases to return (1-500, default 100). | |
| street | No | Street name (building lookup; matched as a substring). | |
| borough | No | NYC borough: Manhattan, Bronx, Brooklyn, Queens, or Staten Island (also accepts MN/BX/BK/QN/SI or 1-5). Required for a building lookup. | |
| respondent | No | Respondent name to match, e.g. an LLC or owner (substring, e.g. "realty llc"). | |
| case_status | No | Optional status filter, e.g. "OPEN" or "CLOSED". | |
| house_number | No | Building house number (building lookup; requires street + borough too). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral disclosure. It details return fields (case type, open date, status, etc.), matching behavior (case-insensitive substrings for respondent and street), and notes the tool is 'keyless'. No side effects or rate limits are mentioned, but for a read-only lookup this is sufficient.
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?
The description is concise (about 5 sentences), front-loaded with the dataset ID and purpose, and contains no redundant information. Every sentence serves a purpose.
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?
Given the absence of an output schema, the description adequately explains return values and includes a summary by status. It covers the key usage scenarios and matching behavior, making it complete for this lookup tool.
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% with descriptions for all 6 parameters. The description adds value by explaining required parameter combinations (building vs respondent), substring matching details, and borough shorthand (MN/BX/BK/QN/SI).
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?
The description clearly states the tool's purpose: looking up HPD housing litigations by building or respondent. It specifies the data source (dataset 59kj-x8nc) and distinguishes from sibling tools like building_violations which handle different types of records.
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 description explains how to use the tool: look up by building (house_number + street + borough) or by respondent name, with at least one required. It does not explicitly state when not to use it or name alternative tools, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
landlord_portfolioA
The reverse of who_owns: every building currently registered with HPD under a given landlord, corporation, officer, or agent name. Searches HPD Registration Contacts (feu5-w2e2) for the name (case-insensitive substring against corporation names and person first/last names), then resolves each matched registration to its building (tesw-yqqr): address, borough, zip, BIN, registration dates, and which contact matched. Start from a name surfaced by who_owns or landlord_litigation. Landlords often hold each building in a separate LLC; officer and agent person names frequently connect buildings the LLC names hide. Reflects current HPD registration filings only. Keyless.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Owner / corporation / officer / agent name to match, e.g. "WFHA 1520 SEDGWICK LP" or "JOHN WARREN" (case-insensitive substring against HPD registration-contact names; pass the fullest name you have, short fragments over-match). | |
| limit | No | Max buildings to return (1-500, default 50). | |
| borough | No | Optional filter: only buildings in this borough. NYC borough: Manhattan, Bronx, Brooklyn, Queens, or Staten Island (also accepts MN/BX/BK/QN/SI or 1-5). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses case-insensitive substring matching, resolution to buildings with details, current registration only, and the 'Keyless' access. It implies a read-only query.
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?
The description is well-structured but slightly verbose. It efficiently covers purpose, process, usage, and limitations in a few sentences. Could be trimmed slightly.
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?
Despite no output schema, the description fully explains the return values (address, borough, zip, BIN, registration dates, matched contact) and data source. Context is thorough for the tool's complexity.
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%, but the description adds meaningful guidance: name is case-insensitive substring, pass fullest name to avoid over-matching, limit default 50, borough accepts multiple formats.
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?
The description clearly states it is the reverse of who_owns, listing buildings under a landlord/corporation/officer/agent name. It specifies the data source (HPD Registration Contacts) and distinguishes from sibling tools like who_owns and landlord_litigation.
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?
It advises starting from names surfaced by who_owns or landlord_litigation, explaining when to use this tool to uncover hidden connections. It does not explicitly state when not to use, but provides clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
who_ownsA
Who is on file with HPD for a building, the 'who do I actually serve' tool. Joins HPD Registrations (tesw-yqqr) to Registration Contacts (feu5-w2e2) by registration id. Give the house number, street, and borough. Returns the registration(s) and every contact (corporate/individual owner, head officer, officer, agent, site manager) with names and business addresses. Reflects HPD registration filings, which can lag reality. Keyless.
| Name | Required | Description | Default |
|---|---|---|---|
| street | Yes | Street name (matched case-insensitively as a substring). | |
| borough | Yes | NYC borough: Manhattan, Bronx, Brooklyn, Queens, or Staten Island (also accepts MN/BX/BK/QN/SI or 1-5). | |
| house_number | Yes | Building house number, e.g. "1520". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses behavioral traits: it joins specific datasets, returns contact names and addresses, reflects HPD filings (which may lag reality), and notes it requires no API key. No contradictions exist.
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?
The description is concise, with three sentences that front-load the purpose and provide essential details without fluff. Every sentence adds value: purpose, data join, input/output, and limitations.
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 simple tool with three parameters and no output schema, the description sufficiently explains inputs, outputs, data source, and limitations. It covers all necessary context for an AI agent to decide when and how to use it.
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?
The input schema fully covers all three required parameters with descriptions (100% coverage). The description adds value by framing them as user instructions ('Give the house number...') and mentions matching behavior indirectly (substring matching for street is detailed in the schema).
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?
The description states exactly what the tool does: it identifies who is on file with HPD, acts as the 'who do I actually serve' tool, and explains the data join process. It clearly distinguishes from sibling tools like building_violations by focusing on ownership contacts.
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 description explicitly lists required inputs (house number, street, borough) and mentions the output (registrations and contacts). It provides a caveat about data lag, but lacks explicit guidance on when to use this tool versus sibling tools like landlord_portfolio.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool targets a distinct aspect of NYC housing data: building violations, building complaints, building ownership, landlord portfolio, landlord litigation, and eviction lookups. There is no overlap in their purposes.
Tool names use lowercase with underscores and follow a domain-prefix pattern for most (building_*, landlord_*). However, 'who_owns' and 'eviction_lookup' break the pattern slightly, though they are still clear.
With 6 tools, the server covers key aspects of NYC housing data without being bloated or sparse. Each tool serves a distinct purpose, and the count is well-scoped for the domain.
The tools cover violations, complaints, ownership, portfolio, litigation, and evictions—core for housing research. Missing potential areas like building permits or tax info, but the set is largely complete for its focus.
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 Connectors
MCP server giving Claude AI access to 22+ NYC public-record databases for real estate due diligence
MCP server for US nursing facility search and ownership lookup (NursingHomeDatabase).
Unofficial MCP server for the public PortlandMaps property/permit/zoning API. Not city-affiliated.
MCP server for nonprofit financials via ProPublica — IRS Form 990 data for 1.8M+ nonprofits.
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.187MIT
- 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.5521MIT
- 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.689MIT
- 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
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