Skip to main content
Glama

Housing Affordability Check

housing_affordability_check
Read-onlyIdempotent

Check housing affordability in a market. Returns mortgage rate, median price, monthly payment, required income, and HUD limits. Optionally specify metro (e.g., "Denver"). The inputs are official statistics on DIFFERENT cadences — a weekly mortgage rate against a quarterly median price — so the monthly payment is an illustrative ratio of published figures, not a live quote. freshness states the span and the age of each input.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
stateNoState name or two-letter code (e.g., "California" or "CA"). Resolved for you — pass this rather than state_code. Optional: without it you still get the national mortgage rate, median price and affordability math, just no HUD income limits.
_blsKeyNoBLS registration key (optional — raises the shared quota; https://data.bls.gov/registrationEngine/)
_hudKeyNoHUD API token (optional — needed for income limits)
_fredKeyNoFRED API key
metro_nameNoMetro name for metro-level FHFA HPI (e.g., "Denver", "Savannah"). Optional.
state_codeNoTwo-letter state code for HUD income limits (e.g., "CO"). `state` is preferred and accepts either form.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
freshnessNo
metro_hpiNo
income_neededNo
mortgage_rateNoCurrent 30-year mortgage rate (percent)
state_resolvedNo
hud_income_limitsNo
median_home_priceNoMedian home price (USD)
case_shiller_indexNo
income_needed_noteNo
avg_hourly_earningsNoAverage hourly earnings for production/nonsup workers (USD) (type varies; observed both null and non-null)
mortgage_rate_as_ofNo
hud_income_limits_noteNo
median_home_price_noteNo
median_home_price_as_ofNo
case_shiller_index_as_ofNo
avg_hourly_earnings_as_ofNo(type varies; observed both null and non-null)
estimated_monthly_paymentNoEstimated monthly PITI (20% down, 30yr fixed)

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed28 schema fields changed
    • removedOutput schema / properties / affordability_date
      Removed value: -{
      -  "description": "Today's date in YYYY-MM-DD format",
      -  "type": "string"
      -}
    • removedOutput schema / properties / annual_income_needed
      Removed value: -{
      -  "description": "Required annual income (at 28% housing expense ratio)",
      -  "type": [
      -    "number",
      -    "null"
      -  ]
      -}
    • changedOutput schema / properties / avg_hourly_earnings / description
      Previous value: -"Average hourly earnings for production/nonsup workers (USD)"New value: +"Average hourly earnings for production/nonsup workers (USD) (type varies; observed both null and non-null)"
    • removedOutput schema / properties / avg_hourly_earnings / type
      Removed value: -[
      -  "number",
      -  "null"
      -]
    • addedOutput schema / properties / avg_hourly_earnings_as_of
      Added value: +{
      +  "description": "(type varies; observed both null and non-null)"
      +}
    • addedOutput schema / properties / case_shiller_index
      Added value: +{
      +  "type": "number"
      +}
    • addedOutput schema / properties / case_shiller_index_as_of
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • changedOutput schema / properties / estimated_monthly_payment / type
      Previous value: -[
      -  "number",
      -  "null"
      -]New value: +"number"
    • addedOutput schema / properties / freshness
      Added value: +{
      +  "properties": {
      +    "as_of": {
      +      "type": "string"
      +    },
      +    "components": {
      +      "items": {
      +        "properties": {
      +          "age_days": {
      +            "type": "number"
      +          },
      +          "cadence": {
      +            "type": "string"
      +          },
      +          "component": {
      +            "type": "string"
      +          },
      +          "observation_date": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "newest_component": {
      +      "type": "string"
      +    },
      +    "newest_observation_date": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "oldest_age_days": {
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "oldest_component": {
      +      "type": "string"
      +    },
      +    "oldest_observation_date": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "span_days": {
      +      "type": "number"
      +    },
      +    "statement": {
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • removedOutput schema / properties / hud_income_limits / oneOf
      Removed value: -[
      -  {
      -    "properties": {
      -      "areas": {
      -        "description": "HUD income limit areas (metro/county, up to 10)",
      -        "items": {
      -          "properties": {
      -            "ami": {
      -              "description": "Area median income (USD)",
      -              "type": [
      -                "number",
      -                "null"
      -              ]
      -            },
      -            "ami_percent": {
      -              "description": "Area median income percentage",
      -              "type": [
      -                "number",
      -                "null"
      -              ]
      -            },
      -            "area_name": {
      -              "type": [
      -                "string",
      -                "null"
      -              ]
      -            },
      -            "limit_120": {
      -              "description": "120% AMI income limit (USD)",
      -              "type": [
      -                "number",
      -                "null"
      -              ]
      -            },
      -            "limit_30": {
      -              "description": "30% AMI income limit (USD)",
      -              "type": [
      -                "number",
      -                "null"
      -              ]
      -            },
      -            "limit_50": {
      -              "description": "50% AMI income limit (USD)",
      -              "type": [
      -                "number",
      -                "null"
      -              ]
      -            },
      -            "limit_80": {
      -              "description": "80% AMI income limit (USD)",
      -              "type": [
      -                "number",
      -                "null"
      -              ]
      -            }
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "State code",
      -        "type": "string"
      -      },
      -      "year": {
      -        "description": "Income limit year",
      -        "type": "string"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "error": {
      -        "type": "string"
      -      }
      -    },
      -    "type": "object"
      -  }
      -]
    • addedOutput schema / properties / hud_income_limits / properties
      Added value: +{
      +  "extremely_low_4person": {
      +    "type": "number"
      +  },
      +  "low_4person": {
      +    "type": "number"
      +  },
      +  "median_income": {
      +    "type": "number"
      +  },
      +  "note": {
      +    "type": "string"
      +  },
      +  "state": {
      +    "type": "string"
      +  },
      +  "very_low_4person": {
      +    "type": "number"
      +  },
      +  "year": {
      +    "type": "string"
      +  }
      +}
    • addedOutput schema / properties / hud_income_limits / type
      Added value: +"object"
    • addedOutput schema / properties / hud_income_limits_note
      Added value: +{
      +  "type": "null"
      +}
    • addedOutput schema / properties / income_needed
      Added value: +{
      +  "type": "number"
      +}
    • addedOutput schema / properties / income_needed_note
      Added value: +{
      +  "type": "string"
      +}
    • removedOutput schema / properties / market
      Removed value: -{
      -  "description": "Market identifier (metro or 'National')",
      -  "type": "string"
      -}
    • addedOutput schema / properties / median_home_price_as_of
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / median_home_price_note
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / metro_hpi / properties / cadence
      Added value: +{
      +  "type": "string"
      +}
    • removedOutput schema / properties / metro_hpi / properties / current / description
      Removed value: -"Latest metro HPI value"
    • removedOutput schema / properties / metro_hpi / properties / error
      Removed value: -{
      -  "type": "string"
      -}
    • addedOutput schema / properties / metro_hpi / properties / metro
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / metro_hpi / properties / observation_date
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • removedOutput schema / properties / metro_hpi / properties / series / description
      Removed value: -"FRED FHFA HPI series ID"
    • removedOutput schema / properties / metro_hpi / properties / trend / enum
      Removed value: -[
      -  "rising",
      -  "falling",
      -  "stable"
      -]
    • changedOutput schema / properties / metro_hpi / type
      Previous value: -[
      -  "object",
      -  "null"
      -]New value: +[
      +  "null",
      +  "object"
      +]
    • addedOutput schema / properties / mortgage_rate_as_of
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / state_resolved
      Added value: +{
      +  "type": "string"
      +}
  2. Changed1 schema field changed
    • addedInput schema / properties / _blsKey
      Added value: +{
      +  "description": "BLS registration key (optional — raises the shared quota; https://data.bls.gov/registrationEngine/)",
      +  "type": "string"
      +}
  3. Changed2 schema fields changed
    • changedInput schema / examples
      Previous value: -[
      -  {
      -    "_fredKey": "your-housing-intel-api-key",
      -    "state_code": "CO"
      -  },
      -  {
      -    "_fredKey": "your-housing-intel-api-key",
      -    "_hudKey": "your-housing-intel-api-key",
      -    "metro_name": "Denver",
      -    "state_code": "CO"
      -  }
      -]New value: +[
      +  {
      +    "state_code": "CO"
      +  },
      +  {
      +    "metro_name": "Denver",
      +    "state_code": "CO"
      +  }
      +]
    • changedInput schema / required
      Previous value: -[
      -  "_fredKey"
      -]New value: +[]
  4. Changed1 schema field changed
    • changedInput schema / examples
      Previous value: -[
      -  {
      -    "_fredKey": "your-housing-intel-api-key",
      -    "state_code": "CO"
      -  },
      -  {
      -    "_fredKey": "your-housing-intel-api-key",
      -    "_hudKey": "your-housing-intel-api-key",
      -    "metro_name": "Denver",
      -    "state_code": "CO",
      -    "zip_code": "80212"
      -  }
      -]New value: +[
      +  {
      +    "_fredKey": "your-housing-intel-api-key",
      +    "state_code": "CO"
      +  },
      +  {
      +    "_fredKey": "your-housing-intel-api-key",
      +    "_hudKey": "your-housing-intel-api-key",
      +    "metro_name": "Denver",
      +    "state_code": "CO"
      +  }
      +]
  5. Changed1 schema field changed
    • removedInput schema / properties / zip_code
      Removed value: -{
      -  "description": "ZIP code for more specific HUD data (optional)",
      -  "type": "string"
      -}
  6. Changed1 schema field changed
    • changedOutput schema / properties / metro_hpi / type
      Previous value: -"object"New value: +[
      +  "object",
      +  "null"
      +]
  7. Changed3 schema fields changed
    • addedInput schema / properties / state
      Added value: +{
      +  "description": "State name or two-letter code (e.g., \"California\" or \"CA\"). Resolved for you — pass this rather than state_code. Optional: without it you still get the national mortgage rate, median price and affordability math, just no HUD income limits.",
      +  "type": "string"
      +}
    • changedInput schema / properties / state_code / description
      Previous value: -"Two-letter state code for HUD income limits (e.g., \"CO\")"New value: +"Two-letter state code for HUD income limits (e.g., \"CO\"). `state` is preferred and accepts either form."
    • changedInput schema / required
      Previous value: -[
      -  "_fredKey",
      -  "state_code"
      -]New value: +[
      +  "_fredKey"
      +]
  8. Changed19 schema fields changed
    • addedOutput schema / properties / affordability_date
      Added value: +{
      +  "description": "Today's date in YYYY-MM-DD format",
      +  "type": "string"
      +}
    • addedOutput schema / properties / annual_income_needed
      Added value: +{
      +  "description": "Required annual income (at 28% housing expense ratio)",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • changedOutput schema / properties / avg_hourly_earnings / description
      Previous value: -"Average hourly earnings"New value: +"Average hourly earnings for production/nonsup workers (USD)"
    • removedOutput schema / properties / case_shiller_index
      Removed value: -{
      -  "type": [
      -    "number",
      -    "null"
      -  ]
      -}
    • changedOutput schema / properties / estimated_monthly_payment / description
      Previous value: -"Estimated monthly payment (20% down, 30yr fixed)"New value: +"Estimated monthly PITI (20% down, 30yr fixed)"
    • addedOutput schema / properties / hud_income_limits / oneOf
      Added value: +[
      +  {
      +    "properties": {
      +      "areas": {
      +        "description": "HUD income limit areas (metro/county, up to 10)",
      +        "items": {
      +          "properties": {
      +            "ami": {
      +              "description": "Area median income (USD)",
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "ami_percent": {
      +              "description": "Area median income percentage",
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "area_name": {
      +              "type": [
      +                "string",
      +                "null"
      +              ]
      +            },
      +            "limit_120": {
      +              "description": "120% AMI income limit (USD)",
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "limit_30": {
      +              "description": "30% AMI income limit (USD)",
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "limit_50": {
      +              "description": "50% AMI income limit (USD)",
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "limit_80": {
      +              "description": "80% AMI income limit (USD)",
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            }
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "State code",
      +        "type": "string"
      +      },
      +      "year": {
      +        "description": "Income limit year",
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "error": {
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  }
      +]
    • removedOutput schema / properties / hud_income_limits / properties
      Removed value: -{
      -  "error": {
      -    "type": "string"
      -  },
      -  "extremely_low_4person": {
      -    "type": [
      -      "number",
      -      "null"
      -    ]
      -  },
      -  "low_4person": {
      -    "type": [
      -      "number",
      -      "null"
      -    ]
      -  },
      -  "median_income": {
      -    "type": [
      -      "number",
      -      "null"
      -    ]
      -  },
      -  "note": {
      -    "type": "string"
      -  },
      -  "raw_response": {
      -    "type": "object"
      -  },
      -  "state": {
      -    "type": "string"
      -  },
      -  "very_low_4person": {
      -    "type": [
      -      "number",
      -      "null"
      -    ]
      -  },
      -  "year": {
      -    "type": [
      -      "number",
      -      "null"
      -    ]
      -  }
      -}
    • removedOutput schema / properties / hud_income_limits / type
      Removed value: -"object"
    • removedOutput schema / properties / income_needed
      Removed value: -{
      -  "description": "Annual income needed for DTI 28%",
      -  "type": [
      -    "number",
      -    "null"
      -  ]
      -}
    • removedOutput schema / properties / income_needed_note
      Removed value: -{
      -  "type": "string"
      -}
    • addedOutput schema / properties / market
      Added value: +{
      +  "description": "Market identifier (metro or 'National')",
      +  "type": "string"
      +}
    • changedOutput schema / properties / median_home_price / description
      Previous value: -"National median home price in dollars"New value: +"Median home price (USD)"
    • removedOutput schema / properties / median_home_price_note
      Removed value: -{
      -  "type": "string"
      -}
    • addedOutput schema / properties / metro_hpi / properties / current / description
      Added value: +"Latest metro HPI value"
    • addedOutput schema / properties / metro_hpi / properties / error
      Added value: +{
      +  "type": "string"
      +}
    • removedOutput schema / properties / metro_hpi / properties / metro
      Removed value: -{
      -  "type": "string"
      -}
    • addedOutput schema / properties / metro_hpi / properties / series / description
      Added value: +"FRED FHFA HPI series ID"
    • changedOutput schema / properties / mortgage_rate / description
      Previous value: -"Current 30-year mortgage rate (%)"New value: +"Current 30-year mortgage rate (percent)"
    • removedOutput schema / required
      Removed value: -[
      -  "mortgage_rate",
      -  "median_home_price",
      -  "median_home_price_note",
      -  "case_shiller_index",
      -  "avg_hourly_earnings",
      -  "estimated_monthly_payment",
      -  "income_needed",
      -  "income_needed_note",
      -  "hud_income_limits"
      -]
  9. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "avg_hourly_earnings": {
      +      "description": "Average hourly earnings",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "case_shiller_index": {
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "estimated_monthly_payment": {
      +      "description": "Estimated monthly payment (20% down, 30yr fixed)",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "hud_income_limits": {
      +      "properties": {
      +        "error": {
      +          "type": "string"
      +        },
      +        "extremely_low_4person": {
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        },
      +        "low_4person": {
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        },
      +        "median_income": {
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        },
      +        "note": {
      +          "type": "string"
      +        },
      +        "raw_response": {
      +          "type": "object"
      +        },
      +        "state": {
      +          "type": "string"
      +        },
      +        "very_low_4person": {
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        },
      +        "year": {
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "income_needed": {
      +      "description": "Annual income needed for DTI 28%",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "income_needed_note": {
      +      "type": "string"
      +    },
      +    "median_home_price": {
      +      "description": "National median home price in dollars",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "median_home_price_note": {
      +      "type": "string"
      +    },
      +    "metro_hpi": {
      +      "properties": {
      +        "current": {
      +          "type": "number"
      +        },
      +        "metro": {
      +          "type": "string"
      +        },
      +        "series": {
      +          "type": "string"
      +        },
      +        "trend": {
      +          "enum": [
      +            "rising",
      +            "falling",
      +            "stable"
      +          ],
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "mortgage_rate": {
      +      "description": "Current 30-year mortgage rate (%)",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    }
      +  },
      +  "required": [
      +    "mortgage_rate",
      +    "median_home_price",
      +    "median_home_price_note",
      +    "case_shiller_index",
      +    "avg_hourly_earnings",
      +    "estimated_monthly_payment",
      +    "income_needed",
      +    "income_needed_note",
      +    "hud_income_limits"
      +  ],
      +  "type": "object"
      +}
  10. Changed1 schema field changed
    • addedInput schema / examples
      Added value: +[
      +  {
      +    "_fredKey": "your-housing-intel-api-key",
      +    "state_code": "CO"
      +  },
      +  {
      +    "_fredKey": "your-housing-intel-api-key",
      +    "_hudKey": "your-housing-intel-api-key",
      +    "metro_name": "Denver",
      +    "state_code": "CO",
      +    "zip_code": "80212"
      +  }
      +]
  11. First observed

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive. The description adds valuable context by disclosing that inputs come from different cadences (weekly mortgage rate vs quarterly median price) and that the monthly payment is an illustrative ratio, not a live quote. It also mentions that `freshness` reports the span and age of inputs, giving the agent awareness of data staleness. This goes beyond the annotations and is important for correct interpretation of results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no fluff. It front-loads the primary action and outputs, then adds the optional metro note and the critical cadence caveat. Every sentence contributes essential information, and the structure is logical and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description does not need to detail return values. It covers the core purpose, the optional metro, and the important data-freshness caveat. The main gap is that it does not explicitly state whether API keys (e.g., _fredKey) are required for certain outputs, though the schema covers this. Overall, it is sufficiently complete for an agent to understand how to call the tool and interpret results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters. The description adds minimal new information about parameters—it only mentions the optional metro and restates the state behavior that is already in the schema. The cadence caveat is behavioral, not parameter-specific, so the description does not meaningfully extend the schema's parameter documentation. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action ('Check housing affordability in a market') and lists concrete outputs (mortgage rate, median price, monthly payment, required income, HUD limits). This makes it distinct from sibling tools like housing_market_snapshot, which focus on broader market conditions, and the specificity of the metrics leaves no ambiguity about the tool's function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context about what the tool does and its optional metro parameter, but it does not explicitly contrast it with sibling housing tools or state when to prefer this over alternatives like housing_market_snapshot or housing_metro_demand. The usage is implied by the name and outputs, but there is no direct guidance on choosing it over other tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.