Keyway MCP tool reference
This reference is generated from the public tool definitions returned by Keyway MCP. It intentionally contains no credentials, endpoint configuration, or tool results.
Snapshot: Production snapshot captured 2026-09-04T18:11:05.179Z.
Tools: 17
| Tool | Description |
|---|---|
| Analyze Comp Set | Complete rent analysis for a comp set. Returns ALL data needed to answer rent, pricing, or competitive positioning questions — with pre-computed comparisons, so you can respond directly without further calculation. Response structure: - subject: flat dict with property info + average metrics + detail breakdown. - comp_set_summary: aggregated averages across all comps (+ per-group), including the set's leasing signal (avgListingDays, exposure, occupancy). - positioning: pre-computed comparisons against comps and market: - {field}VsComps: % difference vs comp set average (e.g. "+4.7%"). - askingRentRank: subject rank by asking rent (e.g. "2/13", 1=highest). - effectiveRentRank: subject rank by effective rent after concessions. - askingRentVsMarket: % diff vs ZIP market average (when zip_code provided). - effectiveRentVsMarket: same for effective rent. - comps: CSV with one row per comp (propertyId, name, yearBuilt, askingRent, ...). Key computed columns: - concessionSpread: discount depth = (asking - effective) / asking * 100. Higher values = more aggressive concessions. 0 = no discount. - exposure: units available / the property's unit count, as a percentage. Present only when the unit count is known; when it is absent, so is this — do not substitute unitsSeen for it. - occupancy: the leased share — exposure's complement, same condition. - unitsSeen: distinct units seen listed in the window. A sample size, NOT the building — it typically runs 20-35% of the unit count. - avgListingDays: days on market, averaged over the period's listings. LEASING SIGNAL: exposure, days on market and leased % are HERE, for the subject and every comp. Do NOT reach for get_comp_set_comps_details to get them; that costs 100K+ tokens for the same numbers. propertyId is the Keyway property code (e.g. "USNC-007026"). Pass it straight to get_property_details, get_rent_metrics_for_properties or get_historical_exposure_summary — do NOT re-resolve comps by name with get_property_id, several comps in a set can share a name. The subject also carries reportedOccupancy: KeyComps' own leased share for the building, independent of this window's listings. - comps_by_bedroom: CSV with comp propertyId + name + per-bedroom metrics (when grouping != PROPERTY). ONE ROW PER BEDROOM COUNT PER COMP, labelled by a `bedrooms` column — read that column before quoting a number, a 12-comp set is ~40 rows. UNIT_MIX names it comps_by_unit_mix and adds `bathrooms`; FLOOR_PLAN names it comps_by_floor_plan and labels by `floorPlan`. positioning.byBedroom is keyed the same way, one entry per bedroom count. These cuts carry no exposure or occupancy: a cut's real denominator is the units of that bedroom count, which nothing here knows. - concessions_summary: (when include_concessions=True) dict with: - propertiesWithActiveConcessions: "X/Y" count. - subjectHasActiveConcession: bool. - byProperty: list with per-property concession activity: - concessionDays: days with active concessions in date range. - frequency: concessionDays/totalDays as percentage. - changes: number of distinct concession texts (volatility indicator). - concessions: CSV with ONLY active concessions (descriptions cleaned of boilerplate). NOTE: Concessions are property-level (not broken down by unit type). Do NOT call other tools trying to get per-unit-type concession data, it does not exist. - historical_rent: CSV of rent trends (when include_historical_rent=True). - market_benchmarks: ZIP-level metrics pass-through (when zip_code provided). |
| Create Comp Set | Create a new comp set with specified properties. Prior to use this tool, confirm the user if they want to create a new comp set. |
| Get Comp Set Comparables Details | Raw property data for comparable properties: amenities, unit listings, reviews. WHEN TO CALL: For amenities — which comps have a pool, a gym, whatever the property offers — use data_level="amenities". Only go to 'detailed'/'full' when the user asks for individual unit-by-unit listing prices or review scores. For exposure, days on market or leased %, call analyze_comp_set instead: it returns those per comp, in a response two orders of magnitude smaller. COST WARNING: 'detailed' and 'full' levels return 100K-200K+ tokens. 'amenities' carries no listings and no rest-of-the-property-record: a 12-comp set measured 13K characters against 306K at 'full'. |
| Get Comp Set Details | Raw property data for the subject/base property: amenities, unit listings, reviews. WHEN TO CALL: For amenities — pool, gym, pet policy, what the property offers — use data_level="amenities". Only go to 'detailed'/'full' when the user asks for individual unit-by-unit listing prices or resident review scores. COST WARNING: 'detailed' and 'full' levels return 50K-200K+ tokens. 'amenities' carries no listings and no rest-of-the-property-record, and measured under 2K characters per property. |
| Get Comp Sets | Get a list of all rent comparable sets (comp sets) available for the organization. Returns up to 50 comp sets with: id, name, subject property ID, and comparable property IDs. Use the returned comp_set_id to analyze the comp set. Note: Returns the first 50 comp sets. If the organization has more, results are truncated. Returns: Dict with "compSets" key containing list of comp set summaries. |
| Get Demographics | Get demographics information for a specified geographic area. Use ``PUMA`` whenever the user asks about a submarket. In this tool, "submarket" and PUMA refer to the same geography level. |
| Get Historical Exposure Summary | How a property's availability moved over time, one row per period. WHEN TO CALL: any "over time", "by month", "trend", "velocity" or "absorption" question about leasing — how much of the property sat available, whether that is improving, how long units take to place. `get_historical_rent_summary` answers that shape of question for PRICE; this one answers it for VELOCITY. CALL THIS FIRST. `get_comp_set_details` and `get_comp_set_comps_details` at data_level "detailed"/"full" can answer the same question by returning every raw unit listing for you to count, but they cost 10K-200K+ tokens and grow with the size of the comp set. This endpoint is pre-aggregated by the backend and bounded at 30 periods, so it costs a few hundred tokens whatever the property's size. Only fall back to the raw-listing tools if this returns no data and the user needs a per-unit answer. Each period carries: - exposureRate: share of units available (0-1). - unitsAvailable: that rate applied to the property's unit count. - netUnitsAbsorbed: drop in available units vs the previous period. Positive means availability shrank. - avgListingDays: average days a unit stayed listed. WHAT THIS CANNOT TELL YOU. There is no per-period count of units leased or taken off the market anywhere in the platform. Exposure is a rate, and `netUnitsAbsorbed` nets move-outs and newly listed units against units leased — a month where ten units leased and ten more came available reads as zero. Report it as net change in availability and say so. If the user asks specifically how many units were leased or taken off the market in a period, give this net figure with that caveat; do not present it as a lease count. |
| Get Historical Rent Summary | Get historical rent data for a property over time, optionally compared against geographic benchmarks (ZIP code, PUMA, MSA) fetched in parallel. Use with only property_id for single-property historical trends. Add zip_code, puma_code, or msa_code to compare against market averages. |
| Get New Development Stats | Get new housing development statistics for a geographic area. Shows the construction pipeline: units under construction, planned, prospective, in lease-up, plus supply growth metrics and on/off market breakdown. |
| Get Property Details | Given property IDs, returns a structured property details payload. |
| Get Property ID | Given a search term, returns properties that match the search term. This returns the property id and the address. |
| Get Property Reviews | Get tenant sentiments and reviews for multiple properties. |
| Get Rent Comps | Find rent comparables (rent comps) for a property, ranked by similarity score, with property details and rent metrics merged in. Each comparable includes `distance` (miles from the subject property), `score` (overall similarity, higher is more similar), `scoreDetail` (per-factor breakdown showing each factor's score and the normalized weight actually applied), a nested `property` object with the essentials for evaluating the comparable (name, address, city, state, zipCode, constructionYear, unitsQuantity, squareFootage, stories, propertyStyle), and a nested `rent` object with the comparable's rent metrics over the requested date window: average/median asking and effective rent, average asking/effective rent per square foot, the derived concession percentage (how far effective rent sits below asking), average days on market for its listings, units available, total units, and the number of rent records behind the numbers. Call this to benchmark rents for a property — e.g. for underwriting, rent surveys, or screening candidate rent comps — narrowing the pool with any combination of the filters below. All filters except `max_distance` are optional; omitted filters don't constrain results. |
| Get Rent Information | Get current available units and their rent values for a property. Returns individual unit-level data: unit number, floor plan, bedroom/bathroom count, square footage, asking rent, effective rent, availability date, and lease terms. Use this tool when the user needs: - Current unit-level listings for a specific property - Available units with their specific rents and floor plans - Raw unit data (not aggregated metrics) For aggregated rent statistics (avg/min/max/median), prefer get_rent_metrics_for_properties. |
| Get rent metrics by market type | Get rent metrics by market type at both property level and bedroom level. Args: date_from: Start date in YYYY-MM-DD format date_to: End date in YYYY-MM-DD format rent_type: Type of rent to retrieve - must be either "ASKING" or "EFFECTIVE" (default: "ASKING") zip_code: The ZIP code to get rent metrics for (optional) msa_code: The MSA code to get rent metrics for (optional) puma_code: The PUMA code to get rent metrics for (optional) include_bedrooms: Whether to include bedroom-level metrics (default: True) |
| Get rent metrics for properties | Get pre-aggregated rent metrics (avg/min/max/median) for one or more properties. Returns compact statistical summaries -- much more token-efficient than fetching raw listings. Use when you have individual property IDs (not a comp set). Each response includes for every grouping level: - askingRent, effectiveRent, askingRentPSF, effectiveRentPSF (avg/min/max/median) - deposit, squareFootage (avg/min/max/median) - averageListingDays, recordsQuantity, totalUnits, unitsAvailable |
| Get Sales Comps | Find sale comparables (sales comps) for a property, ranked by similarity score, flattened into ready-to-use sales-comp records. Each comparable includes `distance` (miles from the subject property), `score` (overall similarity, higher is more similar), `scoreDetail` (per-factor breakdown showing each factor's score and the normalized weight actually applied), and the sales-comp facts flattened onto the record: name, address, city, state, zipCode, `status` ("LISTED" for on-market comps, "SOLD" for off-market ones), listPrice and listingDate, salePrice and saleDate, buyer, seller, the sale's confidenceVerdict and confidenceReasons, transactionType, pricePerSquareFoot and pricePerUnit (from the sale record when available, otherwise derived from the status-correct price), plus squareFootage, unitsQuantity, constructionYear, stories and propertyStyle. Listing and sale facts are populated independently, so a sold comp that was previously listed carries both. Call this to find sale comps for a property — e.g. for valuation, underwriting, or screening recent transactions — narrowing the pool with any combination of the filters below. All filters except `max_distance` are optional; omitted filters don't constrain results. Some matches are removed from the response after ranking, mirroring how Keyway curates sales comps: single-unit properties, off-market comps with no sale record, and comps whose last sale is flagged EXCLUDE. `total` counts matches before this curation, so a page may contain fewer than `size` items; sending confidence_verdicts=["VALID_HIGH", "VALID_WITH_NOTES", "REVIEW"] and min_unit_quantity=2 pushes most of the curation into the search itself. |