Skip to content
Agentmart
Submit a tool

seo-audit

Daily on-page and technical SEO audit of every page on a site - discovers URLs from the sitemap, scores each page, adds cross-page checks (duplicate titles…

Skill by aeonfun

IndexedMIT★ 782
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/aeonfun-seo-audit

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Daily on-page and technical SEO audit of every page on a site - discovers URLs from the sitemap, scores each page, adds cross-page checks (duplicate titles, canonicals, sitemap gaps), diffs against yesterday, and sends the score line plus any regressions

Use cases: security, marketing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/seo-audit

What's inside

Skill name
seo-audit
Description
Daily on-page and technical SEO audit of every page on a site - discovers URLs from the sitemap, scores each page, adds cross-page checks (duplicate titles, canonicals, sitemap gaps), diffs against yesterday, and sends the score line plus any regressions
License
MIT
Metadata
var: · mode: read-only · title: SEO Audit · category: dev
Instructions
379 lines in SKILL.md · view on GitHub

Agent Skills spec issues

  • files: referenced but missing: scripts/seo-audit.mjs, scripts/skill_mode.sh, scripts/notify_format.py

Files (2)

  • SKILL.md
  • checklist.md · references/

SKILL.md (first lines)

Today is ${today}.

> **${var}** — the target **sites**, comma-separated (an origin, not a page:
> `https://www.example.com`). Each site is audited whole and independently. A
> bare host gets `https://` prepended. A path in `${var}` (`…/docs`) still works
> — its origin is what gets crawled.
>
> **Empty `${var}` → there is nothing to audit.** This skill has no built-in
> default site (it ships general-purpose). Log `SEO_NO_TARGET`, send **no**
> notification, and exit clean — a daily "set a target" ping would just get
> muted. Set the target once in the dashboard (the skill's `var`) and it runs
> from the next tick.

## What this does

Discovers every page a site publishes, audits all of them, compares the result
against the previous run, and reports. The heavy lifting (discovery, fetching,
parsing, checking) happens in `scripts/seo-audit.mjs`, which returns
machine-readable findings so you reason over facts instead of eyeballing HTML.

Discovery is sitemap-first: `robots.txt` → `sitemap.xml` (following sitemap
indexes), honouring the robots `*` `Disallow` rules, falling back to a one-hop
crawl of the homepage's internal links when a site has no sitemap. That is the
same list Google works from, so auditing it is auditing what actually ranks.

Auditing the whole site — not three sample templates — is what makes the
cross-page checks possible: duplicate titles, duplicate meta descriptions,
canonicals pointing away from their own page, and pages linked but missing from
the sitemap. None of those are visible from inside a single page, and all of
them are ways a site quietly loses search traffic.

This is on-page and technical SEO only — no keyword research, rank tracking, or
backlink analysis. If a finding would need those, say so rather than guessing.

## Capability notes (read before editing this skill)

This skill is `mode: read-only`, and that is load-bearing:

- The auditor is **Node, not Python**, because `Bash(node:*)` is in the read-only
  capability base while `Bash(python3:*)` is write-tier only
  (`scripts/skill_mode.sh`). Porting it back to Python would force `mode: write`.
- It is **dependency-free stdlib Node**, matching every other helper in
  `scripts/`. There is no install step. If you find yourself wanting a package,
  you are about to break the thing that makes this skill cheap and safe.
- **You have no Write or Edit tool.** Every file this skill produces is written
  with a shell redirection (`>`/`>>`) from an allowed command. The workflow's
  read-only guard reverts writes to code/config paths but **preserves `memory/`
  and `output/`**, which is exactly where this skill writes.
- The guard also appends the `### seo-audit` run-log entry from your final
  output, so put the log detail there (step 8), never a second self-written entry.

`PAGESPEED_API_KEY` is optional. When set, the script folds in Core Web Vitals —
it reads the env var itself, so **never pass the key as a command-line argument**;
the workflow's permission analyzer blocks `$SECRET` expansions on the Bash line.
It prefers **real-user field data** (Chrome UX Report p75 — LCP, **INP** since it
replaced FID in 2024, and CLS — the metrics Google's page-experience signal
actually uses), preferring page-level then origin-level, and falls back to the lab
Lighthouse score only when a URL has too little traffic for field data (the
finding says which). In site mode it samples the entry page only (PageSpeed is
slow and quota-limited; per-page Lighthouse runs would dominate the runtime). When
unset, Core Web Vitals are simply absent. That is a degraded run, not a failed one
— don't mention the missing key in the notification.

## Workflow

1. **Resolve the targets.** Split `${var}` on commas and trim. No confirmation
   step — this runs unattended, so treat `${var}` as final. **If `${var}` is
   empty, there is no site to audit:** log `SEO_NO_TARGET` (Step 8), send no
   notification, and exit. Do not invent a default origin.

2. **Audit each site:**

   ```bash
   node scripts/seo-audit.mjs --site <origin> --format json
   ```

   Useful flags: `--max N` (page cap, default 50) and `--concurrency N`
   (default 4 — politeness as much as speed). Add `--check-links` on the
   **first** site only; it probes up to 40 links and is the slow part. In site
   mode links are deduped across every page first, so a footer link is checked
   once for the whole site rather than once per page.

   A site where no page could be fetched returns `"ok": false` and exits 1.
   Record it and keep going — one dead site must not abort the others. Individual
   pages that fail are reported inside the run as the `pages_fetched` finding.

3. **Read the findings, don't re-derive them.** The report has two levels:
   - `pages[]` — one per URL, each with its own `score`, `summary`, and
     `findings` (same `check` / `status` / `message` / `detail` shape as before).
   - `site_findings[]` — the cross-page checks: `pages_fetched`,
     `duplicate_titles`, `duplicate_descriptions`, `canonical_targets`,
     `sitemap_coverage`.

   The headline `score` is the **mean page score**, and `discovery` records how
   the URLs were found (`sitemap` or `crawl`), how many existed, how many were
   audited, and whether the `--max` cap truncated the run.

4. **Diff against the previous run.** Every run writes its own timestamped
   snapshot (step 5), so the baseline is the **newest snapshot that already
   exists** — i.e. the previous run's, since this run hasn't written its own yet.
   Filenames sort chronologically, so:

   ```bash
   PREV=$(ls -1 memory/seo-audit/*.json 2>/dev/null | sort | tail -1)
   ```

   `$PREV` is the baseline (empty on the very first run). Match pages **by URL**,
   per site, and compare:
   - **New fails** — a check that was `pass`/`warn` yesterday and is `fail` today.
   - **Site score movement** — any change of 3+ points, either direction.
   - **New / removed pages** — URLs in today's sitemap that weren't in
     yesterday's, and vice versa. A page vanishing from the sitemap is a real
     finding; so is a new page shipping with no meta description.
   - **New cross-page problems** — a title or description that became a
     duplicate, a canonical that started pointing elsewhere.
   - **Newly broken links** — URLs in `broken_links` that were not there before.
   - **Fixed** — a check that was `fail`/`warn` yesterday and is `pass` today.
     Report these too; a skill that only ever delivers bad news gets muted.

From aeonfun/aeon, MIT.

More from aeonfun/aeon

Signals

Stars
782
Forks
292
Open issues
0
Last commit (this folder)
Oct 1, 2026 (26 days ago)
Last release
Jul 9, 2026 (3 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from aeonfun

Cite this page

seo-audit skill. Agent Mart. https://agentmart.dev/skills/aeonfun-seo-audit (last updated 2026-10-24)