数据分析

angi-mcp

试用

Read angi.com (US home-services directory) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the angi-mcp server — find pros by trade and city, read a pro's profile, ratings breakdown and reviews, and list the trade/city taxonomy. Use when you want Angi data without the MCP, in a script, or on a machine where the MCP isn't installed.

它能做什么

Read angi.com (US home-services directory) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the angi-mcp server — find pros by trade and city, read a pro's profile, ratings breakdown and reviews, and list the trade/city taxonomy. Use when you want Angi data without the MCP, in a script, or on a machine where the MCP isn't installed.

技能文档

Angi via fpx (no MCP)

Angi fronts www.angi.com with Cloudflare. Every content page returns 403 to plain curl/Node — only robots.txt, the sitemaps and /auth/login get through. fpx runs the fetch inside the user's own browser tab (the Transporter extension), which has already cleared the challenge, so the same URL succeeds. No Angi login is needed for the public data below — a normal open tab is enough; only the optional Signed-in account data section needs a signed-in tab.

Two surfaces, two tools — don't route everything through the bridge:

  • Taxonomy (which trades and cities exist) → the XML sitemaps, reachable by plain curl. No bridge, no extension.
  • Data (pros, ratings, reviews) → fpx get through the tab.

One-time setup

npm install -g @fetchproxy/cli              # provides `fpx`
fpx profile add angi --domain angi.com      # fetch capability only
fpx pair -p angi --subdomain www            # approve the 6-digit code in Transporter

Requires the Transporter extension with an open www.angi.com tab and its Chrome Site access allowing angi.com. Pairing persists across invocations.

Pair per host you intend to fetch, and keep a tab open on it. The bridge relays through a tab on the request's own host, so a bare fpx pair -p angi fails with no tab matching https://angi.com/ — the apex serves no page. Pass --subdomain www, and if you also want the signed-in account data below, open a my.angi.com tab and run fpx pair -p angi --subdomain my as well. (Alternatively --via-tab names the relaying tab explicitly.)

No cookie, storage or header scope is declared — Angi's data is server-rendered and rides the tab's own session, so nothing needs to be read out of the browser. Keep it that way: widening scope later forces a fresh pairing.

The one rule: resolve the trade slug first

Angi URLs are /companylist/us///.htm. The trade is a fixed slug (plumbing, roofing, air-duct-cleaning, …), not free text, and a wrong slug 404s. Resolve from the sitemaps before fetching — plain curl:

# All ~312 trade slugs
curl -s https://www.angi.com/sitemap/statecat-sitemap.xml \
  | grep -o '[^<]*' | sed 's/<[^>]*>//g' \
  | sed -n 's#.*/companylist/us/[a-z][a-z]/\([^/]*\)\.htm#\1#p' | sort -u

# Every city that has pages for one trade (confirms a city/trade combo exists)
curl -s https://www.angi.com/sitemap/angi-geocat-plumbing.xml \
  | grep -o '[^<]*' | sed 's/<[^>]*>//g' | grep '/us/nc/'

Core call

Fetch the page through the tab, pipe the HTML into the extractor:

fpx get 'https://www.angi.com/companylist/us/nc/charlotte/plumbing.htm' -p angi \
  | node references/rsc.mjs legacyId --dedupe id \
  | jq -r '.[] | "\(.businessInfo.businessName)\t\(.rating.averageOverallRating)★ (\(.rating.reviewCount))\t\(.profileUrl)"'

rsc.mjs exists because the data is not in the HTML and not jq-able. Angi is Next.js App Router: records arrive as React Server Component flight rows inside self.__next_f.push([1,"…"]) string literals, and nested values are deduplicated behind "$" references. The extractor concatenates the chunks, unescapes them, brace-matches the objects owning a key, and resolves the references. See references/angi-pages.md for record shapes and recipes.

Always pass --dedupe id on search pages. Each provider is emitted twice (sponsored slot + list row); raw counts are exactly double.

Signed-in account data (optional)

If the tab is signed in to Angi, the account app on my.angi.com is readable through the same profile (angi.com covers the subdomain). It is a different Next.js app — Pages Router, so its data is a plain __NEXT_DATA__ blob, and rsc.mjs does not apply. Use jq directly:

# Identity + project counts
fpx get 'https://my.angi.com/myprojects' -p angi \
  | sed -n 's/.*]*>\(.*\)<\/script.*/\1/p' \
  | jq '.props.pageProps.initialState
        | {user: .projectHomeUser.firstName,
           open: (.openProjectList.projects | length),
           closed: (.closedProjectList.projects | length)}'

# Reviews you've written (plain JSON, session-cookie auth)
fpx get 'https://my.angi.com/account/rating-review/reviews' -p angi | jq

Two limits, both verified:

  • Record fields are unknown. The account these were captured from held zero projects and zero reviews, so only the empty envelopes were observed. Read field names off the data; don't assume them.
  • The inbox is not readable. my.angi.com/inbox runs on the Twilio Conversations SDK; its proxy endpoints reject the session cookie alone (401, XML body username or accesskey could not be verified). fpx cannot speak that protocol — messages need the Twilio client, not a GET.

Signed-out requests are redirected to /auth/login rather than 401'd, so a 200 that contains a login page means the tab is signed out.

Gotchas

  • ?page=N paginates (10 unique pros per page, no overlap between pages).
  • ?zip= is inert — verified: ?zip=90210 on a Charlotte page returns the identical Charlotte pros. Location comes from the URL path only. Don't offer it as a filter.
  • JSON-LD (SearchResultsPage, LocalBusiness) is present and is real JSON, but carries only names/addresses/one sample review — no ratings, no ids. Use it as a cross-check, not the source.
  • A non-HTML or challenge-page 2xx means the tab lost its Cloudflare clearance; refresh a www.angi.com tab rather than parsing the interstitial.

Exit codes (fetch verbs)

  • 0 success · 2 bridge unavailable (extension disconnected, or pairing pending → re-run fpx pair -p angi --subdomain www, and confirm a tab is open on the host you are fetching) · 3 bot wall (tab hasn't cleared Cloudflare → refresh it) · 4 upstream non-2xx (usually a bad trade/city slug — re-resolve from the sitemap).

Notes

  • Reads only — nothing here writes to Angi. Everything is public except the optional account section, which reads only the signed-in user's own data. Stay within angi.com's terms.
  • fpx health -p angi shows bridge state when a call fails.
  • This project is developed and maintained by AI (Claude).

相关技能

Read your Jobber Client Hub — the customer portal a service business (pest control, lawn care, HVAC, cleaning) uses to send you appointments, quotes and invoices — from a shell with the fpx CLI (@fetchproxy/cli), instead of running the jobber-mcp server. Use when you want your Jobber data without the MCP, in a script, or on a machine where the MCP isn't installed.

1 次安装

Query thumbtack.com from a shell — search local service pros by trade and zip, and read pro profiles with ratings, reviews, credentials, business hours and pricing. Uses plain curl against Thumbtack's SSR pages and its anonymous GraphQL endpoint; no API key, no login, no browser extension. Use when you want Thumbtack data without an MCP server, in a script, or one-shot.

1 次安装

Read a Housecall Pro estimate or invoice your contractor sent you — line items, totals, tax, what is still owed, the company behind it — from a shell with plain curl, instead of running the housecallpro-mcp server. Use when you want the data without the MCP, in a script, or on a machine where the MCP isn't installed. Covers declining an option, and why approving cannot be scripted.

1 次安装

Connect to Ben McAdams's personal MCP server for his resume, portfolio, and blog notes.

2 次安装

Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits, goals — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests through your signed-in Chrome tab. Use when you want your MyChart data in a script or one-shot without running the myatriumhealth-mcp server.

1 次安装

Generate more revenue with high-quality leads. Give your AI agent direct access to Prospairrow — extract prospects, enrich with deep company insights, discov...

34 次安装