# Changelog of Zillow MCP Server (`afanasenko/zillow-mcp-server`) Actor

- **URL**: https://apify.com/afanasenko/zillow-mcp-server/changelog.md
- **Full Actor documentation**: https://apify.com/afanasenko/zillow-mcp-server.md

## Changelog

All notable changes to **Zillow MCP Server** are documented here.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### \[0.0.41] - 2026-09-23

#### Fixed

- **Runs and MCP sessions stop at their "Maximum cost per run".** A property is returned only after it is charged. Once the limit is used up, tools say so instead of fetching more.

### \[0.0.40] - 2026-09-23

#### Fixed

- Zillow ZIP pages without a city in the link are read as that ZIP, and search links copied after moving the map are searched inside the map area they show.

### \[0.0.39] - 2026-09-10

#### Changed

- Clarified wording in the README, the changelog, the input descriptions, and the tool argument and output field descriptions. Nothing changes in how the actor runs, what it returns or what it costs.
- When a run fails for a reason on our side, the error message now stays short and plain.

### \[0.0.38] - 2026-08-17

Maintenance build — no user-facing changes. Input schema, output dataset
columns, KVS records, console output, error messages, defaults, and pricing
are all unchanged from 0.0.37. Saved tasks continue to work identically.

### \[0.0.37] - 2026-08-17

Maintenance build — no user-facing changes. Input schema, output dataset
columns, KVS records, console output, error messages, defaults, and pricing
are all unchanged from 0.0.36. Saved tasks continue to work identically.

### \[0.0.36] - 2026-08-12

Maintenance build — no user-facing changes. Input schema, output dataset
columns, KVS records, console output, error messages, defaults, and pricing
are all unchanged from 0.0.35. Saved tasks continue to work identically.

### \[0.0.35] - 2026-08-10

#### Changed

- The rules that keep internal technical details out of run output are now identical across all our
  actors. No user-visible change here — this build only brings this actor in line with the shared copy.

### \[0.0.34] - 2026-08-10

#### Fixed

- **A failed run no longer shows you a raw technical reply.** When a request was refused, the raw
  answer — including a server address — was printed as the run's failure message, stored in
  `RUN_SUMMARY`, and shown on the run page. None of it was ever useful to you, and none of it
  belongs there. A failed run now says the failure was on our side, and nothing more.

### \[0.0.33] - 2026-07-30

#### Fixed

- **Search filters are now actually applied.** Price, bedrooms, bathrooms, square footage, lot size,
  year built, parking, HOA, days on Zillow and property type were being passed to Zillow under names
  it does not recognise, so it ignored them: a request for homes over $900,000 came back with every
  home in the area, and every one of those rows was charged for. All of them now filter correctly.
- **A search Zillow refuses is no longer returned as an empty result.** When Zillow rejects a search
  it answers with an error rather than a result set, and the tools were reading that as "no listings
  found". The tool call now fails with Zillow's own reason, so an agent can correct the filter
  instead of reporting that the area is empty.
- **A search combining a maximum number of bedrooms with a minimum number of bathrooms no longer
  returns nothing.** Zillow rejects that combination unless a maximum number of bathrooms is also
  set; the wrapper now supplies an upper bound, leaving the minimum unchanged.

### \[0.0.31] - 2026-07-30

#### Fixed

- **URL search reads the Zillow pages it used to ignore.** A page for one street address — including
  a `/homedetails/` page with no ZPID number — returns that home; a ZIP page (`/ocala-fl-34481/`) is
  searched as the ZIP itself; a state page (`/nc/land/`) covers the whole state; and a keyword page
  (`/fl/fixer-upper_att/`) applies the keyword and home types written into the URL.
- **Listing-channel filters are sent under the names the search understands.** `isForSaleByOwner`
  and `isForSaleByAgent` were passed straight through, and the search ignores them — asking for
  owner-posted homes quietly returned the ordinary result set, and every row was billed. Zillow's
  owner channel also carries new-construction, bank-owned and auction homes; those are dropped
  before enrichment, so they are not charged for either.

#### Added

- **An agent-readable reason when a URL returns nothing.** Profile pages list no homes, and a
  neighbourhood cannot be searched on its own; the tool result now says which it was and what to
  paste instead, and the same line is recorded in RUN\_SUMMARY.

### \[0.0.28] - 2026-07-29

#### Fixed

- **A ZIP code Zillow cannot search directly no longer comes back empty.** A handful of US ZIPs —
  PO-box and non-residential ones — cannot be searched on their own, and the tool returned
  nothing for them without saying why. Those ZIPs now fall back to a search of the surrounding city,
  filtered back to the requested ZIP, so the caller gets the homes that exist there. Homes outside
  the requested ZIP are dropped before enrichment and are never charged.

#### Added

- **The tool result says when a ZIP had to be searched through its city**, and `RUN_SUMMARY.zipScope`
  records which ZIPs those were and how many rows were dropped unbilled.

### \[0.0.27] - 2026-07-29

#### Changed

- **The Store listing now says what this server does** — three tools that search homes by ZIP code,
  search by Zillow URL, or look one up by zpid, returning address, price, agent email and phone,
  Zestimate, schools and price history — and the price line shows the per-property price instead of
  a generic label. Written so an AI agent browsing the MCP directory can tell what it gets.

### \[0.0.26] - 2026-07-28

#### Added

- **A "Live Status" link in the run's Output tab.** The status page was always being saved, but
  nothing linked to it. The link opens it during the run and still opens it afterwards.

#### Fixed

- **The status page now keeps up with the run.** It was only rewritten once every ten tool calls, so
  a server that had handled fewer than ten showed the start-up screen no matter how much work it had
  actually done. It now refreshes within ten seconds of a tool call — and stays quiet while the
  server is idle, so an always-on server does not accumulate pointless rewrites.

### \[0.0.25] - 2026-07-28

#### Fixed

- **The run cost now shows your plan's price, not the Free-plan price.** Property Data Enriched costs less on paid plans ($0.08 on Free, down to $0.05 on Gold and above), but tool results and `RUN_SUMMARY` always quoted $0.08. Both now quote what your subscription actually pays. Your bill is unchanged — only the number the run reported was wrong.

Same input shape, output columns, dataset shape, MCP tool list, and pricing.

### \[0.0.23] - 2026-05-21

#### Added

- **Plain city URLs now work** — a Zillow city link such as `https://www.zillow.com/austin-tx/` or `https://www.zillow.com/austin-tx/houses/` is read as a location search; previously these returned no results unless a filter was applied first on Zillow. The home-type and listing segments — `/houses/`, `/condos/`, `/townhomes/`, `/apartments/`, `/multi-family/`, `/lots-land/`, `/manufactured/`, `/sold/`, `/rentals/`, `/fsbo/` — map to the matching search. Applies to both regular runs and the `zillow_search_by_url` tool. `searchQueryState`, `_rb` browse, recently-sold, and single-property URLs are unaffected.

Same input shape, output columns, dataset shape, MCP tool list, and pricing.

### \[0.0.22] - 2026-05-21

#### Fixed

- **Running with default settings no longer fails** — starting the actor without a target (for example, clicking Start on the default ZPID mode with no ZPIDs) now performs a small demo run instead of failing with an error. The same applies to ZIP and URL modes left empty. Demo runs are capped at 10 properties for cheap testing; the full property cap is restored once you provide your own target.
- **Plain Zillow browse URLs now work** — for-sale browse URLs like `https://www.zillow.com/homes/Beverly-Hills,-CA_rb/` are now read as a location search (previously they returned no results). Applies to both regular runs and the `zillow_search_by_url` tool.

Same input shape, output columns, dataset shape, MCP tool list, and pricing.

### \[0.0.21] - 2026-05-19

#### Fixed

- **Apartment-building rentals now emit useful data** — ForRent multi-unit apartment buildings cannot be looked up one property at a time, so their record is now built directly from the search result instead: `brokerName` = building name, the building address, and `price` from the lowest unit rent. New additive fields `availabilityCount` and `unitsAvailable`. Ported from parent zillow-scraper 2.3.69. Applies to both regular runs and the `zillow_search_by_zip` / `zillow_search_by_url` MCP tools.

Same input shape, output dataset is a superset (two new fields), same pricing.

### \[0.0.20] - 2026-05-19

#### Fixed

- **Rental search default-fix — sale-flags clearing bug** — 0.0.19 set the cleared flags to explicit `false` instead of deleting them. In practice the search returns 0 results when those flags are explicitly false, but the full inventory when they are absent. Auto-fix now deletes the keys (applies to both the regular-run handler and the `zillow_search_by_zip` MCP tool). Ported from parent zillow-scraper 2.3.65.

Same input shape, output columns, dataset shape, KVS records, MCP tool list, and pricing.

### \[0.0.19] - 2026-05-19

#### Changed

- **Rental search default-fix — extended** — the auto-fix introduced in 0.0.18 also now clears the form-default sale-side listing flags (`isForSaleByAgent: true` + `isForSaleByOwner: true`) on `ForRent` searches when they match the form-default signature. Applies to both the regular-run handler and the `zillow_search_by_zip` MCP tool. Ported from parent zillow-scraper 2.3.64.

Same input shape, output columns, dataset shape, KVS records, MCP tool list, and pricing.

### \[0.0.18] - 2026-05-19

#### Changed

- **Rental search default-fix** — both the regular-run handler and the `zillow_search_by_zip` MCP tool now auto-enable the "Apartments" home type when they detect form-default filters on a `ForRent` search (i.e. Houses + Townhomes + Condos + Multi-family all on, Apartments off). The original defaults are tuned for `ForSale` where apartments are rare; for rentals apartments are the majority of inventory, and the same defaults were yielding ~83% zero-result rate vs ~20% with apartments on. If you really want SFR-only rentals, set `isApartment=false` together with the other home types you want off — the auto-fix only triggers on the exact form-default signature.
- **Input schema** — `isApartment` field description rewritten to call out the rental-search best practice and explain the auto-fix.

Ported from parent zillow-scraper 2.3.63. Same input shape, output columns, dataset shape, KVS records, MCP tool list, and pricing.

### \[0.0.17] - 2026-05-19

#### Changed

- **URL handling** (regular-run + `zillow_search_by_url` tool) — clearer error when `zillowUrl` is missing (now includes an example URL, how to obtain one, and the call shape). Added a pre-flight warning when the URL looks like a single-address shortcut (e.g. `/homes/<address>_rb/`) — those redirect on Zillow's side and never return listings, so the warning points to the right alternative before the search runs. Added a tip when a `/homedetails/.../<zpid>_zpid/` URL is auto-converted, suggesting the `zillow_lookup_property` tool / ZPID mode as the cleaner shape for future calls.
- **RUN\_SUMMARY** — added `properties.capStatus` (`unlimited_complete` / `cap_reached` / `no_results`) and `properties.capNote` so consumers reading the run via the API can tell the difference between "this is the full result set" and "we hit the cap, more available." Available from all 3 MCP tools (`zillow_search_by_zip`, `zillow_search_by_url`, `zillow_lookup_property`) and from regular runs.
- **Input schema** — `zillowUrl` field description rewritten to explain the search-URL requirement (must contain `searchQueryState=`) and point single-property users to the `zillow_lookup_property` tool / ZPID mode.

Same input shape, output columns, dataset shape, KVS records, MCP tool list, and pricing.

### \[0.0.16] - 2026-05-08

#### Changed

- Maintenance build — no user-facing changes.

### \[0.0.15] - 2026-05-07

#### Changed

- **README** — refreshed structure for clarity (restored prior section layout). Same input, output, dataset shape, and pricing.

### \[0.0.14] - 2026-05-07

#### Changed

- Maintenance build — no user-facing changes. Input schema, output dataset columns, KVS records, console output, error messages, defaults, and pricing are all unchanged from 0.0.13. Saved tasks continue to work identically.

### \[0.0.13] - 2026-05-07

#### Changed

- **README** — aligned to Apify quality template (same shape as the parent and sibling actors). Hero rewritten with value-first prose and a "beyond what Zillow's official API offers" comparison; numbered 3-step Quick start; new `🎯 What it does` / `📦 Output sample` / `🧭 When to use it` sections; new `💡 Tips & Best Practices` section (4 sub-sections × 3 bullets); new `🛟 Support & feedback` section pointing to Apify Store reviews / bookmark / Issues tab; new dedicated `⚖️ Is it legal to scrape Zillow?` H2 with link to Apify's web-scraping legality blog; FAQ expanded from 0 to 10 Q\&As (legality, ban risk, MCP vs regular run, Standby costs, agent auto-discovery, data freshness, cost cap). Section order normalized to match the family. No functional changes — same data, tools, pricing, schema.

### \[0.0.12] - 2026-05-07

#### Added

- Full functional parity with the parent scraper. Each property now goes through the same 3-tier agent-email resolution chain (property details → agent profile → name search) and returns 77 fields instead of 42 — including bathroomsFull/Half, lotSize, parking, openHouseSchedule, parcelNumber, view, architecturalStyle, appliances, heating/cooling/flooring/laundryFeatures/fireplaceFeatures/communityFeatures, hasBasement/Garage/Pool/Video/3DModel, lastTaxAssessedValue, lastTaxPaid, mainPhoto, priceChange, datePriceChanged, schools.
- Two opt-in enrichment toggles available on every tool and the regular-run dispatcher: `enrichWalkScore` (adds walkScore / transitScore / bikeScore, 0–100 each) and `enrichPhotos` (adds the full Zillow photo gallery as `photos[]`). Neither adds an extra charge; each adds a little time per property.
- 22 new INPUT\_SCHEMA fields: 16 rental filters (largeDogsAllowed, smallDogsAllowed, catsAllowed, noPets, inUnitLaundry, parkingAvailable, furnished, hardwoodFloor, utilitiesIncluded, disabledAccess, shortTermLease, outdoorSpace, controlledAccess, highSpeedInternet, elevator, acceptsApplications, incomeRestricted), 3 school filters (schools, schoolsRating, includeUnratedSchools), 2 enrichment toggles. Mirrors the parent scraper's filter surface exactly.
- 5 storage records per run — RUN\_SUMMARY, SKIPPED\_ITEMS, FREE\_LIMITS\_APPLIED, USER\_MESSAGE, status.html — matching the parent's operational-record surface. In Standby mode the counters aggregate across all MCP tool calls in the same instance and flush every 10 calls and on Actor.exit. KVS schema (`.actor/key_value_store_schema.json`) documents all 5 collections.
- FREE-plan agent-email masking. Real emails on paid plans, `j***@a***.com` pattern + `masked_upgrade_to_unlock` source on FREE — same gating as the parent scraper.

#### Changed

- Per-request timeout reduced from 30s to 15s — same as the parent (v2.3.45). Retry logic preserved (2 retries on 429 and 2 on network error).

### \[0.0.5] - 2026-05-07

#### Added

- Full schema set: external INPUT\_SCHEMA (`.actor/input_schema.json`) mirroring the parent scraper's structure (mode + ~50 filter fields, sectionCaption groupings), output schema (`.actor/output_schema.json`) declaring the default dataset as the run's primary output, and Standby web-server OpenAPI 3 schema (`.actor/web_server_openapi.json`) documenting POST /mcp + the 3 tool argument shapes. Apify Console now renders all schemas under actor settings (no more "Consider implementing" hints), and the input form for regular runs exposes the same filter set customers expect from the parent.
- Regular-run dispatcher honors the full filter surface: price / rent / beds / baths / sqft / lot size / year built ranges, all home types, all listing types (auctions, foreclosures, FSBO/agent, pending, backup offers), features (garage, pool, A/C, waterfront, basement state), views (city / mountain / park / water), 3D tours, open houses, HOA cap, parking minimum, sort order, days-on-Zillow, free-text keywords. All of them are passed on to the search.

#### Changed

- Regular-run dispatcher now accepts `zpids` (array) instead of `zpid` (singular) — symmetric with parent and lets one run process multiple ZPIDs in a single dispatch. All filters moved from the nested `filters: {}` JSON object to top-level input fields (parent's UX). MCP tool handlers retain their nested `filters` argument shape (the MCP convention agents expect) — both paths share the same internal helpers.

### \[0.0.4] - 2026-05-07

#### Fixed

- TypeScript build error in the regular-run dispatcher (constants for the FREE-tier cap and per-tool-call ceiling were referenced before declaration after the 0.0.3 hybrid-input refactor). No customer-facing behavior change.

### \[0.0.3] - 2026-05-07

#### Added

- **Regular run mode with INPUT\_SCHEMA.** Previously the actor ran exclusively in Standby mode — clicking "Start" in the Apify Console showed "Actor was started without input" with no useful UI. Now the actor is hybrid: connect via MCP at `/mcp` for the full 3-tool experience, OR fill the input form (mode + zpid/zip\_codes/zillow\_url + max\_properties + filters) and click Start for a one-shot regular run that pushes results to the dataset. Same dataset shape, same PPE pricing. mcp.apify.com auto-tool now uses this INPUT\_SCHEMA for its tool surface too.

### \[0.0.2] - 2026-05-07

#### Fixed

- `zillow_lookup_property` and the post-search enrichment chain used the wrong property lookup and failed every tool call with a not-found error. They now use the same lookup as the parent scraper. End-to-end tests now pass for both `zillow_lookup_property` and `zillow_search_by_zip`.

### \[0.0.1] - 2026-05-07

#### Added

- Initial release of Zillow MCP Server — first MCP-wrapper actor in the Zillow family.
- Standby-mode actor exposing a Model Context Protocol (MCP) endpoint at `/mcp` over Streamable HTTP transport. Always-on (no cold-start) — connect any MCP client (Claude Desktop, Cursor, ChatGPT, VS Code) to `https://<actor-id>.apify.actor/mcp` and the actor's tools appear in the client's tool catalog.
- 3 agent-friendly tools mirroring the parent scraper's 3 search modes:
  - `zillow_search_by_zip(zip_codes, max_properties?, filters?)` — find properties by US ZIP code or location name. Returns enriched property records with address, price, beds/baths, sqft, agent name + phone, listing status. Up to 20 ZIPs per call.
  - `zillow_search_by_url(zillow_url, max_properties?)` — paste any Zillow search URL (filters baked into `searchQueryState` are honored automatically) or a single-property `_zpid` page.
  - `zillow_lookup_property(zpid)` — direct lookup of a single property by its Zillow Property ID.
- Pay-per-event pricing 1:1 with the parent Zillow Property & Agent Data Scraper: $0.08 per property enriched on FREE tier, tiered down to $0.05 on DIAMOND. One-time `apify-actor-start` event ($0.00005) per actor start, per GB memory.
- Free plan caps at 15 properties per tool call; paid plans up to 50 per tool call (single-call ceiling, not per-day).
- 41-column dataset row per enriched property, written to the actor's default dataset on every tool call so results are inspectable in the Apify Console alongside the MCP response.
- Auto-discoverable on `mcp.apify.com` once published with category `MCP Servers`.

#### Notes

- v1 enrichment is BASIC: each property is enriched with a single property-details lookup. The parent scraper's full enrichment chain (agent-email lookup via profile + agent search fallback, Walk Score / Transit Score, full photo galleries) is intentionally out of scope for v1 and tracked for v2.
- Same listing data as the parent scraper. Tool calls fail fast with a clear error if the actor's configuration is incomplete.
