ToolMint

Catalog / page-diff-watch

MCP package · coming soon Developer & security

page-diff-watch

"Has the text of this public page (or one part of it) changed since I last looked?" The first call stores a baseline. Each later call fetches the page again and reports changed or not, which lines were added or removed, and a short rule-based summary including price-like tokens that moved.

This is a local MCP / CLI package today. Hosted pay-per-call access is not live yet; the text below describes the current code.

What question it answers

"Has the text of this public page (or one part of it) changed since I last looked?" The first call stores a baseline. Each later call fetches the page again and reports changed or not, which lines were added or removed, and a short rule-based summary including price-like tokens that moved.

When to use it

  • Watching a pricing page, a changelog, a status note or a policy page for any text change.
  • Narrowing to one part with a CSS selector (for example main h1).
  • Pages that need JavaScript to render: set js_render (needs Chromium on the machine; otherwise it falls back to plain fetch and says so).

When not to

  • Not for LinkedIn, Facebook, Instagram, TikTok, X or Twitter (blocked on purpose), or private/internal addresses.
  • Not for pages whose robots.txt disallows the path: you get blockedByRobots:true and no data.
  • The diff is a set of changed lines; it ignores line order. A reordered page shows no change.
  • The summary is regex-based. Price and number "shifts" are pairings by position, not proof.

Example (MCP tool `check_page_change`, or CLI)

npx tsx src/cli.ts https://example.com/ --selector h1

Second call on a changed page, trimmed (shape from samples/httpbin-uuid-change.json):

{
  "tool": "page-diff-watch",
  "version": "0.2.0",
  "url": "https://httpbin.org/uuid",
  "httpStatus": 200,
  "fetchMode": "static",
  "selector": null,
  "selectorMatched": null,
  "robots": { "allowed": true, "checked": true, "reason": "no matching disallow" },
  "firstCheck": false,
  "changed": true,
  "previousHash": "9601cf1c...",
  "hash": "db621474...",
  "changeRatio": 0.33,
  "addedLineCount": 1,
  "removedLineCount": 1,
  "summary": { "paragraph": "Page https://httpbin.org/uuid changed with 1 added and 1 removed line(s) ...", "pricesChanged": [], "numbersChanged": [] },
  "unifiedDiffPreview": "- ...\n+ ...",
  "billing": { "sku": "page_check", "plannedPriceUsd": 0.01, "x402Enabled": false }
}

First call: firstCheck:true, changed:null, summary "First baseline saved ...". If the page returns a server error or rate-limit status after a good baseline, you get changed:null, baselinePreserved:true and an error string instead of a fake change.

Data source and licence

The page you name. The tool does not read the site's terms of use; it only checks robots.txt. You are responsible for having the right to monitor that page. The tool keeps the page's extracted text on disk as the baseline.

Freshness, state and limits

  • Every call fetches the live page (no result cache).
  • Baselines live on the machine that runs the tool, per tenant name; if you share one tenant, you share baselines.
  • Static fetch: 25 s timeout, 2 MB cap.
  • Known gaps: a 404/410 response currently replaces the baseline; robots parsing is simplified and allows the fetch when robots.txt cannot be read or returns a server error.
  • Browser mode has a known DNS-rebinding gap; use static mode for untrusted URLs.

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.