Install
openclaw skills install @chrischall/compass-fpxQuery compass.com (US real-estate portal) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the compass-mcp server — search listings, get property/agent detail, price history, and resolve street addresses through one-shot fetches over a signed-in browser tab. Use when you want Compass data without the MCP, in a script, or on a machine where the MCP isn't installed.
openclaw skills install @chrischall/compass-fpxCompass has no public JSON data-API for search/listing/agent data — it's a
fully server-rendered React app that embeds each page's data as JSON inside
an inline <script> global (global.uc, window.__INITIAL_DATA__,
window.__AGENT_PROFILE__). compass.com also runs AWS WAF, which 403s
plain curl/Node requests on some paths regardless of headers. fpx routes
every request through the user's own signed-in browser tab (the fetchproxy
extension), which already carries a cleared WAF session, so the page renders
normally — you then pull the JSON out of the HTML yourself.
This is Bucket 1 (full-fetchproxy): every call, not just an auth
bootstrap, rides the bridge. Compass validates at the session level per
request, same as the compass-mcp server itself (no server-side path
exists). No Compass login is required beyond having a signed-in tab open —
search/listing/agent data and the address-typeahead endpoint are all public.
npm install -g @fetchproxy/cli # provides `fpx`
fpx profile add compass --domain compass.com
fpx pair -p compass # prints a pair code → approve in the fetchproxy extension
Requirements: the fetchproxy browser extension installed, an open
www.compass.com tab, and its Chrome Site access allowing compass.com.
Pairing persists — after the first approval every later fpx call reuses it.
Two request shapes:
fpx get the path,
then pull the inline JSON global out of the HTML.fpx post-json.fpx get 'https://www.compass.com/homes-for-sale/manhattan-ny/' -p compass > /tmp/page.html
node references/extract-global.mjs /tmp/page.html uc | jq '.sharedReactAppProps.initialResults.lolResults.data | length'
references/extract-global.mjs is a small, dependency-free re-implementation
of the balanced-brace walk compass-mcp's own src/page-state.ts uses
(extractGlobalAssign) — Compass writes each global as a JSON literal
(global.uc = {...};), so once the object is sliced out, JSON.parse/jq
works normally. Regexing for it without brace-balancing breaks the moment a
nested value contains }.
Full endpoint list, exact paths, and jq projections are in
references/requests.md.
Compass's SSR free-text search (/homes-for-sale/?q=<query>) is WAF-walled
in production and reliably 403s. For address resolution, always hit the
structured, WAF-immune typeahead first (POST /api/v3/omnisuggest/autocomplete)
and only fall back to the SSR search pages when it returns nothing — mirror
compass-mcp's own rung order (see references/requests.md §4).
A response is NOT a good page when either is true:
/login (fpx follows redirects like a browser,
so check the body for the login form, or pass -H / inspect with
--json to see the resolved URL).awswaf.com and challenge.js, and is under
~80 KB (the AWS WAF challenge interstitial; a real signed-in page is much
larger). compass-mcp's throwIfSignInPage uses this exact pair of
markers — grep for both before trusting a fetch:grep -q 'awswaf.com' /tmp/page.html && grep -q 'challenge.js' /tmp/page.html && \
[ "$(wc -c < /tmp/page.html)" -lt 80000 ] && echo "WAF-blocked — refresh the compass.com tab"
0 — success.2 — bridge unavailable: extension not connected or pairing pending → fpx pair -p compass, confirm a compass.com tab is open.3 — bot wall: the tab hasn't cleared the AWS WAF challenge → refresh a www.compass.com tab and retry.4 — upstream non-2xx from Compass./page-N/ canonicalizes back to page 1 and returns
identical data. To reach more of the market, narrow with price/bed bands
(/<lo>-<hi>-bed/, /<lo>-<hi>-price/) and re-search each band — don't
paginate._pid/ (navigationPageLink) is a stable
opaque id — use it for bookmarks/trackers. _lid/ (content-addressed by
listingIdSHA) is what you fetch to read the current record, but it
changes when a property is delisted and relisted.compass-mcp stubs those tools
out too; this skill doesn't cover them.fpx health -p compass shows bridge connection state when a call fails.