mcp-fairrent
This server provides access to official HUD data to assess housing affordability and eligibility. It offers:
Fair Market Rent Lookup (
fmr_lookup): Get FMR for an area (county or metro CBSA) by bedroom count (efficiency/studio through 4 bedrooms).Income Limits (
income_limits): Retrieve 30% (extremely low), 50% (very low/Section 8 voucher cutoff), and 80% (low) AMI thresholds for an area and household size (1–8).Affordability Check (
affordability_check): Compute rent gap vs. FMR (dollars and percent) and determine qualification under 30/50/80% AMI bands, with citation-ready numbers.ZIP Crosswalk (
zip_crosswalk): Translate a 5-digit ZIP to county, tract, CBSA, or congressional district, showing residential address share.List Counties (
list_counties): Enumerate counties in a state with 10-digit FIPS entity IDs.List Metro Areas (
list_metro_areas): List HUD CBSA metropolitan areas and codes.
Provides USPS ZIP-to-jurisdiction crosswalk to map ZIP codes to counties, tracts, CBSAs, and congressional districts.
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., "@mcp-fairrentRun affordability check for 2BR at $2600 in NYC for household of 3 income $48k"
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-fairrent
MCP server for HUD housing data. Fair Market Rents by bedroom count (per area or a whole state at once), Section 8 income limits by household size, the LIHTC/MTSP income bands tax-credit buildings use, computed affordability verdicts, and the USPS ZIP-to-jurisdiction crosswalk in both directions (ZIP to county/tract/metro/district, and any of those back to its ZIPs). Built on the MCP TypeScript SDK.
For anyone answering "is this rent affordable here, and who qualifies for help?": tenant organizers, legal-aid intake, housing counselors, relocation planners, and agents that need real HUD numbers.
Tools
Tool | What it does |
| Fair Market Rent for an area, by bedroom count (efficiency through 4BR). |
| The 30% / 50% / 80% AMI income thresholds for an area; pass a household size for the one line that applies. The 50% line is the usual Section 8 voucher cutoff. |
| The computed verdict: how far a rent sits above or below FMR for a bedroom size (dollars and percent), and which income bands (30/50/80% AMI) a household qualifies under — arithmetic done server-side, with the underlying numbers and table year for citation. |
| Map a ZIP to the county, tract, CBSA, CBSA division, congressional district, or county subdivision it sits in, with city/state and the residential-address share so you pick the right one. |
| Counties in a state with their FIPS entity ids, to look up by county name. |
| HUD metro areas (CBSAs) with their codes. |
| The LIHTC (tax-credit building) income bands at 20-80% AMI plus the HERA special bands ( |
| Every county's and metro's FMRs for a whole state in one call ( |
| The reverse crosswalk: every ZIP inside a county, tract, metro, CBSA division, congressional district, or county subdivision, with residential-address shares and city/state. |
Related MCP server: mcp-arcgis-houston
Install
Nothing to clone. Point your MCP client at it and npm fetches it on first run:
{
"mcpServers": {
"fairrent": {
"command": "npx",
"args": ["-y", "@haksanlulz/mcp-fairrent"],
"env": { "HUD_API_TOKEN": "your-hud-token" }
}
}
}git clone https://github.com/haksanlulz/mcp-fairrent
cd mcp-fairrent
npm install
npm run build # emits dist/; the published bin is dist/index.jsnpm start runs the TypeScript directly via tsx without building.
Token
Every tool needs a free HUD USER API token. One-screen signup at huduser.gov → set HUD_API_TOKEN. The tools tell you so if it's missing.
HUD_CONTACT (optional) sets the contact string in the User-Agent sent to HUD; defaults to this repo's URL. Nothing loads a .env file — set both in the shell or the MCP client's env block (.env.example lists them).
The flow
An address is usually a ZIP, but fmr_lookup and income_limits key on a 10-digit county entity id, so bridge the two:
zip_crosswalkwith the ZIP,to: county→ the county's 5-digit FIPS (e.g. ZIP 10451 →36005).list_countiesfor that state → the county's 10-digit entity id (36005→3600599999).fmr_lookupandincome_limitswith that entity id → the bedroom rents and the voucher line.
Worked example: a Bronx landlord wants $2,600 for a 2-bedroom. Is that above Fair Market Rent, and would a family of three earning $48k qualify for a voucher here? That's affordability_check in one call — the entity id with rent: 2600, bedrooms: 2, income: 48000, household_size: 3 — and the answer comes back computed: the dollar and percent gap to the two-bedroom FMR, plus a per-band qualification readout against the 30/50/80% lines, with the table year and the numbers behind each verdict. The model cites; the server does the arithmetic.
Entity ids
fmr_lookup and income_limits take a 10-digit county FIPS (e.g. 3600599999, which is county FIPS 36005 + 99999) or a metro CBSA code. zip_crosswalk and list_counties turn a ZIP into one.
Example
zip_crosswalk with zip: "10451", to: "county":
{
"zip": "10451",
"to": "county",
"note": "res_ratio is the share of the ZIP's residential addresses in each geography; the highest-share county is usually the right entityid.",
"matches": [
{ "geoid": "36005", "city": "BRONX", "state": "NY", "res_ratio": 1, "bus_ratio": 1, "tot_ratio": 1 }
],
"eligibility_scope": "HUD program tables, reproduced as published. Rent figures are Fair Market Rents, not a housing authority's payment standard; income figures are program eligibility lines, not a determination or an award. Confirm with the administering agency before relying on a number for a real household."
}Ratios are rounded to four decimal places. A ZIP with no crosswalk rows (retired, or PO-box-only) answers with an empty matches and a note saying so — it is an answer, not an error.
36005 is Bronx County; list_counties with state: "NY" gives its entity id 3600599999, which fmr_lookup and income_limits take.
Limitations
Numbers are HUD's published FMR and income-limit year tables, not live market rents.
HUD's tables bound the inputs: bedrooms 0-4 (FMR tables stop at four bedrooms), household size 1-8 (income-limit tables stop at eight;
affordability_check's error gives HUD's convention for larger households).affordability_checkcompares a single FMR row. Areas whose FMR data comes back multi-row (small-area/ZIP-level, or multi-year) are refused — pass a county entityid, or usefmr_lookupto see every row.FMR is not the voucher ceiling: housing authorities set payment standards at 90-110% of FMR (24 CFR 982.503). The rent verdict carries this note.
Every response carries an
eligibility_scopenote: these are program lines, not personal determinations, and an answer is exactly as current as its table year.
Develop
npm test # vitest over an in-memory transport, fetch mocked (no network, no token)
npm run smoke # one live call per tool (needs HUD_API_TOKEN; skips without)
npm run typecheck
npm run build # emit dist/ (what actually ships)
npm run verify:pack # pack, install into a clean dir, drive the installed binary over stdioTesting
Two tiers, already split by script. npm test is the offline tier: vitest, in-memory MCP transport, fetch mocked, no token. npm run smoke is the live tier: one real HUD call per tool, needs HUD_API_TOKEN, exits 0 with a skip line without it. CI runs only the offline tier.
Counts, measured 2026-09-11:
find . -name '*.ts' -not -path './node_modules/*' -not -path './dist/*' -not -path './test/*' -not -name smoke.ts | xargs wc -l # app: 767 lines (index.ts + server.ts; smoke.ts is another 65)
find ./test -name '*.test.ts' | xargs wc -l # tests: 951 lines, 2 files
npm test # 48 tests, 48 passedLayers. test/server.test.ts drives every tool end to end through the SDK client: input validation (bounds, required pairs, non-positive numbers) rejected before any HUD request; response shaping against fixtures copied from HUD's documented samples; the transport layer (retry on 429 and 5xx, no retry on 404, response cache keyed on path plus params, failures not cached). test/no-http-stack.test.ts pins that the source imports only the stdio transport, never an HTTP one, and that package.json declares exactly one runtime dependency.
Mutation probe, 2026-09-11: widened the affordability_check bedrooms bound in server.ts from > 4 to > 5. One test went red: affordability_check > enforces the table bounds: bedrooms 0-4, household_size 1-8. 47 others stayed green. Source restored, git diff --quiet -- server.ts clean.
Call-count assertions (toHaveBeenCalledTimes, not.toHaveBeenCalled) were audited the same day: 12 sites, 12 kept, 0 pruned. Each one pins a contract (which endpoint a call hit, validation firing before the network, retry counts, cache hits), not that a function ran. Policy: assert behavior and payloads, never bare invocation.
AI assistance
This project was built with AI assistance (Claude). Correctness rests on the checks, not the generation: the vitest suite drives every tool over the MCP in-memory transport against fixtures that mirror HUD's documented response samples — including this README's worked example — and npm run smoke makes one live call per tool against the real HUD API. I reviewed the code and am accountable for what it does.
License
MIT © Abishai James. Data is public U.S. government data from the HUD USER API; this project is unofficial and not affiliated with HUD.
Available Tools
6 toolsaffordability_checkA
Affordability verdicts computed server-side from the same HUD tables as fmr_lookup and income_limits: whether a proposed rent is above or below the Fair Market Rent for a bedroom size (dollar and percent gap), and which HUD income bands a household qualifies under (extremely low 30%, very low 50% = the Section 8 voucher line, low 80% of area median). Pass rent + bedrooms, income + household_size, or all four; returns the verdicts with the underlying numbers and table year for citation. entityid is a 10-digit county FIPS or a metro CBSA code (same as fmr_lookup).
| Name | Required | Description | Default |
|---|---|---|---|
| rent | No | Proposed monthly rent in dollars, to compare against the FMR for the given bedrooms | |
| year | No | Table year (e.g. '2026'); default is the latest | |
| income | No | Annual gross household income in dollars, to compare against the 30/50/80% area-median lines | |
| bedrooms | No | Bedroom count 0-4 (0 = efficiency/studio); required when rent is given | |
| entityid | Yes | 10-digit county entity id (county FIPS + 99999) or metro CBSA code. Derive from a ZIP via zip_crosswalk then list_counties | |
| household_size | No | Family size 1-8; required when income is given |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description fully discloses behavior: it returns verdicts with dollar/gap and income band qualifications, includes underlying numbers and table year for citation, and explains entityid format and derivation.
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?
Three concise, front-loaded sentences each serve a purpose: defining the tool, explaining inputs/outputs, and clarifying entityid. No redundant or extraneous text.
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?
The description covers the main outputs and input rules, but lacks mention of default year behavior or error conditions. For a tool with no output schema, it is still very complete.
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 description adds significant context beyond the input schema, explaining relational constraints (rent requires bedrooms, income requires household_size) and clarifying entityid usage, even though schema coverage is 100%.
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 computes affordability verdicts combining FMR and income limit comparisons, and distinguishes from sibling tools fmr_lookup and income_limits by mentioning it uses the same HUD tables but provides combined results.
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 the flexible input combinations (rent+bedrooms, income+household_size, or all four) and references sibling tools for deriving entityid, but does not explicitly state when to prefer this tool over fmr_lookup or income_limits individually.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fmr_lookupB
HUD Fair Market Rent (the rent a modest unit should cost) for an area, by bedroom count. entityid is a HUD entity id: a 10-digit county FIPS (e.g. 3600599999 for Bronx County = 36005 + 99999) or a metro CBSA code. Use zip_crosswalk then list_counties to turn a ZIP into a county entityid.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | FMR year (e.g. '2026'); default is the latest | |
| entityid | Yes | 10-digit county entity id (county FIPS + 99999) or metro CBSA code. Derive from a ZIP via zip_crosswalk then list_counties |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It implies a read-only lookup but does not explicitly state that there are no side effects, rate limits, or authentication requirements. The return format is also not fully described.
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 concise sentences front-load the purpose and provide essential input derivation context. No unnecessary words or repetition.
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 simple schema and no output schema, the description adequately explains input derivation but lacks details on the exact return format (e.g., structure of FMR values by bedroom count). It does not describe pagination or error handling.
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 schema already covers both parameters with descriptions. The description adds value by explaining the entityid format in detail with an example and clarifies the year parameter's default behavior.
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 provides HUD Fair Market Rent for an area by bedroom count. It explains the entityid format and how to derive it from a ZIP using sibling tools, but does not explicitly differentiate itself from similar tools like income_limits or affordability_check.
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?
No guidance is given on when to use this tool versus alternatives such as income_limits or affordability_check. It only describes how to prepare the entityid input, not the conditions for choosing this tool over others.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
income_limitsA
HUD income limits for an area: the extremely-low (30% AMI), very-low (50%, the Section 8 voucher line), and low (80%) income thresholds, by household size. Pass household_size (1-8) to get the single threshold that applies to a family that size. entityid is a 10-digit county FIPS or a metro CBSA code (same as fmr_lookup).
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | Income-limit year; default is the latest | |
| entityid | Yes | 10-digit county entity id (county FIPS + 99999) or metro CBSA code. Derive from a ZIP via zip_crosswalk then list_counties | |
| household_size | No | Family size 1-8; omit for all sizes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full transparency burden. It describes the output (income thresholds) and the effect of parameters, but does not disclose behavioral traits such as read-only nature, data freshness, or rate limits. Adequate for a simple lookup tool.
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 extremely concise—three sentences with no wasted words. It front-loads the purpose and immediately provides actionable details, making it easy for an agent to parse and use.
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 no output schema, the description sufficiently explains what the tool returns (three thresholds, single if household_size provided) and covers all parameters. It references a sibling tool (fmr_lookup) for entityid format. Lacks explicit mention of output structure but is otherwise complete.
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 description adds value beyond the schema by explaining the entityid format (10-digit county FIPS or metro CBSA code, same as fmr_lookup) and the effect of household_size (1-8, returns single threshold). The year parameter is noted as defaulting to latest.
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 retrieves HUD income limits for an area, specifies the three thresholds (30%, 50%, 80% AMI), and explains how household size affects the output. It distinguishes from fmr_lookup by noting the same entityid format, providing context for differentiation.
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 gives clear guidance: when to include household_size (for a single threshold) and explains the entityid format with a reference to fmr_lookup. However, it does not explicitly state when not to use this tool or suggest alternatives like affordability_check.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_countiesA
List the counties in a state with their 10-digit FIPS entity ids, so you can look up FMR or income limits by county name. Pass a 2-letter state code.
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | 2-letter state code (e.g. 'NY') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states that the tool lists counties with FIPS IDs, which implies a read-only operation. However, it does not disclose any additional behavioral traits such as authentication, rate limits, or reliance on external APIs. The description is minimally adequate.
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 a single, well-structured sentence that front-loads the action and purpose. Every word is necessary, and there is no redundancy or unnecessary detail.
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 tool's simplicity (one parameter, no output schema) and the presence of sibling tools, the description is complete. It explains what the tool does, why it is useful, and how to use it. The return format (county names and FIPS IDs) is implied, which is sufficient for this context.
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 already provides a description for the single parameter 'state' ('2-letter state code (e.g. 'NY')'). The tool description simply repeats this ('Pass a 2-letter state code'). With 100% schema description coverage, the description adds no new meaning beyond what the schema provides, earning a baseline score of 3.
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 verb 'List' and the resource 'counties in a state' with a specific purpose ('so you can look up FMR or income limits by county name'). This distinguishes it from sibling tools like fmr_lookup and income_limits, which perform different actions.
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 ties the tool to subsequent lookups (FMR, income limits), indicating when to use it. It also specifies the required input format ('Pass a 2-letter state code'), providing clear usage instructions. Although it does not mention when not to use, the context is sufficiently clear given the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_metro_areasA
List HUD metropolitan areas (CBSAs) with their codes, for metro-level FMR and income-limit lookups.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden of behavioral disclosure. It indicates the tool returns codes, but does not mention response format, pagination, or data freshness. For a simple enumeration tool, this is adequate but not highly descriptive.
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 a single, front-loaded sentence that efficiently conveys the action, resource, and purpose. No unnecessary words or repetition.
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 zero-parameter listing tool with no output schema, the description is complete. It explicitly connects to sibling tools (FMR, income limits) and explains the value of the output (codes for lookups).
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 has zero parameters and schema description coverage is 100%, so the baseline is 4. The description adds no parameter information because none exist, but it does hint at the response content ('with their codes').
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 action (List), the resource (HUD metropolitan areas), and the purpose (for metro-level FMR and income-limit lookups). It distinguishes itself from sibling tools like fmr_lookup or income_limits by indicating it provides codes for those lookups.
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 states the use case: 'for metro-level FMR and income-limit lookups.' This provides clear context for when to invoke this tool, but it does not mention any exclusions or alternatives. However, as a listing tool, the usage is naturally implied as a prerequisite step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zip_crosswalkA
Map a 5-digit ZIP to the county, tract, CBSA (metro), or congressional district it falls in, using the HUD-USPS crosswalk. Returns each matching geography with its residential-address share (res_ratio); the highest-share county is the one to resolve into an entityid via list_counties.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Target geography: county | tract | cbsa | cd (default county) | |
| zip | Yes | 5-digit ZIP code | |
| year | No | Crosswalk year; default is the latest |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations present, so description carries full burden. Describes the return format (geography + res_ratio) and hints at selection behavior (highest-share county). Does not mention potential edge cases (missing ZIP, multiple matches) but overall informative.
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 sentences with no extraneous text. Front-loaded with core purpose and immediately useful detail (res_ratio, entityid resolution).
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 no output schema, description explains exactly what is returned and how to interpret it (res_ratio, highest-share county). Includes cross-references to sibling tools for follow-up. Complete for a simple geospatial mapping 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%, so baseline is 3. Description adds no additional meaning to parameters themselves, but provides context on the output (res_ratio) that could influence parameter choice.
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?
Explicitly states the mapping from 5-digit ZIP to county/tract/CBSA/CD using HUD-USPS crosswalk, and mentions the res_ratio return value. Distinguishes from sibling tools like list_counties by referencing it as a subsequent step.
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?
Clearly describes the use case: mapping ZIPs to geography. Provides guidance on next step (resolving highest-share county via list_counties). Lacks explicit when-not-to-use or alternatives, but context is sufficient.
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.
6 tool updates
v1.0.0- First observed
affordability_check - First observed
fmr_lookup - First observed
income_limits - First observed
list_counties - First observed
list_metro_areas - First observed
zip_crosswalk
TDQS
Scored across 6 tools
Each tool has a distinct purpose: fmr_lookup for rent, income_limits for income thresholds, affordability_check for combined analysis, zip_crosswalk for geocoding, list_counties and list_metro_areas for geography enumeration. No overlap.
Most names follow a predictable verb_noun pattern (list_counties, list_metro_areas) or noun_noun (zip_crosswalk), but some are noun_verb (fmr_lookup, affordability_check). Slight inconsistency but still clear.
6 tools cover the core functionality of HUD fair market rent and income limit lookups with necessary geocoding support. Each tool earns its place without being excessive.
The set provides comprehensive querying for rent, income, affordability, and geolocation. Missing potential features like historical data or batch operations, but the core use case is well-covered.
Maintenance
Related MCP Connectors
HUD MCP — U.S. Department of Housing and Urban Development APIs.
MCP server for medicare-coverage
Census MCP — U.S. Census Bureau housing-relevant APIs.
MCP server for US nursing facility search and ownership lookup (NursingHomeDatabase).
Related MCP Servers
- AlicenseAqualityDmaintenanceAn 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.528 npm1MIT
- AlicenseNot gradedqualityCmaintenanceThis MCP server provides access to City of Houston GIS open geospatial data, enabling search, query, and schema retrieval of datasets like parcels and zoning through ArcGIS feature services.6 npmMIT
- FlicenseNot gradedqualityCmaintenanceRemote MCP server exposing US Census (ACS 5-year) and FEMA flood data. Works as a connector in both Claude and ChatGPT.-
- AlicenseAqualityAmaintenanceMCP server for NYC housing data, enabling tenant organizers and legal-aid intakes to pull building violations, complaints, ownership, litigation, and evictions. It wraps six city datasets from NYC Open Data.612 npmMIT