Propstack MCP vs Compass MCP

A side-by-side look at the Propstack MCP and Compass MCP MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.

Propstack MCP logoPropstack MCPReal Estate · Local subprocess (stdio)Propstack CRM MCP: search contacts, manage properties, track deals, schedule viewings for real estate agents (Makler).65GreatAuth: api key requiredCompass MCP logoCompass MCPReal Estate · Local subprocess (stdio)Compass real-estate for Claude — search, property details, photos, price history, compare61GoodAuth: not declared

Verdict: choose Propstack MCP for real estate work as a local process; choose Compass MCP for real estate as a local process. You can also run both side by side in one mcpServers block.

Which MCP server should you choose?

Propstack MCP logoChoose Propstack MCP when

  • You need dedicated capabilities in the Real Estate domain.
  • You prefer a local stdio subprocess transport.
  • Its auth model fits you: API key required.
  • You have the keys it needs: PROPSTACK_API_KEY.
  • You want tools like search_contacts, get_contact, create_contact.
Explore Propstack MCP

Compass MCP logoChoose Compass MCP when

  • You need dedicated capabilities in the Real Estate domain.
  • You prefer a local stdio subprocess transport.
  • You want tools like compass_search_properties, compass_get_property, compass_get_saved_homes.
Explore Compass MCP

Feature & specification comparison

Rows where the two servers differ are marked.

SpecPropstack MCP logoPropstack MCPCompass MCP logoCompass MCP
CategoryReal EstateReal Estate
Quality signal65/100 · Great61/100 · Good
Install commandConfirmedConfirmed
TransportLocal subprocess (stdio)Local subprocess (stdio)
AuthAPI key requiredNot declared
PricingBYOK (pay the provider)Not declared
Required env varsPROPSTACK_API_KEYNone listed
Verified ownerCommunity listingCommunity listing
GitHub stars90
Directory activity 5 views 0 installs 0 upvotes 1 views 0 installs 0 upvotes
Tools5218

Tools & capabilities

Propstack MCP tools 52

  • search_contactsSearch and filter contacts in Propstack CRM. Use this tool to: - Find contacts by name, email, or phone number - List recent leads (sort by created_at desc) - Find uncontacted leads (last_contact_at is null) - Filter by broker assignment, status, tags, or GDPR status - Search across all contact fields with 'q' parameter The 'q' parameter searches across: first name, last name, all emails, all addresses, and all phone numbers. Phone search ('phone_number') ignores formatting — both 015712345678 and 0157-123-456-78 will match. Returns paginated results. Use expand=true for full details including custom fields. Custom fields: pass 'custom_filters' as an object of custom-field-name → value to filter by agency-specific fields (use list_custom_fields to discover field names). Each entry becomes a cf_<name> query parameter, e.g. { marketing_channel: "Website" }. Data minimization (Art. 25 DSGVO): pass 'fields' with an array of contact field names to return only those fields per contact (e.g. ["first_name", "last_name", "email"]). Omit 'fields' to return the default set unchanged. Unknown field names produce an error listing the valid options.
  • get_contactGet full details of a single contact by ID. Use this tool to: - View complete contact information before a call - Check relationships, documents, and owned properties - See sub-contacts (e.g. family members at same address) Use 'include' to load related data in one request.
  • create_contactCreate a new contact in Propstack CRM. Use this tool to: - Register a new lead after a phone call - Create a contact from a web form submission - Add a new property owner Auto-upserts: if a contact with the same email or old_crm_id already exists, it will be updated instead of creating a duplicate. Use get_contact_sources first to find valid source IDs.
  • update_contactUpdate an existing contact in Propstack CRM. Use this tool to: - Update contact details after a call - Change broker assignment - Add or remove tags (Merkmale) - Update GDPR status - Change contact rating or status Tag management options: - group_ids: replaces ALL tags with this list - add_group_ids: adds tags without removing existing ones - sub_group_ids: removes specific tags Only provide the fields you want to change.
  • delete_contactDelete a contact from Propstack CRM (soft delete). The contact is moved to a 30-day recycle bin and can be restored. Use this tool for: - GDPR deletion requests (Art. 17 DSGVO) - Removing duplicate contacts - Cleaning up test data
  • get_contact_sourcesList all available contact/lead sources in Propstack. Returns the list of sources like "Immobilienscout 24", "Website", "Empfehlung", etc. with their IDs. Use this tool to look up valid source IDs before creating or updating contacts with client_source_id.
  • search_contacts_by_phoneLook up a contact by phone number. This is the go-to tool for voice agent caller identification. When a call comes in, use this tool with the caller's phone number to instantly find the matching contact. Phone matching ignores formatting — all of these find the same contact: 015712345678, 0157-123-456-78, +49 157 12345678 Returns the matching contact(s) with key details. If no match is found, the caller is unknown and you should create a new contact.
  • search_propertiesSearch and filter properties (Objekte) in Propstack CRM. Use this tool to: - Find properties by address, ID, or exposé ID (use 'q' for fulltext) - Filter by status, type, marketing type, or project - Find properties in a price/rent range - List properties by size, rooms, or construction year - Filter by custom fields via the 'custom_filters' object (see below) The 'q' parameter searches: unit_id, street, zip code, city, district, exposé ID. Range filter pattern: 11 numeric fields each have _from and _to variants. For example, price_from=200000 & price_to=400000 finds properties priced 200–400k. Available range fields: price, base_rent, total_rent, property_space_value, living_space, plot_area, number_of_rooms, number_of_bed_rooms, number_of_bath_rooms, floor, construction_year. Common queries: - "Apartments 300–400k in Berlin": q="Berlin", marketing_type=BUY, rs_type=APARTMENT, price_from=300000, price_to=400000 - "All available rentals": marketing_type=RENT, status=<available_id from get_property_statuses> - "Properties on market 90+ days": sort_by=created_at, order=asc - "What's in Project X?": project_id=<id> Custom fields: pass 'custom_filters' as an object of custom-field-name → value (use list_custom_fields to discover field names). Each entry becomes a cf_<name> query parameter, e.g. { energy_class: "A" }. Always returns total count. Use expand=true for custom fields. Data minimization (Art. 25 DSGVO): pass 'fields' with an array of property field names to return only those fields per property (e.g. ["id", "title", "price", "city"]). Omit 'fields' to return the default set unchanged. Unknown field names produce an error listing the valid options.
  • get_propertyGet full details of a single property by ID. Use this tool to: - View complete property information for an exposé - Check images, floorplans, documents, and links - See custom fields, broker assignment, and project - Get multilingual texts (use locale parameter) Always fetches with new=1 (extra fields) and expand=1 (custom fields).
  • create_propertyCreate a new property (Objekt) in Propstack CRM. Use this tool to: - List a new property from an acquisition call - Create a listing from an owner inquiry - Add a property to a project Use get_property_statuses to look up valid status IDs. Use the relationships_attributes array to link an owner contact on creation. rs_type values: APARTMENT, HOUSE, TRADE_SITE, GARAGE, SHORT_TERM_ACCOMODATION, OFFICE, GASTRONOMY, INDUSTRY, STORE, SPECIAL_PURPOSE, INVESTMENT. rs_category provides sub-types (e.g. PENTHOUSE, VILLA, MAISONETTE for APARTMENT/HOUSE).
  • update_propertyUpdate an existing property in Propstack CRM. Use this tool to: - Update the price or rent - Change property status (e.g. mark as reserved or sold) - Edit description texts - Assign to a different broker or project - Update custom fields Only provide the fields you want to change. Use get_property_statuses to look up valid status IDs.
  • get_property_statusesList all available property statuses in Propstack. Returns statuses like "Verfügbar", "Reserviert", "Verkauft" with their IDs, colors, and sort positions. Use this tool to look up valid status IDs before: - Filtering properties by status in search_properties - Setting a property's status in create_property or update_property
  • +40 more on the listing page

Compass MCP tools 18

  • compass_search_propertiesSearch Compass listings by location (city, ZIP, neighborhood) and optional filters. Resolves free-text via slugification into Compass's URL routing, then fetches the SSR search-results page and extracts the embedded listings array. Compass server-renders ~41 listings into that page (its `num`), and `total_items` reports the full market count. PAGINATION (issue #87): Compass no longer paginates the SSR search via any URL — `/page-N/`, `?page=N`, and `?start=N` all canonicalize back to page 1 and return the identical listings, so only the first SSR page (~41 listings) is reachable through this primitive. `offset` is honored WITHIN that page, and `next_offset` is emitted only when more listings remain within it — it is never a false cursor that re-fetches page 1. TO REACH BEYOND THE FIRST PAGE, narrow with `price_min` / `price_max` / `beds_min`/`beds_max` to bucket the result set into <~41-listing bands (price-banding), then search each band. Returns each matching listing's address, price, beds/baths, sqft, lat/lng, the Compass homedetails URL (`_lid/` form, content-addressed by `listing_id_sha`), and the stable `_pid/` URL via `property_url` and the surfaced `pid` field. The per-listing `primary_photo_url` / `primary_thumbnail_url` are omitted in the default `compact` view (they are Compass CDN URLs a model cannot see); pass `view: "full"` to get them, or `compass_get_property_photos` for the whole gallery. USE `pid`/`_pid/` FOR LONG-LIVED REFERENCES (trackers, sheets, bookmarks) — sha-based `_lid/` URLs change when a property is delisted and relisted. Use the sha-based URL to fetch the current listing record. Read-only; safe to call repeatedly.
  • compass_get_propertyFetch a property's full Compass record. Pass either `url` (a full Compass homedetails URL or path from a compass_search_properties result) or `listing_id_sha` alone — when only the sha is supplied, the tool fetches /listing/<sha>/view, which redirects to the canonical /homedetails/<slug>/<sha>_lid/ page. Returns address, neighborhood, beds/baths, sqft, lot size (`lot_size_sqft` plus the derived `lot_size_acres` = round(sqft / 43560, 2), null — never 0 — for condos / missing lots), price + price-per-sqft, monthly charges, MLS status, amenities, schools, parcel number, and the canonical Compass URL. Also returns `extracted_features` (lake_front, hot_tub, basement, furnished, dock, community) keyword-parsed from the description. DESCRIPTION HANDLING: The raw `description` (Compass marketing copy) is omitted by default — pass `include_description: true` to keep it. `extracted_features` is always populated and usually sufficient. URL FORMS: Compass exposes two URL shapes for a listing. `_lid/` (content-addressed by `listing_id_sha`) — what this tool fetches and what `url` returns — is the form to use for reading the current listing record. `_pid/` (opaque short ID, in `property_url` and the surfaced `pid` field) is **stable across re-listings** and is the right choice for any long-lived reference (trackers, sheets, bookmarks); sha-based URLs go stale when a property is delisted and relisted. Read-only; safe to call repeatedly.
  • compass_get_saved_homesNot yet supported — Compass renders /overview/favorites via an auth-scoped GraphQL we have not yet identified. Throws a clear error explaining the limitation.
  • compass_get_saved_searchesNot yet supported — Compass renders saved searches via an auth-scoped GraphQL we have not yet identified. Throws a clear error explaining the limitation.
  • compass_calculate_mortgageLocal-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 — fully deterministic, safe to use for scenario comparison without burning a fetch. 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.
  • compass_get_price_historyFull listing history for a Compass property — Listed / Sold / Pending / Price Change / Delisted events with date, price, and MLS attribution. Returns three arrays: `events` covers this listing's events, `history` aggregates events from prior listings of the same property, and `events_normalized` merges both into a shared cross-MCP schema (`{date, type, price?, price_change_pct?, source_mls?}` with a fixed type enum: Listed | PriceChange | Pending | Contingent | Sold | Withdrawn | Relisted | Delisted). Pass either `url` (the full Compass homedetails URL or path) or `listing_id_sha` alone — sha-only calls fetch /listing/<sha>/view, which redirects to the homedetails page. Note: most of this data is already returned inline on `compass_get_property` (the events[] / history[] arrays live on the same listing record); call this tool only when you want the merged + normalized timeline. Read-only; safe to call repeatedly.
  • compass_compare_propertiesFetch 2 or more Compass properties and align their facts side-by-side. Each target may supply `url` (a full Compass homedetails URL or path) or `listing_id_sha` alone — sha-only targets fetch /listing/<sha>/view, which redirects to the homedetails page. Returns the full per-property record per row (with `extracted_features` populated). Per-target errors are captured per-row — one bad target will not fail the whole call; a failed row carries `status` = `error_kind` (`timeout` / `bridge_down` / `protocol` / `other`), `retryable` and `error`, and the envelope reports `count` / `ok` / `errored`. Calls are concurrent, and the whole call is bounded by an overall deadline: any row still unsettled when it is reached comes back as `{ status: "pending", retryable: true, error }` with a top-level `pending` count — re-run just those targets. The raw `description` is omitted from each row by default — pass `include_description: true` to keep it. The redundant `summary` table is also opt-in via `include_summary: true` — by default only `results[]` is returned, which already carries every fact.
  • compass_calculate_affordabilitySolve for the maximum home price you can afford under the standard 28/36 DTI rule. Inputs: monthly income, recurring monthly debts (car loans, student loans, etc.), down payment, interest rate, and optional property-tax rate / insurance / HOA / loan term. Output: max home price, the binding constraint (front-end vs back-end), and the full PITI breakdown at that price. Same math across the realty MCP cohort (@chrischall/realty-core). No network — pure local math.
  • compass_get_property_photosThe full photo gallery for a Compass listing — every image in listing.media[]. Each entry returns the original CDN URL plus a thumbnail URL and pixel dimensions. Pass either `url` (the full Compass homedetails URL or path) or `listing_id_sha` alone — sha-only calls fetch /listing/<sha>/view, which redirects to the homedetails page. By default only photos (category 0) are returned; set `include_all_categories: true` to also include floorplans and other media. Returns `{ listing_id_sha, count, photos }`. Read-only; safe to call repeatedly.
  • compass_healthcheckRound-trips a small public www.compass.com URL (/robots.txt) through ContextMint Bridge (your signed-in browser tab) 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 'this browser can't serve a capability' from 'real www.compass.com-side problem'. Read-only, no auth required. Call this when a real tool fails and you want to know which hop broke.
  • compass_get_by_addressResolve a free-text street address to a Compass listing's canonical URL and identifiers in one call. Walks three rungs: first the structured typeahead `POST /api/v3/omnisuggest/autocomplete` (the primary rung — Compass's address-suggest API, which routes around the AWS WAF that 403s the SSR free-text path, issues #78/#79), then `/homes-for-sale/?q=<address>` (the free-text rung) and — when those return no verified match — a slug-based search at `/homes-for-sale/<city-state-or-zip>/` (the search-fallback rung, issue #71). Each candidate is verified against the query (case + street-type abbreviation normalization, then whole-token equality, issue #45) before being accepted. Returns `{ url, listing_id_sha, pid, address, resolved, matched_via }` where `matched_via` is `"typeahead"`, `"freetext"`, or `"search_fallback"` so callers can see which rung found the match. When no rung matches, returns `{ resolved: false, error: "no listing matched" }` rather than leaking a wrong URL. When the lookup was blocked by a sign-in / AWS WAF challenge instead, it returns `{ resolved: false, status: "auth_required", error, hint }` — NOT a miss: sign in to compass.com in the browser and retry. The `url` is the stable `_pid/` form when Compass provides a `navigationPageLink` (preferred for trackers/bookmarks — sha URLs go stale on relisting), falling back to the `_lid/` form otherwise. Read-only; safe to call repeatedly.
  • compass_bulk_getFetch up to 200 Compass listings in a single call. Returns one structured row per input target (no side-by-side summary table — use `compass_compare_properties` for that). Each row is either `{ listing_id_sha, url, status: "ok", property }` on success or `{ listing_id_sha, url, status, error_kind, retryable, error }` on failure (`status` = `error_kind`) — one bad target never fails the whole call. `retryable: true` (a bridge `timeout` after one retry, an unreachable `bridge_down`, issue #73) is NOT a missing listing, so retry it (a cold bridge usually succeeds on the second call) rather than concluding Compass has no record; `protocol` / `other` are real misses. Targets accept the same `url` / `listing_id_sha` shape as `compass_get_property`. Calls fan out concurrently. The whole call is bounded by an overall deadline: a slow or hung row never wedges it — any row still unsettled when the deadline is reached comes back as `{ status: "pending", retryable: true, error }` alongside a top-level `pending` count, so re-run just those targets. The envelope also reports `count` / `ok` / `errored`. `extracted_features` is populated per row. The raw `description` is omitted by default — pass `include_description: true` to keep it.
  • +6 more on the listing page

Ready-to-paste client configs

Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.

Propstack MCP

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "ashev87-propstack-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "propstack-mcp-server"
      ],
      "env": {
        "PROPSTACK_API_KEY": "YOUR_PROPSTACK_API_KEY_HERE"
      }
    }
  }
}

Compass MCP

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "compass-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "compass-mcp"
      ]
    }
  }
}

Frequently asked questions

Propstack MCP is categorized under Real Estate and uses a local stdio subprocess. Compass MCP belongs to Real Estate and uses a local stdio subprocess. Pick Propstack MCP for real estate work and Compass MCP for real estate.

Copy the mcpServers block from the config section on this page into your client's config (for example claude_desktop_config.json or ~/.cursor/mcp.json), then fully restart the client.

Propstack MCP is bring-your-own-key: usage is billed by the API provider you supply a key for. Auth: api key required. Compass MCP has no declared pricing — check the project's own site. If a server needs environment variables such as API keys, define them under the env key in your client's MCP config.

Yes. MCP clients support multiple servers: add ashev87-propstack-mcp and compass-mcp as separate keys in the same mcpServers object, and your assistant will call tools from either one.

On AllMCPs, Propstack MCP has a quality signal of 65/100 (Great) with 5 views, 0 installs and 9 GitHub stars. Compass MCP has 61/100 (Good) with 1 views, 0 installs and 0 GitHub stars.