Catalog / pricing-tos-watch
pricing-tos-watch
Did a pricing page or terms page change?
What questions it answers
- Pricing page: what plans and prices does this page show, and did they change since my last check?
- Terms or privacy page: which clauses were added, removed or changed since my last check, and does any clause mention arbitration, AI training, data sharing, auto-renewal, price increases, class-action waiver, liability limits or termination?
When to use it
- Watching a vendor you depend on for price or terms changes.
- A first pass that tells an agent "look at this clause", with a short excerpt.
When not to
- It is a keyword and text-change detector, not legal or financial advice. Flags are pattern matches.
- Price extraction is a heuristic. Expect wrong plan names or billing periods on busy pages (a real sample labelled one plan "Freelancer," with period "day"). JSON-LD offers are more reliable when a page has them.
- It does not return the full terms. You get clause headings, short previews (up to 280 characters), and excerpts of changed clauses (up to 500 characters). Read the source page for the full text.
- Not for LinkedIn, Facebook, Instagram, TikTok, X or Twitter, private addresses, or pages whose robots.txt disallows the path (you get
blockedByRobots:trueand no data). Robots is always checked. - Known issue: if a page returns an error status (for example 403 or 429) the tool can currently save that error page as the baseline and report a false change. Do not rely on
changedfor pages that block bots until this is fixed.
Example (MCP tool `pricing_extract`, or CLI)
npx tsx src/cli.ts pricing --url https://basecamp.com/pricing
Trimmed output (shape from samples/pricing-basecamp-com-pricing.json):
{
"tool": "pricing-tos-watch",
"version": "0.1.0",
"kind": "pricing",
"url": "https://basecamp.com/pricing",
"status": 200,
"mode": "static",
"robots": { "allowed": true, "checked": true, "reason": "allowed by Allow: /" },
"planCount": 7,
"plans": [
{ "name": "Pro Unlimited,", "price": 199, "priceRaw": "$199", "currency": "USD", "billingPeriod": "month", "source": "heuristic" }
],
"sourcesUsed": ["heuristic"],
"firstCheck": true,
"changed": null,
"billing": { "sku": "pricing_extract", "plannedPriceUsd": 0.02, "x402Enabled": false }
}
ToS call (tos_extract), trimmed:
{
"kind": "tos",
"clauseCount": 4,
"clauses": [ { "id": "c1-0b2c7861", "heading": "1. INFORMATION WE COLLECT", "textPreview": "PSF may collect ...", "hash": "0b2c7861" } ],
"flags": [ { "key": "data_sharing", "clauseId": "c2-f714795d", "heading": "...", "excerpt": "..." } ],
"flagKeys": ["data_sharing"],
"firstCheck": false,
"changed": true,
"clauseDiffs": [ { "status": "changed", "heading": "Arbitration", "before": "...", "after": "...", "id": "c0-c24ccfa2" } ]
}
clauseDiffs.status is added, removed or changed (unchanged clauses are dropped). The first call for a URL has firstCheck:true and changed:null. Up to 80 clauses are listed.
Tools
| Tool | Input | Planned price |
|---|---|---|
pricing_extract | url, optional selector, js_render, reset | $0.02 |
tos_extract | url, optional js_render, reset | $0.03 |
page_watch | url, optional kind (pricing, tos, auto), selector, js_render, reset | $0.02 |
watchlist_check | urls (1 to 20), optional kind, js_render | $0.05 |
Price is USDC on Base (eip155:8453). Today everything is free because the payment layer is a disabled stub.
Data source and licence
The public pages you name. Terms and privacy text is the site owner's copyright; the tool returns only short excerpts and keeps clause hashes plus 400-character previews on disk. Prices are facts read from the page. The tool does not read the site's terms of use; it checks robots.txt only.
Freshness, state and limits
- Every call fetches the live page; there is no result cache.
- The baseline is stored on the machine running the tool, shared by all callers there.
- Static fetch: 25 s timeout, 2 MB cap. At most 50 plans per page, 20 URLs per watchlist.
- The pricing
changedflag also reacts to the first 5,000 characters of page text, so a banner or date can set it. - Robots parsing is simplified and allows the fetch if robots.txt cannot be read.
Errors are not charged
Payment settles only on a successful answer. Any response with status 400 or higher (bad input, not found, upstream failure) is never settled.