watch-for-changes
Check something on the web on a recurring cadence, compare it to what you saw last time, and only report back when there's an actual change.
Before running any command
If tvly is not found on PATH, follow the bundled CLI setup.
Important: this is orchestration, not a Tavily platform feature
Tavily's API is stateless — it has no built-in scheduling, alerting, or "watch this" endpoint. This skill combines:
- Tavily (
tvly extract or tvly search) for the actual "check the thing" step
- Some recurring-task mechanism for the "keep doing this on a cadence" step. Use whatever your environment offers:
- Any other agent/CLI with its own scheduling or long-running-task primitive: use that
- No agent-level scheduler available: a plain OS cron job / systemd timer / Windows Task Scheduler entry that re-invokes the agent (or the diff script directly) on the target cadence, or a scheduled CI job (e.g. GitHub Actions
schedule trigger)
Be upfront with the user about this — "monitor" here means "something re-runs this check for you on a cadence," not "Tavily is watching this in the background on its own." Ask the user which mechanism is available/preferred if it isn't obvious.
Keep snapshots in the user's working project or a configured writable data
directory, not inside the installed power. If no scheduler is available, report
that monitoring is not active; a baseline alone does not schedule future checks.
When to use
- Watching a specific URL/page for content changes (pricing, terms, changelog, filing status)
- For a recurring summary of new coverage on a broad topic, use tavily-search with a suitable time filter and an available scheduler. This skill focuses on change detection.
How it works
- Baseline: extract the target page (or run the target search) once, save the content and a hash/fingerprint of it to a local snapshot file.
- Schedule: set up a recurring check at the cadence the user wants, using whatever recurring-task mechanism is available (the host's scheduler or a configured cron/CI job).
- Each run: re-extract, compare to the saved snapshot.
- No meaningful difference → stay quiet, update the snapshot's "last checked" timestamp, don't bother the user.
- Real difference → summarize what changed and notify.
- Update the snapshot with the new content after each check, whether or not it changed.
Quick start
1. Take the baseline snapshot:
python3 << 'PYEOF'
import json, subprocess, hashlib, os
url = "https://example.com/pricing"
raw = subprocess.check_output(['tvly', 'extract', url, '--json'], stderr=subprocess.DEVNULL)
data = json.loads(raw)
content = data['results'][0]['raw_content']
os.makedirs('.tavily', exist_ok=True)
snapshot = {
"url": url,
"content": content,
"hash": hashlib.sha256(content.encode()).hexdigest(),
}
with open('.tavily/monitor_pricing.json', 'w') as f:
json.dump(snapshot, f)
print("Baseline saved.")
PYEOF
2. Set up the recurring check — point whatever recurring-task mechanism is available at the diff script below: an available host scheduling primitive or a configured cron/CI job.
3. Each scheduled run — diff against the saved snapshot:
python3 << 'PYEOF'
import json, subprocess, hashlib
url = "https://example.com/pricing"
path = ".tavily/monitor_pricing.json"
with open(path) as f:
prev = json.load(f)
raw = subprocess.check_output(['tvly', 'extract', url, '--json'], stderr=subprocess.DEVNULL)
data = json.loads(raw)
content = data['results'][0]['raw_content']
new_hash = hashlib.sha256(content.encode()).hexdigest()
if new_hash != prev['hash']:
print(f"CHANGED: {url}")
# Optionally diff prev['content'] vs content and summarize the change in plain English
# (e.g. via a quick tavily-research call or a direct text diff) before alerting the user.
else:
print(f"No change: {url}")
with open(path, 'w') as f:
json.dump({"url": url, "content": content, "hash": new_hash}, f)
PYEOF
Options
| Consideration |
Guidance |
| Cadence |
Match check frequency to how often the thing actually changes — a pricing page doesn't need hourly checks; a live filing tracker might |
| Snapshot storage |
Keep one JSON file per monitored target under .tavily/, named for what it watches |
| Noisy pages |
If a page has content that changes trivially every load (timestamps, ad slots), hash a specific section's content, not the whole page — extract with --query/--chunks-per-source to narrow to the relevant section first |
| What changed |
For a human-readable summary of what changed (not just that it changed), diff the old and new text and optionally run it through tvly research for a plain-English summary |
Tips
- Don't over-schedule. Every check costs an API call — pick a cadence that matches how often the target realistically changes.
- Narrow what you hash. Whole-page hashing catches every cosmetic change (ads, timestamps, view counts) as a "change" — extract just the section that matters when possible.
- Say what kind of change, not just that one happened. "Changed" is a weak alert — "the Pro plan price moved from $49 to $59" is a useful one.
- Be explicit that some external mechanism is doing the scheduling, not a Tavily background service — if the session closes, the loop stops, or the cron/CI job isn't actually wired up, monitoring stops.
See also
- tavily-extract — the underlying content-fetch this skill re-runs on a schedule
- tavily-search — for monitoring a topic broadly rather than one fixed URL
1---2name: watch-for-changes3description: Watch a page, site, or topic for changes on a recurring schedule and only speak up when something meaningfully changed. Use this skill when the user wants to track a competitor's pricing page, watch for regulatory filings, keep an eye on a changelog, or says "monitor this page", "watch for changes", "alert me if X changes", "track this site", or "let me know when this updates". This is an orchestration skill built from Tavily's extract/search plus a recurring-task mechanism — Tavily itself has no scheduling API, so this skill documents that explicitly rather than implying otherwise. The recurring-task step is written generically so it works under any agent/CLI, not just Claude Code.4---56# watch-for-changes78Check something on the web on a recurring cadence, compare it to what you saw last time, and only report back when there's an actual change.910## Before running any command1112If `tvly` is not found on PATH, follow the bundled [CLI setup](../tavily-cli/SKILL.md#setup).1314## Important: this is orchestration, not a Tavily platform feature1516Tavily's API is stateless — it has no built-in scheduling, alerting, or "watch this" endpoint. This skill combines:1718- **Tavily** (`tvly extract` or `tvly search`) for the actual "check the thing" step19- **Some recurring-task mechanism** for the "keep doing this on a cadence" step. Use whatever your environment offers:20 - Any other agent/CLI with its own scheduling or long-running-task primitive: use that21 - No agent-level scheduler available: a plain OS cron job / systemd timer / Windows Task Scheduler entry that re-invokes the agent (or the diff script directly) on the target cadence, or a scheduled CI job (e.g. GitHub Actions `schedule` trigger)2223Be upfront with the user about this — "monitor" here means "something re-runs this check for you on a cadence," not "Tavily is watching this in the background on its own." Ask the user which mechanism is available/preferred if it isn't obvious.2425Keep snapshots in the user's working project or a configured writable data26directory, not inside the installed power. If no scheduler is available, report27that monitoring is not active; a baseline alone does not schedule future checks.2829## When to use3031- Watching a specific URL/page for content changes (pricing, terms, changelog, filing status)32- For a recurring summary of new coverage on a broad topic, use [tavily-search](../tavily-search/SKILL.md) with a suitable time filter and an available scheduler. This skill focuses on change detection.3334## How it works35361. **Baseline:** extract the target page (or run the target search) once, save the content and a hash/fingerprint of it to a local snapshot file.372. **Schedule:** set up a recurring check at the cadence the user wants, using whatever recurring-task mechanism is available (the host's scheduler or a configured cron/CI job).383. **Each run:** re-extract, compare to the saved snapshot.39 - No meaningful difference → stay quiet, update the snapshot's "last checked" timestamp, don't bother the user.40 - Real difference → summarize what changed and notify.414. **Update the snapshot** with the new content after each check, whether or not it changed.4243## Quick start4445**1. Take the baseline snapshot:**4647```bash48python3 << 'PYEOF'49import json, subprocess, hashlib, os5051url = "https://example.com/pricing"52raw = subprocess.check_output(['tvly', 'extract', url, '--json'], stderr=subprocess.DEVNULL)53data = json.loads(raw)54content = data['results'][0]['raw_content']5556os.makedirs('.tavily', exist_ok=True)57snapshot = {58 "url": url,59 "content": content,60 "hash": hashlib.sha256(content.encode()).hexdigest(),61}62with open('.tavily/monitor_pricing.json', 'w') as f:63 json.dump(snapshot, f)6465print("Baseline saved.")66PYEOF67```6869**2. Set up the recurring check** — point whatever recurring-task mechanism is available at the diff script below: an available host scheduling primitive or a configured cron/CI job.7071**3. Each scheduled run — diff against the saved snapshot:**7273```bash74python3 << 'PYEOF'75import json, subprocess, hashlib7677url = "https://example.com/pricing"78path = ".tavily/monitor_pricing.json"7980with open(path) as f:81 prev = json.load(f)8283raw = subprocess.check_output(['tvly', 'extract', url, '--json'], stderr=subprocess.DEVNULL)84data = json.loads(raw)85content = data['results'][0]['raw_content']86new_hash = hashlib.sha256(content.encode()).hexdigest()8788if new_hash != prev['hash']:89 print(f"CHANGED: {url}")90 # Optionally diff prev['content'] vs content and summarize the change in plain English91 # (e.g. via a quick tavily-research call or a direct text diff) before alerting the user.92else:93 print(f"No change: {url}")9495with open(path, 'w') as f:96 json.dump({"url": url, "content": content, "hash": new_hash}, f)97PYEOF98```99100## Options101102| Consideration | Guidance |103|---|---|104| Cadence | Match check frequency to how often the thing actually changes — a pricing page doesn't need hourly checks; a live filing tracker might |105| Snapshot storage | Keep one JSON file per monitored target under `.tavily/`, named for what it watches |106| Noisy pages | If a page has content that changes trivially every load (timestamps, ad slots), hash a specific section's content, not the whole page — extract with `--query`/`--chunks-per-source` to narrow to the relevant section first |107| What changed | For a human-readable summary of *what* changed (not just *that* it changed), diff the old and new text and optionally run it through `tvly research` for a plain-English summary |108109## Tips110111- **Don't over-schedule.** Every check costs an API call — pick a cadence that matches how often the target realistically changes.112- **Narrow what you hash.** Whole-page hashing catches every cosmetic change (ads, timestamps, view counts) as a "change" — extract just the section that matters when possible.113- **Say what kind of change, not just that one happened.** "Changed" is a weak alert — "the Pro plan price moved from $49 to $59" is a useful one.114- **Be explicit that some external mechanism is doing the scheduling**, not a Tavily background service — if the session closes, the loop stops, or the cron/CI job isn't actually wired up, monitoring stops.115116## See also117118- [tavily-extract](../tavily-extract/SKILL.md) — the underlying content-fetch this skill re-runs on a schedule119- [tavily-search](../tavily-search/SKILL.md) — for monitoring a topic broadly rather than one fixed URL