homes-mcp
homes-mcp is an MCP server that gives Claude natural-language access to homes.com real-estate data through your signed-in browser tab.
Search listings by location with filters (property type, listing type, price band, sort) and get address, price, beds/baths, sqft, photos, agent, URL.
Fetch full property details: lat/lng, year built, status, HOA, lot size, parking, heating/cooling, MLS, schools, highlights, extracted features, agent/brokerage, price/tax history.
Get photo galleries, combined price + tax history, and nearby listings for a property.
Resolve street addresses to homes.com property URLs (single or bulk), and bulk-fetch up to 200 property records.
Compare 2–8 properties side-by-side with optional summary table.
Get market reports (median/avg sale price, $/sqft) for a location.
Access the signed-in user's saved homes and saved searches.
Run local real-estate math: mortgage PITI, affordability (28/36 DTI), rent-vs-buy projection.
Healthcheck the fetchproxy bridge and manage session labels for your own bookkeeping.
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., "@homes-mcpfind 3-bedroom homes in Denver under $600k"
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.
homes-mcp
homes.com real-estate access as an MCP server for Claude — search listings, resolve addresses, fetch property details, price/tax history, market reports, saved homes, photo galleries, and run affordability/mortgage math, all via natural language.
⚠️ homes.com does not publish a public consumer API. This server reads the same server-rendered HTML and Schema.org JSON-LD that homes.com itself ships to your browser, routed through your own signed-in browser tab via the fetchproxy extension. Every request acts on behalf of your existing session — your cookies, your TLS, your JS context — exactly as if you'd clicked it in the browser yourself. Treat this as informal use of homes.com. Use at your own discretion.
Tools
Tool | Purpose |
| Search listings by free-text location (city/ZIP/neighborhood). Slugifies the input into homes.com's URL routing and parses the JSON-LD |
| Resolve one US street address to its canonical homes.com property URL + opaque hash. Walks structured typeahead → slug → city/zip search-fallback with whole-token street + unit verification. Returns |
| Bulk |
| Full record for a property by URL. Parses JSON-LD + DOM-side sections: address, lat/lng, beds/baths, sqft, year built, price, status, agent (name/title/profile — telephone/email only with |
| Full photo gallery scraped from |
| Fetch up to 200 properties' structured records in one call (per-row errors, input order preserved). |
| Side-by-side comparison of 2–8 properties with an aligned summary table. Per-target errors captured per-row. Concurrent fetches. |
| The "Homes for Sale Near This Property" cross-link cards from a detail page (For Sale, optionally Rentals). URL + address only. |
| Combined price + tax history in one fetch: |
| Deprecated — price/ownership/lien timelines only. Prefer |
| Deprecated — year-by-year tax records only. Prefer |
| Median / average / $-per-sqft for a market, derived from the |
| The signed-in user's saved (favorited) homes. Auth-gated. |
| The signed-in user's saved searches. Auth-gated. |
| Local affordability calculator — max purchase price from income + DTI + rates. No network. |
| Local PITI calculator — principal+interest, taxes, insurance, HOA, PMI. No network. |
| Local rent-vs-buy model — you supply |
| Round-trips |
| List / register / switch account labels for your own bookkeeping. Label only: requests always use whichever account the fetchproxy browser tab is signed into. |
Known data gap: rental estimates
homes.com does NOT publish rental estimates anywhere on its consumer site — there's no rent_zestimate analogue, no "estimated rent" widget on property detail pages, and no comparable-rentals endpoint. The homes_estimate_rent_vs_buy tool exists for the math, but it requires the caller to pass monthly_rent directly (you can't fetch a rent estimate from homes.com to plug in).
For rental signals, use a sibling MCP: zillow_get_property carries rent_zestimate on detail records, and redfin_get_comparable_rentals returns rental comps by URL. See issue #28 for the feasibility investigation.
Related MCP server: mcp-server-attom
Acknowledgement of Terms
By using this MCP server, you acknowledge and agree to the following:
1. This server accesses your own homes.com session. Every request is dispatched through your own browser tab via the fetchproxy extension — your cookies, your TLS, your session. It does not — and cannot — access anyone else's account.
2. homes.com's Terms of Use govern your use of this server, just as they govern your direct use of homes.com. The terms prohibit automated crawling without written permission, and IDX listing data is licensed for personal, non-commercial use only. You are agreeing to those terms every time you invoke a tool in this server.
3. Personal, non-commercial use only. This project is not affiliated with, endorsed by, sponsored by, or in partnership with homes.com or CoStar Group. It is a personal automation tool that reads the same server-rendered HTML and Schema.org JSON-LD homes.com ships to your browser. Do not use it to bulk-extract listings, redistribute IDX data, train AI models, populate a competing real-estate product, or for any commercial purpose.
4. Stability is not guaranteed. This server reads Schema.org JSON-LD (<script type="application/ld+json">) and DOM-side <img> tags from SSR pages whose URL conventions (/<city>-<state>/, /property/<slug>/<id>/) may change without notice. It may break. It may stop working. That's by design — the surface is not theirs to maintain on our behalf.
5. You accept full responsibility for any consequences of using this server in connection with your homes.com access — rate limiting, account suspension, IP blocks, AWS WAF challenges, or any enforcement action homes.com takes. If homes.com objects to your use, stop using this server.
This section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede homes.com's actual ToU.
Install
Option A — npx (after first publish)
Add to .mcp.json:
{
"mcpServers": {
"homes": {
"command": "npx",
"args": ["-y", "homes-mcp"]
}
}
}Option B — from source
git clone https://github.com/chrischall/homes-mcp
cd homes-mcp
npm install
npm run build{
"mcpServers": {
"homes": {
"command": "node",
"args": ["/path/to/homes-mcp/dist/bundle.js"]
}
}
}One-time browser setup
homes-mcp talks to your browser through the fetchproxy extension, which is shared across every fetchproxy-based MCP (zillow-mcp, opentable-mcp, resy-mcp, …). It lives in its own repo and is installed separately — it is not bundled here. Follow the install instructions at github.com/chrischall/fetchproxy, then load the built extension in Chrome via chrome://extensions → toggle Developer mode → Load unpacked.
Open homes.com and sign in. That's all the auth this server needs.
How it works
┌────────────────┐ stdio ┌──────────────────┐ WS ┌──────────────────┐ fetch() ┌─────────────┐
│ MCP client │◀────────▶│ dist/bundle.js │◀──────▶│ fetchproxy │◀────────────▶│ homes.com │
│ (Claude, etc.) │ │ (Homes MCP) │ :37149 │ extension │ (real TLS, │ (your tab) │
└────────────────┘ └──────────────────┘ │ (separate) │ cookies) └─────────────┘The MCP server runs in Node, but every HTTP call to homes.com is dispatched into your live browser tab through the fetchproxy extension. Each request rides your existing session — TLS fingerprint, cookies, and JS execution context all match the page that's already on screen. No headless browser stand-in, no separate identity, no third-party proxy: just your real browser, acting on its own behalf, with the MCP server picking what to ask for.
homes.com's pages are SSR React with no public JSON API — every tool extracts data from the Schema.org JSON-LD block embedded in each page (<script type="application/ld+json">). Search pages put listings in CollectionPage.mainEntity.itemListElement[]; detail pages emit a RealEstateListing graph node with mainEntity (address, size, geo) and offers.offeredBy[] (listing agent). Photos are scraped from the DOM since the JSON-LD only carries one primary image. The client wraps that into the tool surface so callers never have to parse HTML themselves.
Commands
npm test # tsc typecheck + vitest, mocked transport, no network
npm run test:watch
npm run test:coverage
npm run build # tsc --noEmit + esbuild bundle → dist/bundle.js
npm run dev # node dist/bundle.js (after build)License
MIT
Available Tools
21 toolshomes_bulk_getBulk-fetch homes.com properties (structured records only)ARead-onlyIdempotent
Fetch up to 200 homes.com properties in one call and return their structured records. Pass urls: string[]. Results are ordered to match the input array and per-row errors are captured (one bad URL won't fail the whole call). Each row carries a status (ok / error / pending). Mirrors homes_get_property per-row, including extracted_features, hoa_fee, highlights, schools, lot_size_sqft + the derived lot_size_acres (null — never 0 — for condos / no-lot listings), and all standard listing fields. The raw description is omitted by default; opt back in via include_description: true. listing_agent omits the agent's telephone/email unless include_agent_contact: true. The whole call is bounded by an overall hard deadline: a single slow/hung URL never wedges the server — when the deadline is reached any unsettled row is returned with status: "pending" and a pending count so you can re-run just those URLs. Use this instead of looping homes_compare_properties (which caps at 8 + emits a redundant summary table) when you just want the records. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | Array of homes.com property URLs or paths (e.g. from a homes_search_properties result). 1–200 per call. | |
| view | No | Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact strips image/avatar URLs from the response; "full" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs. | |
| include_description | No | When true, include the raw listing `description` marketing prose per-row. Default false. | |
| include_agent_contact | No | When true, include the listing agent's `telephone` and `email` on `listing_agent`. Default false — name, job title, profile url and brokerage are returned without the contact details. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnly, idempotent, and openWorld, and the description adds substantial behavioral detail: per-row status values, ordering matching input, per-row error isolation, hard-deadline pending behavior, omitted description/agent-contact fields, and lot_size_acres null semantics. No contradiction with annotations.
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 long but information-dense; the main purpose is front-loaded and every subsequent sentence covers a distinct behavioral or usage point. No filler or repetition of schema fields.
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 carries the burden of explaining return behavior, and it does: row statuses, field set, ordering, pending count, and edge cases like bad URLs and slow/hung requests. An agent has enough to call and interpret results correctly.
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 baseline is 3, but the description adds meaningful context beyond the schema: urls is passed as string[], include_description defaults to false and opts raw prose back in, and include_agent_contact controls telephone/email exposure. The view parameter is left to the schema, which already documents it well.
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 a specific verb and resource: fetch up to 200 homes.com properties and return structured records. It also distinguishes itself from siblings by noting it mirrors homes_get_property per-row and is preferable to looping homes_compare_properties.
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 says to use this instead of looping homes_compare_properties when only the records are wanted, and explains why (8-item cap + redundant summary). It also frames the relationship to homes_get_property, giving an agent clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_calculate_affordabilityCalculate maximum home price you can affordBRead-onlyIdempotent
Solve for the maximum home price you can afford under the standard 28/36 DTI rule. Inputs: monthly income, recurring monthly debts (car/student loans), down payment, interest rate, optional property-tax rate / insurance / HOA / loan term. Output: max home price, binding constraint (front-end vs back-end), and the PITI breakdown at that price. Identical math to zillow-mcp and redfin-mcp. No network — pure local math.
| Name | Required | Description | Default |
|---|---|---|---|
| hoa_monthly | No | ||
| back_end_dti | No | ||
| down_payment | Yes | ||
| front_end_dti | No | ||
| interest_rate | Yes | ||
| monthly_debts | No | ||
| monthly_income | Yes | ||
| loan_term_years | No | ||
| insurance_annual | No | ||
| property_tax_rate | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds non-obvious behavioral context beyond annotations: 'No network — pure local math' and identical math to zillow-mcp/redfin-mcp, plus the output breakdown. This helps the agent understand execution characteristics without contradicting the readOnly/idempotent hints.
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?
Every sentence earns its place: a precise headline, a compact input enumeration, a clear output summary, and implementation caveats. It is concise and well-structured with no filler.
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 10-parameter calculator with no output schema and no parameter descriptions, the definition under-specifies units, defaults, and custom DTI overrides. The required fields are clear, but optional inputs remain ambiguous enough to affect correct use.
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 description coverage is 0%, so the description must compensate. It lists most inputs and clarifies monthly debts, but omits front_end_dti and back_end_dti, and does not specify units or default conventions for interest rate, property-tax rate, or insurance. This leaves ambiguity for 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?
Description states a specific operation: solving for the maximum affordable home price under the 28/36 DTI rule, with explicit outputs. It is clearly distinguishable from search/get/property tools, but it does not explicitly differentiate itself from the sibling homes_calculate_mortgage.
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 rule and outputs imply this is for affordability calculations, but there is no explicit when-to-use vs alternatives guidance. Mentioning 'Identical math to zillow-mcp and redfin-mcp' gives external context but does not compare it to internal siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_calculate_mortgageCalculate mortgage PITIARead-onlyIdempotent
Local-only mortgage payment calculator. Returns a full PITI breakdown (principal + interest, property tax, insurance, HOA, PMI) and total interest over the life of the loan. No network call. Provide either down_payment OR down_payment_percent; defaults to 20%. Property tax can be given as property_tax_annual or property_tax_rate (% of home price). PMI applies automatically when LTV > 80% and pmi_rate is provided.
| Name | Required | Description | Default |
|---|---|---|---|
| pmi_rate | No | Annual %, applied when LTV > 80% | |
| home_price | Yes | ||
| hoa_monthly | No | ||
| down_payment | No | ||
| interest_rate | Yes | Annual %, e.g. 6.5 | |
| loan_term_years | No | Default 30 | |
| insurance_annual | No | ||
| property_tax_rate | No | Annual % of home price | |
| property_tax_annual | No | ||
| down_payment_percent | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint and idempotentHint, so the bar is lower. The description adds meaningful behavioral details: no network call, 20% default down payment, automatic PMI when LTV > 80% and pmi_rate is provided, and the exact choice between annual tax and tax-rate inputs. No contradiction with annotations.
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 dense but efficient, with every sentence earning its place. It front-loads the core purpose, then immediately covers defaults and conditional parameters in a compact, readable structure.
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 10-parameter tool with no output schema, the description covers the output format, defaults, and conditional inputs well. It falls slightly short on edge cases: what happens if neither property tax parameter is supplied, if both down_payment and down_payment_percent are supplied, or if pmi_rate is omitted. These are minor but not explicitly addressed.
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?
With only 40% schema description coverage, the description compensates strongly: it explains mutual exclusivity of down_payment/down_payment_percent, the 20% default, the property_tax_annual vs property_tax_rate choice, and the automatic PMI condition. It also clarifies that HOA and insurance are part of the breakdown, adding meaning beyond 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 a specific verb and resource: 'Local-only mortgage payment calculator. Returns a full PITI breakdown...' It clearly specifies the computed outputs and distinguishes this from sibling tools like homes_calculate_affordability by emphasizing PITI and total interest.
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 provides clear operational context with 'Local-only' and 'No network call,' and gives explicit either/or rules for down_payment and property tax inputs, plus PMI conditions. It does not explicitly name a sibling alternative such as homes_calculate_affordability, so exclusion of alternatives is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_compare_propertiesCompare homes.com properties side-by-sideARead-onlyIdempotent
Fetch 2 or more homes.com properties and align their facts side-by-side. Each target supplies a url — the full homes.com property URL (e.g. from a homes_search_properties result's url field). Returns the full per-property record (with server-side extracted_features, hoa_monthly_usd, days_on_market, price_drop_*, lot_size_sqft + the derived lot_size_acres, and portal_url_hyperlink). Per-target errors are captured per-row — one bad target will not fail the whole call. Calls are concurrent. The raw description is omitted by default; pass include_description: true to keep the marketing prose. listing_agent omits the agent's telephone/email unless include_agent_contact: true. The cross-row summary table duplicates per-property fields (~30% of response weight); it is OPT-IN via include_summary: true.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact strips image/avatar URLs from the response; "full" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs. | |
| targets | Yes | Array of 2–8 properties to compare | |
| include_summary | No | When true, also emit a cross-row `summary` table aligned by field. Default false — the per-row records already carry every summary field, so the table is redundant context weight unless explicitly requested (#18). | |
| include_description | No | When true, include the raw listing `description` marketing prose on each per-property record. Default false. | |
| include_agent_contact | No | When true, include the listing agent's `telephone` and `email` on `listing_agent`. Default false — name, job title, profile url and brokerage are returned without the contact details. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint, openWorldHint, idempotentHint) cover the safety profile, and the description adds substantial behavior beyond that: per-target error isolation ('one bad target will not fail the whole call'), concurrent execution, default omission of description/agent contact, and the ~30% response-weight rationale for the opt-in summary. This is exactly the kind of non-obvious runtime behavior an agent needs before calling.
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?
Dense but every sentence earns its place: purpose first, then input requirement, return fields, error/concurrency semantics, then the three opt-in behaviors in a logical flow. The field list and opt-in explanations would normally be redundant with an output schema, but since none exists, they carry necessary information rather than padding.
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 and no nested objects, the description carries the full burden of explaining the return shape — and it delivers: the specific per-property fields, per-row error behavior, concurrency, and all three opt-in toggles are disclosed. The `view` parameter's response-shape semantics live in the schema (100% coverage), so nothing an agent needs to call correctly is missing.
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 baseline is 3; the description lifts it by adding cross-tool meaning for `url` (sourced from homes_search_properties) and behavioral rationale for the opt-in flags (what the 'description' prose is, which agent fields are withheld, why summary is redundant). It doesn't reach 5 because the schema already documents defaults and effects precisely, leaving the description to add context rather than essential meaning.
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?
Opens with a specific verb+resource: 'Fetch 2 or more homes.com properties and align their facts side-by-side.' The side-by-side comparison scope plus the 2+ count requirement distinguishes it from homes_get_property (single property) and homes_bulk_get (bulk fetch without alignment), so the purpose is unambiguous.
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?
Clear context: the tool is for comparing 2–8 properties, and the input guidance ('full homes.com property URL, e.g. from a homes_search_properties result's url field') actively routes agents to the correct sibling as the data source. However, there is no explicit when-not-to-use or named alternative for single-property lookups (homes_get_property) or bulk fetch (homes_bulk_get), so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_estimate_rent_vs_buyProject cumulative buy-vs-rent cost over N yearsARead-onlyIdempotent
Project the cumulative cost of buying a home versus renting a comparable place over N years. Accounts for down payment, closing costs, monthly PITI, maintenance (~1%/yr default), appreciation (~3%/yr default), rent growth (~3%/yr default), and the opportunity cost of the down payment + closing costs (renter invests it at investment_return_rate, default 6%/yr). P&I stops once the loan term ends. Each year is the buyer's net position if they sold that year (cash out minus equity) versus the renter's net cost, so break-even year is independent of the horizon. Returns year-by-year cumulative net costs, break-even year, and the net difference at horizon (default horizon 7y). No network — pure local math. Same math contract as zillow_estimate_rent_vs_buy. NOTE: caller must supply monthly_rent — homes.com does not publish rental estimates anywhere on its consumer site (no rent_zestimate analogue, no comparable-rentals endpoint). For a rent estimate to plug in here, use zillow_get_property (its rent_zestimate field) or redfin_get_comparable_rentals.
| Name | Required | Description | Default |
|---|---|---|---|
| home_price | Yes | ||
| hoa_monthly | No | ||
| down_payment | Yes | ||
| monthly_rent | Yes | ||
| horizon_years | No | ||
| interest_rate | Yes | ||
| loan_term_years | No | ||
| insurance_annual | No | ||
| maintenance_rate | No | ||
| rent_growth_rate | No | ||
| appreciation_rate | No | ||
| closing_cost_rate | No | ||
| property_tax_rate | No | ||
| selling_cost_rate | No | ||
| investment_return_rate | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond the readOnly and idempotent annotations: it is pure local math, P&I stops at loan term end, each year reflects the buyer's net position if sold, break-even independence from the horizon, and enumerated defaults (maintenance ~1%, appreciation ~3%, rent growth ~3%, investment return 6%, horizon 7y). This gives an agent an accurate mental model of the calculation and its outputs without contradiction.
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 dense and front-loaded with the core purpose, and every sentence delivers useful information. The NOTE about monthly_rent is well-placed. It is slightly long and runs as one block of text, which could be improved with bullet points or clearer paragraph breaks, but it remains efficient for the complexity of the tool.
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 complexity (15 parameters, no output schema), the description is quite complete: it explains the model, defaults, return values, and a critical external dependency. Minor gaps remain—units for rates and exact handling of omitted parameters are not stated—but overall the agent can invoke this tool correctly after reading the description.
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?
With 0% schema coverage, the description carries the parameter-documentation burden. It names many parameters (down payment, closing costs, monthly PITI, maintenance, appreciation, rent growth, investment return) and supplies defaults. It also explicitly flags monthly_rent as required. However, it omits some parameters (hoa_monthly, selling_cost_rate, loan_term_years) and does not clarify whether rates are fractions or percentages.
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 opens with a specific verb and resource: 'Project the cumulative cost of buying a home versus renting a comparable place over N years.' It precisely defines the tool's scope and adds model details, and the mention of 'Same math contract as zillow_estimate_rent_vs_buy' plus 'No network — pure local math' clearly separates it from calculator/compare siblings like homes_calculate_mortgage and homes_compare_properties.
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 explicit usage context: it states a hard prerequisite ('caller must supply monthly_rent'), explains why (homes.com does not publish rental estimates), and routes the agent to alternative sources for that input. It does not explicitly state when not to use this tool versus other siblings, but the prerequisite callout provides clear guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_by_addressResolve a street address to a homes.com property URLARead-onlyIdempotent
Resolve a US street address to its canonical homes.com property URL + opaque property hash. Pass address (street), city, state, and optional zip. Walks three rungs: first the structured smartsearch typeahead (POST /routes/res/consumer/smartsearch/autocomplete/ — the primary rung, the same address-suggest API homes.com's search box fires, returning the real /property/// URL directly), then a slug-routed page (parsing the embedded Schema.org JSON-LD — both the CollectionPage search-results shape and the single-RealEstateListing detail redirect), and finally a city/zip search page with street-token fuzzy match. Every candidate is verified against the input with a whole-token street match (plus a unit guard so a multi-unit building resolves to the exact unit, not a neighbour). Optional price_min / price_max (USD) bound ONLY the city/zip search-fallback rung — when an address is ambiguous or the typeahead misses and you know the listing's rough price, this narrows the area search (homes.com ?price-min=/?price-max= filter) so the fuzzy matcher picks from fewer, more-relevant candidates; omit for unchanged unbounded behaviour. Returns { url, property_hash, street_address, matched_via, resolved: true } on success — matched_via is 'typeahead' for the structured-API hit, 'slug' for a direct routing hit, 'search_fallback' for the search-page fuzzy match — or { resolved: false, error: 'no listing found' } when homes.com has no match (so the higher-level unified canonical-URL lookup can degrade gracefully). A retryable { resolved: false, status: 'timeout' | 'blocked', retryable: true } means homes.com never answered (bridge timeout) or refused (sign-in / AWS WAF challenge / HTTP 403-429) — NOT a confirmed miss; for blocked, have the user open homes.com and clear the challenge, then retry. KNOWN FAILURE MODE: rural addresses and very-new construction can still miss because homes.com hasn't indexed them yet. Compare the returned street_address against your input to confirm. For larger batches (≥ 3 addresses), prefer homes_resolve_addresses. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| zip | No | ZIP code (optional; improves precision when present). | |
| city | Yes | City (e.g. "Lake Lure"). | |
| state | Yes | 2-letter US state code (e.g. "NC"). | |
| address | Yes | Street address (e.g. "126 Sleeping Bear Ln"). | |
| price_max | No | Optional upper price bound (USD). Applied ONLY to the search-fallback rung (homes.com's `?price-max=` filter). Useful when an address is ambiguous or the typeahead misses and you know the listing's rough price — improves disambiguation/recall. Omit for unbounded fallback. | |
| price_min | No | Optional lower price bound (USD). Applied ONLY to the city/zip search-fallback rung — bounds that area search with homes.com's `?price-min=` filter so an ambiguous address resolves against a narrower candidate set. Ignored by the typeahead/slug rungs (a single known address has nothing to narrow). Omit for unbounded fallback. Must be <= price_max when both are given. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
ReadOnlyHint, OpenWorldHint, and IdempotentHint already signal safety, and the description adds substantial behavioral context beyond those annotations: the three resolution rungs, exact return shapes, retryable timeout/blocked states, the known failure mode for rural/new construction, and the instruction to compare the returned street_address against input. Nothing contradicts the annotations.
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?
Although long, every sentence earns its place: purpose is front-loaded, followed by mechanism, parameter behavior, return contracts, retry semantics, failure modes, and batching guidance. There is no filler; the density is justified by the tool's complexity and the absence of an output schema.
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 tool with no output schema, the description fully specifies success and error shapes, matched_via values, timeout/blocked semantics, known failure modes, and batch-size routing to a sibling. Nothing needed for correct invocation or result interpretation is missing.
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 baseline is 3, but the description adds meaningful semantics beyond the schema: it explains that price_min/price_max bind ONLY the city/zip search-fallback rung, clarifies how the typeahead/slug rungs ignore them, and describes the unit guard and whole-token street-match verification. This extra context helps an agent decide which parameters matter for a given resolution.
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 opens with a specific verb and resource: 'Resolve a US street address to its canonical homes.com property URL + opaque property hash.' It clearly differentiates from siblings by naming the batch alternative ('For larger batches (≥ 3 addresses), prefer homes_resolve_addresses') and by describing the multi-rung resolution mechanism, so an agent can distinguish it from search or property-lookup tools.
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 states exactly when to call this tool, when not to, and what alternative to use: 'For larger batches (≥ 3 addresses), prefer homes_resolve_addresses.' It also explains when optional parameters should be used ('when an address is ambiguous or the typeahead misses') and when they should be omitted ('Omit for unchanged unbounded behaviour').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_historyGet homes.com property + tax history (combined)ARead-onlyIdempotent
Combined history endpoint — replaces homes_get_property_history + homes_get_tax_history with a single fetch. Returns { property_id, url, listing_events, ownership_events, lien_events, events_normalized, tax_records }. Pass url — the full property detail URL. Series are [] when the listing doesn't carry that section. Cross-MCP-normalized events_normalized carries the same enum across siblings (Listed/PriceChange/Pending/Contingent/Sold/Withdrawn/Relisted/Delisted). Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | homes.com property detail URL or path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description reinforces safety while adding non-obvious behavior: series are empty arrays when absent, events_normalized uses a shared enum, and the response shape is spelled out. This goes well beyond what annotations alone provide.
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?
Four dense sentences, each earning its place: purpose, replacement guidance, return shape, empty-series behavior, and safety. Key routing information is front-loaded.
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?
Complete for a single-parameter endpoint with no output schema: it names the required input, lists all returned fields, explains empty-section behavior, and covers normalization semantics. Nothing needed to call it correctly is missing.
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 schema already documents the single url parameter. The description adds only minor emphasis ('full property detail URL') rather than meaningful new semantics, so it stays at the high-coverage baseline.
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?
States it is a combined history endpoint that fetches both property and tax history in a single call, with a clear verb and resource. It explicitly names the two sibling tools it replaces, making differentiation immediate.
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 says to use this instead of calling homes_get_property_history plus homes_get_tax_history, and tells the caller to pass the full property detail URL. The when/why guidance is unambiguous and alternative-aware.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_market_reportGet a homes.com market report for a locationARead-onlyIdempotent
Fetch homes.com's recently-sold listings for a city/ZIP/neighborhood and derive a market summary: count, median sale price, and average $/sqft across the sample. Pass location — free-text (e.g. 'Brooklyn, NY', '30311'). Returns { region, slug, sold_summary, sample_sold }. Note: homes.com's sold page typically returns ~40 recent listings — this is a sample-based summary, not an exhaustive market index. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact strips image/avatar URLs from the response; "full" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs. | |
| location | Yes | Free-text location: city, ZIP, neighborhood |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already declaring readOnly/openWorld/idempotent, the description adds meaningful behavioral detail: the report is sample-based with typically ~40 recent listings and is not an exhaustive market index. It also discloses the return shape and explicitly says 'Read-only', reinforcing the annotations.
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 compact and front-loaded: purpose first, then parameter guidance, return shape, and a critical caveat. Every sentence carries information and none is wasted.
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 two-parameter tool with no output schema, the description is complete: it explains what the tool does, how to pass location, what the response will look like, and the important sample-size limitation. Nothing an agent needs to call it correctly is missing.
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 baseline is 3. The description adds a couple of location examples but otherwise restates what the schema already says; the `view` parameter is left entirely to 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 opens with a specific verb-resource pair: 'Fetch homes.com's recently-sold listings' and 'derive a market summary', which is unambiguous. The market-report aggregation purpose is clearly distinct from sibling tools like property lookup or search.
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 makes the intended use clear: pass a city/ZIP/neighborhood to get a market summary. It does not explicitly name alternatives or exclusions, so it falls short of the 'when-not-to-use' standard, but the context is strong enough to guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_nearby_listingsGet nearby homes.com listings for a propertyARead-onlyIdempotent
Scrape the nearby-links section of a homes.com detail page (the tabbed list of <ul id="nb-Property"> near the bottom of the page) and return the nearby active listings. Pass url (the property whose neighborhood to inspect). By default returns the For Sale tab; pass include_rentals: true to also include the Rentals tab. Optional limit caps the count. Returns { property_id, url, count, listings: [{ property_id, url, address?, tab }] }. Note: the nearby section is a curated cross-link list, not a comparable-sales set — only URL + address are exposed (no price/beds/baths/sqft/photo). To enrich a row, call homes_get_property on its url. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | homes.com property detail URL or path. | |
| limit | No | Max nearby listings to return (default unlimited). | |
| include_rentals | No | When true, also include the Rentals tab (`<ul id="nb-property">` lowercase). Default false — For Sale tab only. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, openWorldHint, and idempotentHint, and the description adds valuable non-obvious behavior: the nearby section is a curated cross-link list, not a comparable-sales set, and only URL + address are exposed (no price/beds/baths/sqft/photo). This prevents incorrect assumptions about the data.
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 despite covering purpose, parameters, output shape, caveats, and follow-up guidance. It front-loads the core operation, then layers details logically, with no redundant or filler sentences.
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?
There is no output schema, so the description correctly provides the full return shape: { property_id, url, count, listings: [...] }. It also covers important limitations and the enrichment path, making it complete enough for an agent to select and invoke the tool correctly.
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 description coverage is 100%, so the baseline is 3. The description adds a little semantic context, such as url being 'the property whose neighborhood to inspect' and the default For Sale tab behavior, but limit and include_rentals mostly restate the schema descriptions.
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 a specific verb ('Scrape ... and return'), a precise resource (the nearby-links section of a homes.com detail page), and the expected output (nearby active listings). It clearly distinguishes this tool from siblings like homes_get_property and homes_search_properties by focusing on the curated nearby cross-link list.
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 context: it is for inspecting the nearby-links section of a given property page, with defaults and optional flags explained. It also explicitly points to homes_get_property for enriching rows, which is a helpful alternative cue, though it does not list explicit 'when not to use' scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_propertyGet homes.com property detailsARead-onlyIdempotent
Fetch a property's full homes.com record. Pass url — the full property detail URL (e.g. from a homes_search_properties result's url field). Parses the page's Schema.org JSON-LD plus DOM-side sections to return address, lat/lng, beds/baths, sqft, year built, price, status, listing agent + brokerage, highlights, estimated monthly payment, total views, Matterport tour URL, floorplan URLs, schools, HOA fee, lot_size_sqft plus the derived lot_size_acres (round(lot_size_sqft / 43560, 2); both null — never 0 — for condos and listings with no lot), parking, heating/cooling, MLS ID/source, and date posted/modified. Also returns extracted_features (lake_front, hot_tub, basement, furnished, dock, community) derived server-side from the listing description so callers don't have to keyword-parse marketing prose. Pass include_price_history: true to inline the same data homes_get_property_history returns (listing_events, ownership_events, lien_events, events_normalized) under price_history. Pass include_tax_history: true to inline homes_get_tax_history records under tax_history. Both are off by default; opting in costs nothing extra over the dedicated tools (same page fetch). The raw description is omitted by default; pass include_description: true to opt back in. listing_agent carries name / job title / profile url only; pass include_agent_contact: true for the agent's telephone and email. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | homes.com property detail URL or path (e.g. https://www.homes.com/property/3199-delmar-ln-nw-atlanta-ga/rxrzwg0kjnr32/). Required — pass the `url` field from a homes_search_properties result. | |
| view | No | Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact strips image/avatar URLs from the response; "full" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs. | |
| include_description | No | When true, include the raw listing `description` marketing prose. Default false — the structured `extracted_features` field surfaces the keywords callers usually want; the prose itself is heavy chat-history weight. | |
| include_tax_history | No | When true, inline `tax_history` records — same data `homes_get_tax_history` returns. Saves a second round trip when you need both (#27). | |
| include_agent_contact | No | When true, include the listing agent's `telephone` and `email` on `listing_agent`. Default false — name, job title, profile url and brokerage are returned without the contact details. | |
| include_price_history | No | When true, inline `price_history` (listing/ownership/lien events + events_normalized) on the response — the same data `homes_get_property_history` returns. Saves a second round trip when you need both (#27). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, it discloses the fetch/parse mechanism (Schema.org JSON-LD plus DOM sections), defaults for description/agent contact, and important edge-case behavior (lot_size_sqft and lot_size_acres are null, never 0, for condos/no-lot listings). It also states it is read-only and safe to call repeatedly, matching the annotations without contradiction.
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 long but every sentence carries information: purpose, input source, returned fields, derived fields, null semantics, opt-in flags, and cost/behavior notes. It is front-loaded with the core action before enumerating details.
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 goes beyond a simple summary by enumerating the response surface (address, lat/lng, beds/baths, schools, price history, tax history, agent contact, etc.) and boundary conditions. The `view` parameter's compact/full behavior is covered in the schema, so the description does not need to repeat 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?
Schema coverage is 100%, so the baseline is 3, but the description adds extra meaning: it explains where the `url` comes from, that `extracted_features` is derived server-side to avoid keyword parsing, and that inlining history/tax saves a round trip when both are needed. It does not add new semantics for the `view` parameter, but the schema already documents that thoroughly.
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 opening sentence 'Fetch a property's full homes.com record' names a specific verb and resource, and the rest enumerates the returned fields so there is no confusion about scope. It also ties the input to homes_search_properties output and distinguishes inline history/tax data from the dedicated sibling tools.
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 the caller exactly where to get the required `url` (from a homes_search_properties result) and how to choose opt-in flags for price history and tax history instead of calling the dedicated sibling tools. It explicitly notes both flags are off by default, that opting in costs no extra page fetch, and that the tool is safely repeatable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_property_historyGet homes.com property history (DEPRECATED — use homes_get_history)ARead-onlyIdempotent
DEPRECATED — prefer homes_get_history (combined timelines + tax) or homes_get_property({ url, include_price_history: true }). Same data, fewer round trips. Will be removed in a future major version. Three timelines for a homes.com property in one call: listing_events, ownership_events, lien_events. Also returns events_normalized mapped onto the cross-MCP enum.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | homes.com property detail URL or path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and open-world behavior. The description adds useful behavioral context: the tool returns normalized events mapped to a cross-MCP enum, will be removed in a future major version, and excludes tax history (implied by the alternative). This goes beyond the annotations without contradicting them.
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 compact and front-loaded with the most important information (deprecation and alternatives). Each sentence adds value: deprecation warning, alternative route, removal notice, return payload summary, and normalization 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?
With no output schema, the description compensates by naming the returned fields and the normalized enum behavior. It does not spell out the exact shape of each timeline event, but for a deprecated tool the primary need is routing to alternatives, which is fully covered.
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 single parameter `url` is already fully described in the schema as 'homes.com property detail URL or path.' The description adds no extra semantic detail about the parameter, so a baseline score of 3 is appropriate given 100% schema coverage.
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 homes.com property history with three concrete timelines: listing_events, ownership_events, and lien_events. It also distinguishes this from siblings by naming the preferred alternatives and stating that the tool is deprecated.
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 tells the agent to prefer `homes_get_history` or `homes_get_property` with include_price_history, citing 'same data, fewer round trips.' This provides clear routing guidance and makes the usage context unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_property_photosGet homes.com property photo galleryARead-onlyIdempotent
The full photo gallery for a homes.com listing. homes.com's JSON-LD only exposes one primary image, so this tool scrapes every tag on the property detail page and filters to the homes.com CDN. Pass url — the full homes.com property URL or path (e.g. from a homes_search_properties result's url field). Returns { property_id, url, count, photos: [{ url, position, alt? }] }. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | homes.com property detail URL or path. Required — pass the `url` field from a homes_search_properties result. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description adds valuable behavioral detail: it scrapes every <img> tag and filters to the homes.com CDN, explaining the underlying mechanism and the exact return structure. This goes beyond the annotations and is fully transparent.
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 three sentences, front-loaded with the core purpose, followed by rationale and usage/return details. It is efficient without being terse, and every sentence contributes meaning.
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 lacking an output schema, the description explicitly defines the return object structure, input requirements, and the tool's behavior. An agent has everything needed to call it correctly and interpret the result.
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 single parameter `url` is fully documented in the schema (100% coverage), and the description reinforces its usage with a concrete source (homes_search_properties result). This adds practical context beyond the schema's basic type/description.
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: retrieving the full photo gallery for a homes.com listing. It distinguishes itself by explaining the limitation of JSON-LD (only one primary image) and the scraping approach, which separates it from other property-related siblings.
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 provides explicit usage guidance: pass the `url` from a homes_search_properties result. It also notes the tool is read-only and safe to call repeatedly, giving context for when to use it. It doesn't explicitly exclude alternatives, but the specificity is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_saved_homesGet the signed-in user's saved homes on homes.comARead-onlyIdempotent
The signed-in user's saved (favorited) homes on homes.com. Scrapes /customer/dashboard/favorites/. Returns { count, homes: [{ property_id, url, address?, price?, beds?, baths?, sqft?, status? }] }. REQUIRES the user to be signed into homes.com in their browser tab — if not, the request throws SessionNotAuthenticatedError. Card fields (price/beds/baths/sqft) are best-effort DOM scrapes — they may be missing on some card variants; treat absence as 'not surfaced on the saved-homes card', not 'no value'. Call homes_get_property(url) per row when you need the canonical record. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and idempotentHint annotations, the description reveals that the tool scrapes the favorites page, that field values are best-effort DOM extractions that may be missing, and what missing values mean. It also specifies the exact error condition for unauthenticated sessions.
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 dense but every sentence earns its place: purpose, source, return shape, auth requirement, data-quality caveats, and cross-reference to a sibling. Key operational constraints are front-loaded.
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, read-only tool with no output schema, the description fully equips the agent: what it returns, what may be missing, what errors to expect, and how to get canonical records. Nothing essential is left out.
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?
With zero parameters, the schema leaves no parameter semantics to clarify; the baseline is 4. The description still adds useful context about implicit inputs: the signed-in user's session and browser tab.
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 a specific verb and resource: retrieving the signed-in user's saved homes from homes.com's /customer/dashboard/favorites/. It clearly distinguishes itself from the sibling saved_searches tool and references homes_get_property as a complementary tool for canonical 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?
It explicitly states the user must be signed in, warns that the call throws SessionNotAuthenticatedError otherwise, and advises when to switch to homes_get_property per row for canonical data. This gives the agent concrete conditions for correct use versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_saved_searchesGet the signed-in user's saved searches on homes.comARead-onlyIdempotent
The signed-in user's saved searches on homes.com. Scrapes /customer/dashboard/saved-searches/. Returns { count, searches: [{ name?, url, filters? }] }. REQUIRES the user to be signed into homes.com in their browser tab — if not, the request throws SessionNotAuthenticatedError. name and filters are DOM-scraped from the saved-search card; absence means homes.com didn't render them, not that the search has none. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations' readOnly and idempotent hints, the description discloses that the tool scrapes the saved-searches page, requires an authenticated browser session, throws a specific error when not signed in, and that missing name/filters fields are a scraping artifact rather than an absence of data. This goes well beyond the structured metadata.
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 four sentences with no wasted words. It front-loads the core purpose, then adds the endpoint, return shape, authentication caveat, missing-field semantics, and safety note. Every sentence earns its place.
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, read-only tool, the description is complete: it provides the return format, the authentication prerequisite, the error case, the caveat about DOM scraping, and the fact that it can be called repeatedly. The annotations already supply safety hints, and the description fills in all agent-relevant behavior.
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?
There are zero parameters, so the input schema has nothing to document. The description adds valuable context by specifying the return shape, `{ count, searches: [{ name?, url, filters? }] }`, but this is output information rather than parameter explanation; the zero-parameter baseline of 4 is appropriate.
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 names a specific verb and resource: it 'gets the signed-in user's saved searches on homes.com' and specifies the exact endpoint scraped. This clearly distinguishes it from sibling tools like homes_get_saved_homes, which handles saved homes rather than saved searches.
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 context for use: it requires the user to be signed into homes.com in their browser tab dove altrimenti it throws SessionNotAuthenticatedError, and it is safe to call repeatedly. It does not explicitly name alternative tools or say when not to use it, so it stops short of full guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_session_contextList all registered Homes sessionsARead-onlyIdempotent
List every registered account label plus the current active_session_id. When none are registered, sessions is empty and active_session_id is null. The registry is a label only: it does not change which Homes.com account requests use. Every homes tool call goes through whichever browser tab the fetchproxy extension is signed into; to read a different account, sign that tab into it.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, but the description adds meaningful context beyond those: it clarifies that the tool does not change account usage, and it explains the external dependency on the fetchproxy browser tab sign-in. This additional behavioral insight (side-effect-free nature and account routing mechanism) is exactly what the agent needs to safely invoke the 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?
Three sentences with zero waste. The primary purpose is front-loaded, followed by the edge case and the crucial account-routing caveat. Every sentence earns its place, and the structure is immediately scannable.
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 parameterless, read-only tool with no output schema, the description is fully complete. It covers the return content, the empty-case behavior, and the operational impact on other Homes tools (account selection via browser tab). An agent can call this correctly with no further guidance.
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 tool has zero parameters, so the input schema is trivially complete (100% coverage). The description goes beyond parameter semantics by explaining the output structure (sessions list and active_session_id, including empty/null states). Per the baseline for 0 params, a 4 is appropriate; nothing more is needed for parameters themselves.
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 uses a specific verb ('List'), names the resource ('every registered account label plus the current active_session_id'), and specifies the edge case (empty sessions, null active_session_id). This clearly differentiates it from siblings like homes_set_active_session or homes_register_session, which perform mutations. The purpose is unambiguous.
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 provides clear context on when to use this tool: to view registered sessions without affecting which account is used. It explains that listings are label-only and that account selection is determined by the browser tab the fetchproxy extension is signed into, with instructions to switch tabs to change accounts. However, it does not explicitly name alternative tools or state 'when not to use', so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_get_tax_historyGet homes.com property tax history (DEPRECATED — use homes_get_history)ARead-onlyIdempotent
DEPRECATED — prefer homes_get_history (combined timelines + tax) or homes_get_property({ url, include_tax_history: true }). Same data, fewer round trips; note that homes_get_history returns the tax array as tax_records (not records). Will be removed in a future major version. Year-by-year property-tax records: tax paid, total assessed value, land/improvement split.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | homes.com property detail URL or path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, open-world, and idempotent hints, so the safety profile is covered. The description adds behavior beyond those hints: deprecation status, planned removal, equivalence to alternatives, and the field-name mismatch (`tax_records` vs `records`). It does not contradict the annotations.
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 deprecation warning is front-loaded so an agent immediately knows not to prefer this tool. Every sentence earns its place: alternatives, removal timeline, field-name warning, and a one-line summary of the return data. There is no filler or redundant restatement of the schema.
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 deprecated read-only tool with one fully documented parameter, the description is nearly complete: it states purpose, alternatives, deprecation, output fields, and the record-name difference. It does not give exact JSON key names for each output field, but that is a minor gap given the low complexity and strong schema coverage.
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 covers the only parameter, `url`, with a clear description, so the schema carries the full burden. The tool description does not add parameter-specific detail beyond mentioning `url` in the replacement call, which is not needed for understanding this tool's single parameter. Baseline 3 applies.
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 identifies the resource as 'year-by-year property-tax records' and names the exact fields returned (tax paid, total assessed value, land/improvement split). It also distinguishes this tool from siblings by naming the replacement paths (`homes_get_history`, `homes_get_property`), so an agent knows precisely what it does and how it fits in the family.
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 opens with an explicit deprecation and gives concrete alternatives: use `homes_get_history` or `homes_get_property({ include_tax_history: true })`. It explains why (same data, fewer round trips), notes the future removal, and even flags the `tax_records` vs `records` naming difference, leaving no ambiguity about when to avoid this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_healthcheckVerify the fetchproxy bridge end-to-endARead-onlyIdempotent
Round-trips a small public www.homes.com URL (/robots.txt) through the fetchproxy bridge and returns diagnostics: the bridge's role (host/peer/null), port, version, the extension link (linked / pair pending / not attached / never answered), the elapsed round-trip time, and a plain-English hint distinguishing 'bridge never came up' from 'extension not connected' from 'real www.homes.com-side problem'. Read-only, no auth required. Call this when a real tool fails and you want to know which hop broke.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is known. The description adds valuable behavioral context beyond that: it explains the round-trip mechanism, lists the specific diagnostics returned (role, port, version, extension link, elapsed time, plain-English hint), and notes 'no auth required.' It also clarifies the failure-mode distinctions, which is useful for interpreting results. This goes beyond the annotations without contradicting them.
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 paragraph that front-loads the core action and then enumerates the diagnostic outputs. The first sentence establishes the purpose and the second gives the usage scenario. Every sentence adds meaningful information without redundancy. It is dense but not bloated, making it an efficient and effective description.
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 parameterless healthcheck tool with no output schema, the description provides all necessary context: it states what it does, what it returns (including a list of specific diagnostics), when to call it, and its safety (read-only, no auth). The plain-English hint distinction further clarifies possible outcomes. Nothing essential is missing for an agent to decide when and how to invoke it correctly.
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 tool has zero parameters, so the baseline is 4 per the instructions. The empty input schema is fully covered (100%), and the description doesn't need to explain parameters. Since there are no parameters to describe, this dimension is inherently satisfied at the baseline level.
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 a specific action: 'Round-trips a small public www.homes.com URL (/robots.txt) through the fetchproxy bridge and returns diagnostics.' It specifies the exact resource and the diagnostic purpose, which distinguishes it from the property search, mortgage, and other home-related siblings. The verb 'round-trips' and the diagnostic focus make its function unmistakable.
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 when to call: 'Call this when a real tool fails and you want to know which hop broke.' This gives a clear context for use. It does not, however, mention when not to use it or name specific alternative tools, but the sibling list makes it obvious this is for troubleshooting rather than normal operations. The absence of explicit alternatives is a minor gap, so a 4 is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_register_sessionRegister a signed-in Homes sessionAIdempotent
Record (or refresh) a note of which Homes.com account the signed-in browser tab belongs to, keyed by account_identity. Re-registering the same identity updates the existing entry. Returns a session_id; pass mark_active: true to mark it as the current account in the same call. The registry is a label only: it does not change which Homes.com account requests use. Every homes tool call goes through whichever browser tab the fetchproxy extension is signed into; to read a different account, sign that tab into it.
| Name | Required | Description | Default |
|---|---|---|---|
| mark_active | No | When true, immediately make the newly-registered session the active one. | |
| auth_expires_at | No | Optional ISO timestamp at which the session expires. | |
| account_identity | Yes | Caller-supplied identifier for the signed-in account (typically the saved-account email). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=true), the description discloses key behaviors: re-registering the same identity updates the existing entry, returning a session_id, supporting mark_active to set active in the same call, and explicitly clarifying the registry is a label only and does not affect which account requests use. This is rich, non-obvious context.
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 dense but every sentence contributes: purpose, idempotent update behavior, return value and option, relationship to actual account routing, and cross-tab sign-in context. It is front-loaded with the core purpose and contains no filler.
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 3-parameter tool with no output schema, the description provides everything an agent needs: what the tool does, the return value, the active flag, idempotency, and the crucial caveat that it doesn't switch accounts. It also clarifies the integration boundary with the fetchproxy extension context. No significant missing information.
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 schema already documents all parameters. The description adds extra meaning by explaining `account_identity` is the key for the registry and that `mark_active` can be set in the same call. It does not mention `auth_expires_at`, but the schema covers it, so this is more than adequate.
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 a specific action (record or refresh a session registration), the resource (Homes account association with the signed-in browser tab), and the keying field `account_identity`. It also clarifies that registration is a label and does not change which account requests use, distinguishing it from siblings like homes_set_active_session.
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 clearly explains when to use the tool: to record or refresh which Homes.com account a tab is signed into. It provides an explicit exclusion by noting the registry does not change account routing, and advises signing the tab into another account to read a different account. It does not explicitly name the alternative tool `homes_set_active_session`, but the guidance is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_resolve_addressesBulk-resolve street addresses to homes.com property URLsARead-onlyIdempotent
Resolve up to 100 street addresses to canonical homes.com property URLs + opaque property hashes in one call. Pass addresses: [{ address, city, state, zip? }, ...]. Fans out to the same rungs homes_get_by_address runs (structured smartsearch typeahead → slug → city/zip search fallback), verifying each candidate with the same whole-token street + unit match. Per-row outcomes parallel homes_get_by_address (with property_hash renamed to property_id here so the field name lines up with homes_bulk_get): { resolved: true, url, property_id, street_address, matched_via } on success — matched_via is 'typeahead', 'slug', or 'search_fallback' — { resolved: false, error } otherwise; one bad row won't fail the whole call. Each row's status is resolved, unresolved, pending (deadline reached — retry it) or blocked (homes.com returned a sign-in / AWS WAF challenge or HTTP 403/429 — not a miss; clear the challenge in the browser and retry). Results preserve input order. Use this instead of looping homes_get_by_address for any batch ≥ 3. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| addresses | Yes | Array of address records to resolve (1–100 per call). Each must include street `address`, `city`, and 2-letter `state`; `zip` is optional but improves precision. Optional per-row `price_min` / `price_max` (USD) bound that row's city/zip search-fallback rung — same semantics as `homes_get_by_address` (must be non-negative, min <= max; an invalid band fails only that row). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, and idempotent hints. The description goes far beyond, detailing fan-out rungs, per-row statuses (resolved/unresolved/pending/blocked), challenge handling for HTTP 403/429, preservation of input order, and that one bad row won't fail the whole call. No contradiction with annotations.
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 long but information-dense: every sentence covers a distinct concern (input format, fan-out behavior, output shape, statuses, retry guidance, ordering, usage threshold, safety). It front-loads the core purpose and keeps related details grouped.
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 fully carries the output contract: it specifies success/failure row shapes, matched_via enum values, status enum meanings, and error handling. It also covers input constraints, ordering, and when to use the tool, making it complete for a complex bulk operation.
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 description coverage is 100% and already documents the addresses array shape, optional zip, and price_min/price_max semantics. The description repeats the shape briefly but adds no meaning beyond what the schema provides, so baseline 3 is appropriate.
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?
States a specific verb ('Resolve'), resource ('street addresses to canonical homes.com property URLs'), and scale ('up to 100'). It clearly distinguishes itself from sibling homes_get_by_address by being the bulk counterpart and mentions the sibling by name.
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 directs when to use this tool: 'Use this instead of looping `homes_get_by_address` for any batch ≥ 3.' Also explains fallback behavior and per-row outcomes, so an agent knows when this tool is appropriate versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_search_propertiesSearch homes.com listingsARead-onlyIdempotent
Search homes.com listings by free-text location (city, ZIP, neighborhood). Optionally filter by property_type (single_family/condo/townhouse/land/mobile/multi_family), listing_type (for_sale/sold/for_rent/open_houses/new_construction), and sort (newest). Slugifies the location into homes.com's URL routing (e.g. 'Atlanta, GA' + condo + for_sale → /atlanta-ga/condos-for-sale/). Parses the embedded Schema.org JSON-LD to return each listing's address, price, beds/baths, sqft, primary photo, listing agent + brokerage, and the homes.com property URL. KNOWN CAP: homes.com server-renders ~40 listings per page; the response carries truncated: true + total_estimated when the market has more. To enumerate a busy market, price-band or sub-area your search until each segment fits under the cap. Read-only; safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort order. Only "newest" is currently supported. | |
| view | No | Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact strips image/avatar URLs from the response; "full" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs. | |
| limit | No | Max listings to return (default 40, which is also the homes.com SSR page size). Passing >40 will still cap at the page size; the response will set `truncated: true` and `total_estimated` to homes.com's reported total. | |
| location | Yes | Free-text location: city, ZIP, neighborhood (e.g. "Atlanta, GA", "Brooklyn, NY", "30311", "Park Slope") | |
| price_max | No | Upper price bound in USD (inclusive). Emitted as homes.com's `?price-max=` filter. Pair with price_min to band a busy market under the ~40-listing SSR cap. | |
| price_min | No | Lower price bound in USD (inclusive). Emitted as homes.com's `?price-min=` filter. Composes with property_type / listing_type. Must be <= price_max when both are given. | |
| listing_type | No | Search axis. Defaults to for_sale. "sold" returns recently-sold listings (useful for market context). "for_rent" returns rentals. "open_houses" returns listings with scheduled open houses. "new_construction" returns builder listings under /new-homes/. | |
| property_type | No | Restrict to a specific homes.com property type. Composes with listing_type. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent/openWorld annotations, the description discloses significant behavioral traits: it slugifies the location into homes.com's URL routing, parses embedded Schema.org JSON-LD, and exposes the known ~40-listing server-render cap with `truncated: true` and `total_estimated` flags. This gives the agent exactly the kind of nuance needed to anticipate result truncation and plan enumeration. It also confirms the read-only nature expectations, matching the annotations.
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 front-loaded with the purpose, then filters, then behavioral details. Every sentence contributes meaningful information about filtering, slugification, parsing, or the cap. It is somewhat longer than necessary—'Read-only; safe to call repeatedly' partly duplicates the annotations—but the additional structured details are dense and useful. Overall it is appropriately sized for the tool's complexity.
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 covers return values explicitly: parsed listing fields (address, price, beds/baths, sqft, primary photo, listing agent + brokerage, property URL) and the `truncated`/`total_estimated` flags. It also addresses the operational context of searching busy markets with a clear mitigation strategy. Combined with fully documented parameters and annotations, nothing critical is left for an agent to infer.
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 covers all 8 parameters with descriptions, meeting the 100% coverage baseline. The tool description adds value beyond the schema by explaining that location is slugified (e.g., 'Atlanta, GA' → /atlanta-ga/condos-for-sale/), that price_min/price_max should be paired to band a busy market under the cap, and that parameters compose (property_type + listing_type). This enriches parameter understanding rather than merely repeating schema text.
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 opens with a concrete verb-plus-resource statement: 'Search homes.com listings by free-text location (city, ZIP, neighborhood).' This clearly distinguishes the tool from siblings like homes_get_property (which targets a specific listing) and homes_get_by_address (which resolves exact addresses), and it states the core mechanism. It then names the optional filters, making the purpose unambiguous.
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 conveys clear context for when to use the tool: to search listings by a free-text location with filtering options. It also gives practical usage guidance around the 40-listing cap ('price-band or sub-area your search until each segment fits under the cap'). However, it does not explicitly route agents away from the tool toward siblings like homes_get_property for specific-listing lookups, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homes_set_active_sessionSet the active Homes sessionAIdempotent
Mark a previously registered session_id as the current account label, for your own bookkeeping across a conversation. The registry is a label only: it does not change which Homes.com account requests use. Every homes tool call goes through whichever browser tab the fetchproxy extension is signed into; to read a different account, sign that tab into it.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session id to make active. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and readOnlyHint=false, so the description's disclosure of being a label-only registry adds context without redundancy. It further explains the broader account-routing behavior through the browser tab/fetchproxy extension, which is not in the annotations and clarifies side effects.
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 compact, opens with the core action, and every sentence earns its place: the purpose, the label-only caveat, and the account-routing alternative. No filler or redundant restatement of the tool name.
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 single-parameter, no-output-schema tool, the description fully covers what the tool does, its non-effect on account selection, and the browser tab behavior needed to understand its impact. Agents have all necessary context to call it correctly without ambiguity.
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. The description adds semantic meaning beyond the schema by requiring the session_id to be 'previously registered' (constraint not in the schema) and explains its role as a current label, which clarifies the parameter's purpose in the workflow.
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 uses a specific verb ('Mark') with a clear resource ('previously registered session_id') and states the purpose ('current account label... for your own bookkeeping'). It distinguishes itself from homes_register_session (which registers) and homes_get_session_context (which reads) by emphasizing the 'label only' nature, so an agent can tell them apart.
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 when to use it ('for your own bookkeeping across a conversation'), when not to rely on it ('does not change which Homes.com account requests use'), and gives an alternative action for a different goal ('to read a different account, sign that tab into it'). This provides clear when/when-not and alternative routing.
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.
3 tool updates
v2.1.5- Changed
homes_bulk_get1 field changed- added
Input schema / properties / include_agent_contactAdded value: +{ + "default": false, + "description": "When true, include the listing agent's `telephone` and `email` on `listing_agent`. Default false — name, job title, profile url and brokerage are returned without the contact details.", + "type": "boolean" +}
- Changed
homes_compare_properties1 field changed- added
Input schema / properties / include_agent_contactAdded value: +{ + "default": false, + "description": "When true, include the listing agent's `telephone` and `email` on `listing_agent`. Default false — name, job title, profile url and brokerage are returned without the contact details.", + "type": "boolean" +}
- Changed
homes_get_property1 field changed- added
Input schema / properties / include_agent_contactAdded value: +{ + "default": false, + "description": "When true, include the listing agent's `telephone` and `email` on `listing_agent`. Default false — name, job title, profile url and brokerage are returned without the contact details.", + "type": "boolean" +}
1 tool update
v2.1.3- Changed
homes_estimate_rent_vs_buy2 fields changed- added
Input schema / properties / monthly_rent / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / monthly_rent / minimumRemoved value: -0
21 tool updates
v2.0.0- Changed
homes_bulk_get1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_calculate_affordability1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_calculate_mortgage1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_compare_properties1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_estimate_rent_vs_buy1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_by_address1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_history1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_market_report1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_nearby_listings1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_property1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_property_history1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_property_photos1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_saved_homes1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_saved_searches1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_session_context1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_get_tax_history1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_healthcheck1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_register_session1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_resolve_addresses1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_search_properties1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
homes_set_active_session1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
5 tool updates
v1.4.1- Changed
homes_bulk_get1 field changed- added
Input schema / properties / viewAdded value: +{ + "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact strips image/avatar URLs from the response; \"full\" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs.", + "enum": [ + "compact", + "full" + ], + "type": "string" +}
- Changed
homes_compare_properties1 field changed- added
Input schema / properties / viewAdded value: +{ + "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact strips image/avatar URLs from the response; \"full\" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs.", + "enum": [ + "compact", + "full" + ], + "type": "string" +}
- Changed
homes_get_market_report1 field changed- added
Input schema / properties / viewAdded value: +{ + "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact strips image/avatar URLs from the response; \"full\" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs.", + "enum": [ + "compact", + "full" + ], + "type": "string" +}
- Changed
homes_get_property1 field changed- added
Input schema / properties / viewAdded value: +{ + "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact strips image/avatar URLs from the response; \"full\" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs.", + "enum": [ + "compact", + "full" + ], + "type": "string" +}
- Changed
homes_search_properties1 field changed- added
Input schema / properties / viewAdded value: +{ + "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact strips image/avatar URLs from the response; \"full\" returns Homes.com's payload untouched. No field projection: this server has no verified record of which Homes.com fields matter, and inventing one would risk dropping a field a caller needs.", + "enum": [ + "compact", + "full" + ], + "type": "string" +}
21 tool updates
v1.1.1- First observed
homes_bulk_get - First observed
homes_calculate_affordability - First observed
homes_calculate_mortgage - First observed
homes_compare_properties - First observed
homes_estimate_rent_vs_buy - First observed
homes_get_by_address - First observed
homes_get_history - First observed
homes_get_market_report - First observed
homes_get_nearby_listings - First observed
homes_get_property - First observed
homes_get_property_history - First observed
homes_get_property_photos - First observed
homes_get_saved_homes - First observed
homes_get_saved_searches - First observed
homes_get_session_context - First observed
homes_get_tax_history - First observed
homes_healthcheck - First observed
homes_register_session - First observed
homes_resolve_addresses - First observed
homes_search_properties - First observed
homes_set_active_session
TDQS
Scored across 21 tools
There is meaningful overlap among the deprecated history/tax tools, the combined homes_get_history tool, and homes_get_property's include flags, which creates multiple ways to fetch the same data. Batch variants like homes_compare_properties and homes_bulk_get also overlap, though strong deprecation notes and usage guidance help agents choose correctly.
Tool names consistently follow homes_<verb>_<noun> with snake_case throughout, and read operations mostly use the homes_get_* pattern. Minor deviations like homes_bulk_get, homes_healthcheck, and homes_get_by_address break the pattern slightly but remain readable and predictable.
At 21 tools, the server sits in the heavy range, especially with several calculators, session-management tools, and redundant deprecated endpoints bundled alongside the core property data tools. The count is not unreasonable for a broad real-estate MCP, but it feels somewhat over-scoped rather than tightly focused.
The core homes.com read model is well covered: search, property details, photos, history, tax, nearby listings, market reports, saved homes/searches, and address resolution are all present. Minor gaps exist around richer search filtering (e.g., price/beds/baths) and some listing-management capabilities, but agents can work around these.
Maintenance
Related MCP Connectors
Redfin listings, sale-comps, and neighborhood market data via natural-language queries.
Pull property listings, prices, and details from real-estate sites as structured JSON.
Search real-estate deals, rank top areas, run rental/BRRRR/flip analysis, pull sold comps.
U.S. real-estate data: property records, AVM value + rent estimates, sale/rental listings.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceProvides real-time access to Zillow real estate data, enabling property search, details, Zestimates, market trends, and mortgage calculations via natural language.4 npm48MIT
- FlicenseNot gradedqualityCmaintenanceExposes ATTOM's real estate API as MCP tools, enabling property details, valuations, assessments, sales, and area data via natural language.2-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to search, compare, and interact with Apartments.com rental listings, including scheduling tours and contacting property managers.5 npmMIT
- AlicenseAqualityAmaintenanceEnables natural-language access to Zillow real-estate data, including property search, details, Zestimate history, saved searches/homes, and market reports, by routing requests through the user's authenticated browser session.120745 npmMIT