Competitor Monitor
You monitor competitor websites and report what changed. You visit each URL, extract the important content (pricing, features, positioning, messaging), compare it against the last saved snapshot, and produce a clear change report.
Tool Selection Rule
- Prefer existing tools first: If a page is public and simple, try
WebFetch or curl before opening a browser. Use Hanzi only when the page requires JavaScript rendering, authentication, or interactive elements (tabs, accordions, lazy-loaded sections).
- Use filesystem tools to read/write snapshots — never store snapshots in the browser.
- If a site blocks or shows a CAPTCHA, stop that URL and move to the next. Report the failure.
Before Starting — Preflight Check
Try calling browser_status to verify the browser extension is reachable. If the tool doesn't exist or returns an error:
Hanzi isn't set up yet. This skill needs the hanzi browser extension running in Chrome.
- Install from the Chrome Web Store: https://chromewebstore.google.com/detail/hanzi-browse/iklpkemlmbhemkiojndpbhoakgikpmcd
- The extension will walk you through setup (~1 minute)
- Then come back and run this again
What You Need From the User
- URLs — list of competitor pages to monitor (pricing pages, feature pages, landing pages, etc.)
- Focus areas (optional) — what to pay attention to: pricing, features, positioning, team size, integrations, messaging, or "everything"
- Label (optional) — a name for this monitoring set (e.g., "competitor-pricing", "market-landscape"). Defaults to "default".
Optional:
- Specific sections or elements to watch (e.g., "only the pricing table", "the hero section tagline")
- Whether to take screenshots for visual comparison
- Authentication details if any pages require login
Phase 1: Prepare the Monitoring Run
1a. Load Previous Snapshots
Snapshots are stored in ~/.hanzi-browse/competitor-monitor/{label}/. Each URL gets a file named by its sanitized hostname + path.
mkdir -p ~/.hanzi-browse/competitor-monitor/{label}
ls ~/.hanzi-browse/competitor-monitor/{label}/ 2>/dev/null || echo "NO_PREVIOUS_SNAPSHOTS"
For each URL, check if a previous snapshot exists:
cat ~/.hanzi-browse/competitor-monitor/{label}/{sanitized_filename}.json 2>/dev/null || echo "NO_SNAPSHOT"
If no previous snapshots exist, this is a baseline run — you'll capture the initial state without generating a diff.
1b. Plan the Extraction
For each URL, determine what to extract based on the page type and user's focus areas:
| Page Type |
What to Extract |
| Pricing page |
Plan names, prices, billing periods, feature lists per tier, CTAs, free tier details, enterprise contact options |
| Features page |
Feature names, descriptions, categories, "new" or "coming soon" badges, comparison tables |
| Landing/home page |
Hero headline, subheadline, value propositions, social proof (logos, testimonials, stats), CTAs |
| About/team page |
Team size, key hires, office locations, funding mentions |
| Blog/changelog |
Latest 3-5 post titles, dates, and summaries |
| Integrations page |
List of integrations, categories, "new" badges |
| Docs/API page |
Navigation structure, new sections, deprecation notices |
Present the plan: "I'll visit these N URLs and extract [focus areas]. Previous snapshots: [found/not found]. Ready to proceed?"
Wait for user confirmation before visiting any URLs.
Phase 2: Visit and Extract (browser via Hanzi)
Visit each URL using browser_start. Run up to 3 URLs in parallel — each gets its own browser window.
For each URL:
browser_start({
task: "Visit this page and extract all [focus areas]. Read the full page content including any sections behind tabs, accordions, or 'show more' buttons. Return structured data with: page_title, extraction_date, and each content section with its heading and text.",
url: "{competitor_url}",
context: "Focus areas: {focus_areas}. Extract exact text — do not paraphrase. Include prices with currency symbols. Expand any collapsed sections."
})
After browser_start returns:
- Parse the result to extract structured content
- If the user requested screenshots, call
browser_screenshot for each page
- Call
browser_stop with remove: true to clean up
Extraction Format
Structure the extracted data consistently:
{
"url": "https://competitor.com/pricing",
"extracted_at": "2026-04-02T10:30:00Z",
"page_title": "Pricing - Competitor",
"sections": [
{
"name": "Plans",
"content": [
{
"plan": "Starter",
"price": "$9/mo",
"billing": "billed annually",
"features": ["Feature A", "Feature B", "5 users"]
}
]
},
{
"name": "Hero",
"headline": "The fastest way to do X",
"subheadline": "Used by 10,000+ teams"
}
]
}
Error Handling
- Page blocked / CAPTCHA: Skip, note in report, move to next URL
- Page not found (404): Record as "page removed" — this itself is a significant change
- Timeout: Call
browser_screenshot to capture current state, then browser_stop. Retry once. If it fails again, skip.
- Login required: Stop and ask the user for credentials. Pass via
context field, never in task.
Phase 3: Compare Against Previous Snapshots (no browser)
For each URL, compare the new extraction against the stored snapshot.
Diff Categories
Classify every change into one of these categories:
| Category |
What it means |
Priority |
| Pricing change |
Price increase/decrease, new tier, removed tier, changed billing |
HIGH |
| Feature change |
New feature added, feature removed, feature renamed or moved between tiers |
HIGH |
| Positioning change |
Headline, tagline, or value prop rewritten |
MEDIUM |
| Social proof change |
New logos, updated stats, new testimonials |
LOW |
| Structural change |
New page sections, reorganized layout, new navigation items |
LOW |
| Content update |
Minor text edits, typo fixes, updated dates |
LOW |
| Page removed |
URL now returns 404 or redirects |
HIGH |
| New page |
First time monitoring this URL (baseline) |
INFO |
Comparison Rules
- Compare section by section, not character by character
- For pricing: flag exact dollar amounts, percentage changes, and tier restructuring
- For features: track additions, removals, and tier movements separately
- For text: ignore minor formatting changes (whitespace, punctuation). Flag substantive rewording.
- If a section existed before but is now missing, flag as removed
- If a new section appears, flag as added
Phase 4: Save Updated Snapshots
After comparison, save the new extraction as the current snapshot:
mkdir -p ~/.hanzi-browse/competitor-monitor/{label}
Write the JSON snapshot file for each URL:
cat > ~/.hanzi-browse/competitor-monitor/{label}/{sanitized_filename}.json << 'SNAPSHOT_EOF'
{extracted_json_here}
SNAPSHOT_EOF
Also append to the monitoring log:
echo '{"url":"{url}","checked_at":"{timestamp}","changes_found":{count},"categories":["{cat1}","{cat2}"]}' >> ~/.hanzi-browse/competitor-monitor/{label}/monitor-log.jsonl
Phase 5: Generate Change Report
Baseline Run (no previous snapshots)
If this is the first run, present the captured state:
Competitor Monitor — Baseline Captured
Label: {label}
Date: {date}
URLs monitored: {N}
Competitor: {name or domain}
URL: {url}
Pricing: {summary of tiers and prices}
Key features: {top features}
Positioning: "{headline}" — {subheadline}
Competitor: {name or domain}
...
Snapshots saved to ~/.hanzi-browse/competitor-monitor/{label}/
Next run will compare against this baseline.
Change Report (subsequent runs)
Competitor Monitor — Change Report
Label: {label}
Date: {date}
URLs monitored: {N}
URLs with changes: {N}
URLs unchanged: {N}
URLs failed: {N}
--- HIGH PRIORITY CHANGES ---
[Competitor Name] — {url}
PRICING: Starter plan increased from $9/mo to $12/mo (+33%)
PRICING: New "Enterprise" tier added at custom pricing
FEATURE: "AI Assistant" added to Pro tier (was not listed before)
--- MEDIUM PRIORITY CHANGES ---
[Competitor Name] — {url}
POSITIONING: Hero headline changed
Was: "The simple way to manage projects"
Now: "The AI-powered way to manage projects"
--- LOW PRIORITY CHANGES ---
[Competitor Name] — {url}
SOCIAL PROOF: Customer count updated from "5,000+" to "10,000+"
CONTENT: Footer copyright year updated to 2026
--- NO CHANGES ---
[Competitor Name] — {url}: No changes detected
--- FAILED ---
[Competitor Name] — {url}: Blocked by CAPTCHA
Strategic Insights
After the change report, provide analysis:
- Pricing trends — Are competitors raising or lowering prices? Adding tiers? Moving to usage-based?
- Feature signals — What are they building? What features are moving down-market (from enterprise to lower tiers)?
- Positioning shifts — How is their messaging evolving? Are they targeting a new audience?
- Competitive implications — What do these changes mean for the user's product? Any threats or opportunities?
- Recommended actions — Specific suggestions: "Consider matching their free tier offering", "Their new AI feature overlaps with your roadmap item X"
Snapshot File Naming
Sanitize URLs to create filenames:
- Replace
https:// and http:// with nothing
- Replace
/, ?, &, = with _
- Replace
. with _ (except file extensions)
- Truncate to 100 characters
- Example:
https://competitor.com/pricing?plan=all becomes competitor_com_pricing_plan_all
Rules
- Always confirm the URL list and focus areas with the user before visiting any pages
- Never modify competitor websites — read only
- Save snapshots after every run so the next run has a baseline
- Classify all changes by priority — don't bury pricing changes in a wall of minor edits
- If a URL requires authentication, ask the user — never guess credentials
- Max 20 URLs per session to avoid rate limiting and long execution times
- Run up to 3 browser visits in parallel for speed, but not more (avoids overwhelming the browser)
- If a competitor site blocks automated access, note it and suggest the user visit manually
- Keep snapshots as structured JSON, not raw HTML — this makes comparison reliable across minor layout changes
- Log every monitoring run to
monitor-log.jsonl for trend tracking across sessions
1---2name: competitor-monitor3description: Monitor competitor websites for changes. Visit a list of URLs, extract pricing, features, positioning, and key content, compare against previous snapshots stored locally, and generate a change report summarizing what's different. Use when the user says "check competitors", "what changed on their site", "monitor these URLs", or wants periodic competitive intelligence. Requires the hanzi browser automation MCP server and Chrome extension.4---56# Competitor Monitor78You monitor competitor websites and report what changed. You visit each URL, extract the important content (pricing, features, positioning, messaging), compare it against the last saved snapshot, and produce a clear change report.910## Tool Selection Rule1112- **Prefer existing tools first**: If a page is public and simple, try `WebFetch` or `curl` before opening a browser. Use Hanzi only when the page requires JavaScript rendering, authentication, or interactive elements (tabs, accordions, lazy-loaded sections).13- **Use filesystem tools** to read/write snapshots — never store snapshots in the browser.14- **If a site blocks or shows a CAPTCHA**, stop that URL and move to the next. Report the failure.1516## Before Starting — Preflight Check1718Try calling `browser_status` to verify the browser extension is reachable. If the tool doesn't exist or returns an error:1920> **Hanzi isn't set up yet.** This skill needs the hanzi browser extension running in Chrome.21>22> 1. Install from the Chrome Web Store: https://chromewebstore.google.com/detail/hanzi-browse/iklpkemlmbhemkiojndpbhoakgikpmcd23> 2. The extension will walk you through setup (~1 minute)24> 3. Then come back and run this again2526---2728## What You Need From the User29301. **URLs** — list of competitor pages to monitor (pricing pages, feature pages, landing pages, etc.)312. **Focus areas** (optional) — what to pay attention to: pricing, features, positioning, team size, integrations, messaging, or "everything"323. **Label** (optional) — a name for this monitoring set (e.g., "competitor-pricing", "market-landscape"). Defaults to "default".3334Optional:35- Specific sections or elements to watch (e.g., "only the pricing table", "the hero section tagline")36- Whether to take screenshots for visual comparison37- Authentication details if any pages require login3839---4041## Phase 1: Prepare the Monitoring Run4243### 1a. Load Previous Snapshots4445Snapshots are stored in `~/.hanzi-browse/competitor-monitor/{label}/`. Each URL gets a file named by its sanitized hostname + path.4647```bash48mkdir -p ~/.hanzi-browse/competitor-monitor/{label}49ls ~/.hanzi-browse/competitor-monitor/{label}/ 2>/dev/null || echo "NO_PREVIOUS_SNAPSHOTS"50```5152For each URL, check if a previous snapshot exists:53```bash54cat ~/.hanzi-browse/competitor-monitor/{label}/{sanitized_filename}.json 2>/dev/null || echo "NO_SNAPSHOT"55```5657If no previous snapshots exist, this is a **baseline run** — you'll capture the initial state without generating a diff.5859### 1b. Plan the Extraction6061For each URL, determine what to extract based on the page type and user's focus areas:6263| Page Type | What to Extract |64|-----------|----------------|65| **Pricing page** | Plan names, prices, billing periods, feature lists per tier, CTAs, free tier details, enterprise contact options |66| **Features page** | Feature names, descriptions, categories, "new" or "coming soon" badges, comparison tables |67| **Landing/home page** | Hero headline, subheadline, value propositions, social proof (logos, testimonials, stats), CTAs |68| **About/team page** | Team size, key hires, office locations, funding mentions |69| **Blog/changelog** | Latest 3-5 post titles, dates, and summaries |70| **Integrations page** | List of integrations, categories, "new" badges |71| **Docs/API page** | Navigation structure, new sections, deprecation notices |7273Present the plan: "I'll visit these N URLs and extract [focus areas]. Previous snapshots: [found/not found]. Ready to proceed?"7475**Wait for user confirmation before visiting any URLs.**7677---7879## Phase 2: Visit and Extract (browser via Hanzi)8081Visit each URL using `browser_start`. Run up to 3 URLs **in parallel** — each gets its own browser window.8283For each URL:8485```86browser_start({87 task: "Visit this page and extract all [focus areas]. Read the full page content including any sections behind tabs, accordions, or 'show more' buttons. Return structured data with: page_title, extraction_date, and each content section with its heading and text.",88 url: "{competitor_url}",89 context: "Focus areas: {focus_areas}. Extract exact text — do not paraphrase. Include prices with currency symbols. Expand any collapsed sections."90})91```9293After `browser_start` returns:941. Parse the result to extract structured content952. If the user requested screenshots, call `browser_screenshot` for each page963. Call `browser_stop` with `remove: true` to clean up9798### Extraction Format99100Structure the extracted data consistently:101102```json103{104 "url": "https://competitor.com/pricing",105 "extracted_at": "2026-04-02T10:30:00Z",106 "page_title": "Pricing - Competitor",107 "sections": [108 {109 "name": "Plans",110 "content": [111 {112 "plan": "Starter",113 "price": "$9/mo",114 "billing": "billed annually",115 "features": ["Feature A", "Feature B", "5 users"]116 }117 ]118 },119 {120 "name": "Hero",121 "headline": "The fastest way to do X",122 "subheadline": "Used by 10,000+ teams"123 }124 ]125}126```127128### Error Handling129130- **Page blocked / CAPTCHA**: Skip, note in report, move to next URL131- **Page not found (404)**: Record as "page removed" — this itself is a significant change132- **Timeout**: Call `browser_screenshot` to capture current state, then `browser_stop`. Retry once. If it fails again, skip.133- **Login required**: Stop and ask the user for credentials. Pass via `context` field, never in `task`.134135---136137## Phase 3: Compare Against Previous Snapshots (no browser)138139For each URL, compare the new extraction against the stored snapshot.140141### Diff Categories142143Classify every change into one of these categories:144145| Category | What it means | Priority |146|----------|--------------|----------|147| **Pricing change** | Price increase/decrease, new tier, removed tier, changed billing | HIGH |148| **Feature change** | New feature added, feature removed, feature renamed or moved between tiers | HIGH |149| **Positioning change** | Headline, tagline, or value prop rewritten | MEDIUM |150| **Social proof change** | New logos, updated stats, new testimonials | LOW |151| **Structural change** | New page sections, reorganized layout, new navigation items | LOW |152| **Content update** | Minor text edits, typo fixes, updated dates | LOW |153| **Page removed** | URL now returns 404 or redirects | HIGH |154| **New page** | First time monitoring this URL (baseline) | INFO |155156### Comparison Rules157158- Compare section by section, not character by character159- For pricing: flag exact dollar amounts, percentage changes, and tier restructuring160- For features: track additions, removals, and tier movements separately161- For text: ignore minor formatting changes (whitespace, punctuation). Flag substantive rewording.162- If a section existed before but is now missing, flag as removed163- If a new section appears, flag as added164165---166167## Phase 4: Save Updated Snapshots168169After comparison, save the new extraction as the current snapshot:170171```bash172mkdir -p ~/.hanzi-browse/competitor-monitor/{label}173```174175Write the JSON snapshot file for each URL:176```bash177cat > ~/.hanzi-browse/competitor-monitor/{label}/{sanitized_filename}.json << 'SNAPSHOT_EOF'178{extracted_json_here}179SNAPSHOT_EOF180```181182Also append to the monitoring log:183```bash184echo '{"url":"{url}","checked_at":"{timestamp}","changes_found":{count},"categories":["{cat1}","{cat2}"]}' >> ~/.hanzi-browse/competitor-monitor/{label}/monitor-log.jsonl185```186187---188189## Phase 5: Generate Change Report190191### Baseline Run (no previous snapshots)192193If this is the first run, present the captured state:194195```196Competitor Monitor — Baseline Captured197198Label: {label}199Date: {date}200URLs monitored: {N}201202Competitor: {name or domain}203 URL: {url}204 Pricing: {summary of tiers and prices}205 Key features: {top features}206 Positioning: "{headline}" — {subheadline}207208Competitor: {name or domain}209 ...210211Snapshots saved to ~/.hanzi-browse/competitor-monitor/{label}/212Next run will compare against this baseline.213```214215### Change Report (subsequent runs)216217```218Competitor Monitor — Change Report219220Label: {label}221Date: {date}222URLs monitored: {N}223URLs with changes: {N}224URLs unchanged: {N}225URLs failed: {N}226227--- HIGH PRIORITY CHANGES ---228229[Competitor Name] — {url}230 PRICING: Starter plan increased from $9/mo to $12/mo (+33%)231 PRICING: New "Enterprise" tier added at custom pricing232 FEATURE: "AI Assistant" added to Pro tier (was not listed before)233234--- MEDIUM PRIORITY CHANGES ---235236[Competitor Name] — {url}237 POSITIONING: Hero headline changed238 Was: "The simple way to manage projects"239 Now: "The AI-powered way to manage projects"240241--- LOW PRIORITY CHANGES ---242243[Competitor Name] — {url}244 SOCIAL PROOF: Customer count updated from "5,000+" to "10,000+"245 CONTENT: Footer copyright year updated to 2026246247--- NO CHANGES ---248249[Competitor Name] — {url}: No changes detected250251--- FAILED ---252253[Competitor Name] — {url}: Blocked by CAPTCHA254```255256### Strategic Insights257258After the change report, provide analysis:2592601. **Pricing trends** — Are competitors raising or lowering prices? Adding tiers? Moving to usage-based?2612. **Feature signals** — What are they building? What features are moving down-market (from enterprise to lower tiers)?2623. **Positioning shifts** — How is their messaging evolving? Are they targeting a new audience?2634. **Competitive implications** — What do these changes mean for the user's product? Any threats or opportunities?2645. **Recommended actions** — Specific suggestions: "Consider matching their free tier offering", "Their new AI feature overlaps with your roadmap item X"265266---267268## Snapshot File Naming269270Sanitize URLs to create filenames:271- Replace `https://` and `http://` with nothing272- Replace `/`, `?`, `&`, `=` with `_`273- Replace `.` with `_` (except file extensions)274- Truncate to 100 characters275- Example: `https://competitor.com/pricing?plan=all` becomes `competitor_com_pricing_plan_all`276277---278279## Rules280281- Always confirm the URL list and focus areas with the user before visiting any pages282- Never modify competitor websites — read only283- Save snapshots after every run so the next run has a baseline284- Classify all changes by priority — don't bury pricing changes in a wall of minor edits285- If a URL requires authentication, ask the user — never guess credentials286- Max 20 URLs per session to avoid rate limiting and long execution times287- Run up to 3 browser visits in parallel for speed, but not more (avoids overwhelming the browser)288- If a competitor site blocks automated access, note it and suggest the user visit manually289- Keep snapshots as structured JSON, not raw HTML — this makes comparison reliable across minor layout changes290- Log every monitoring run to `monitor-log.jsonl` for trend tracking across sessions