{"serverId":"mcp-registry/com.difficat/difficat","tools":[{"name":"compare_snapshot","fixed":{"name":"compare_snapshot","description":"Free up to 40 pages a day per client address for a live compare, no key needed. Compares a saved snapshot, as Site A, against a live targetUrl (every stored page paired by path, or the urls pairs you name) at the snapshot’s width and check mode, priced at one captured page per pair (half a live pair) with no discovery; the snapshot’s own origin is never fetched. With otherSnapshotId, or with pairs naming a page of one stored set against a page of another, it compares stored snapshots at no charg","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"urls":{"type":"array","items":{"type":"object","required":["source","target"],"properties":{"source":{"type":"string","maxLength":2048,"minLength":1,"description":"Page URL on Site A."},"target":{"type":"string","maxLength":2048,"minLength":1,"description":"The same page's URL on Site B."}}},"maxItems":50000,"minItems":1,"description":"With targetUrl: the pairs to compare, each source a page of the snapshot (its path or full URL on the snapshot’s origin) and each target on targetUrl. Without it every stored page is paired by path."},"pairs":{"type":"array","items":{"type":"object","required":["a","b"],"properties":{"a":{"type":"object","required":["snapshotId","n"],"properties":{"n":{"type":"integer","maximum":9007199254740991,"minimum":0,"description":"A page number from the set’s page list."},"snapshotId":{"type":"string","pattern":"^snap-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The snapshot set id, snap-<uuid>."}},"description":"The page that is Site A."},"b":{"type":"object","required":["snapshotId","n"],"properties":{"n":{"type":"integer","maximum":9007199254740991,"minimum":0,"description":"A page number from the set’s page list."},"snapshotId":{"type":"string","pattern":"^snap-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The snapshot set id, snap-<uuid>."}},"description":"The page that is Site B."}}},"maxItems":200,"minItems":1,"description":"With the account key: the snapshots to compare, pair by pair, each a page of a stored set as Site A and one as Site B. Pairs may span sets and reuse one snapshot; at most 200. Give this, or snapshotId with otherSnapshotId, which pairs the pages both hold by path."},"dryRun":{"type":"boolean","description":"Quote only: runs every check and the pricing, then answers the page count and exact amount. Nothing is charged, the free allowance is not used and no job starts; the same body without dryRun is priced from the retained result."},"visual":{"description":"Not accepted: a run against a snapshot uses the masks and freeze recorded with the snapshot.","type":"string"},"targetUrl":{"type":"string","maxLength":2048,"minLength":1,"description":"The live site to compare against the snapshot (full URL). Give this or otherSnapshotId."},"threshold":{"type":"number","maximum":1,"minimum":0,"description":"Visual diff tolerance as a fraction from 0 (exact) to 1: 0.05 means 5%. The web app takes a percentage; the API does not."},"shareToken":{"type":"string","maxLength":200,"minLength":20,"description":"A share token (dcs_…) the snapshot’s owner issued for agents. Needed unless the account key on the request’s HTTP headers owns or was granted the snapshot."},"snapshotId":{"type":"string","pattern":"^snap-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The snapshot id, snap-<uuid>, from list_snapshots or the web app."},"callbackUrl":{"type":"string","maxLength":2048,"minLength":1,"description":"Optional https URL (port 443) that receives one JSON POST when the job ends (jobId, status, summary, links; never the jobToken), a nudge to read the job. Public hosts only, no redirects followed, retried twice; delivery never affects the job."},"maxPriceUsd":{"type":"number","description":"Optional spend cap in USD. A job priced above it is refused before any challenge, so an auto-paying client is never asked for more.","exclusiveMinimum":0},"idempotencyKey":{"type":"string","maxLength":255,"minLength":1,"description":"Optional opaque string a retry repeats: under a prepaid balance the same value within 24 hours is not charged again and answers DUPLICATE_REQUEST with the jobId of the first call."},"otherSnapshotId":{"type":"string","pattern":"^snap-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A second snapshot set to compare the first against, its pages paired by path. Needs the account key on the request; never free. Give this, pairs or targetUrl."}}},"annotations":{"readOnlyHint":false,"openWorldHint":true,"idempotentHint":false,"destructiveHint":false},"title":"Compare against a snapshot"},"changes":[{"kind":"schema","detail":"Added \"type\":\"string\" to untyped parameters: visual. Change to number/boolean/array where that's what you accept.","verify":true}],"tokensBefore":1280,"tokensAfter":1285}],"toolsChanged":1,"tokensSaved":0,"todo":[],"note":"Deterministic fixes. Changes marked verify need a human look before shipping (renames, inferred annotations, inferred types, removed text). Parameter descriptions in `todo` need to be written by someone who knows the API."}