every-app/open-seo已通过检查
SKILL DETAIL
seo-audit
every-app/open-seo/seo-audit
Audit a website and deliver a one-page, plain-language SEO report anyone can act on, centered on a single do-this-week action.
安装量 · 122查看来源
Installation
npx skills add https://github.com/every-app/open-seo --skill seo-audit
技能文件
SKILL.md
最近同步 · 2026年8月30日
SKILL.md›
---
name: seo-audit
description: "Audit a website and deliver a one-page, plain-language SEO report anyone can act on, centered on a single do-this-week action."
---
# OpenSEO SEO Audit
## Goal
Audit a domain and produce a one-page HTML report that anyone, including a complete SEO beginner, can read once and act on. The whole report exists to support ONE action the owner can take this week; everything else is supporting detail.
Use this when asked for an SEO audit or review of a domain, especially when the output is a shareable report for a non-expert. For expert-facing analysis of a competitor or market, use `competitor-analysis` or `competitive-landscape` instead.
## Required inputs
- Domain to audit
- `projectId` (use `list_projects`; if no project matches the domain, create one with `create_project`)
## Project context
The project-context tools are free and shared with the app and other agents.
1. Call `get_project_context` first and ground the report in it — what the business does decides which findings matter and what the one thing should be.
2. This skill needs `business_overview`. If it is empty, run a minimal inline setup: infer what the business does from the site and confirm it with the user in one question, write it back with `update_project_context`, then continue the audit. Never front-load the full interview; suggest `seo-project-setup` at the end for the rest.
3. Before spending credits, check the research log. If the same research ran within the last 30 days, reuse that result and say so instead of re-buying it.
4. On finish, write back what is durable — a corrected `business_overview`, the pages the report singles out via `addKeyPages` — and append a research log entry: `{ appendResearchLog: { summary: "Site audit: <domain>. Verdict: <conclusion>" } }`.
## OpenSEO MCP tools
- `whoami`: confirm connection and remaining credits before spending anything. If OpenSEO is not connected, stop and ask the user to connect it.
- `list_projects` / `create_project`: resolve the `projectId`.
- `run_site_audit`: start the crawl (default page budget). Leave Lighthouse off (its default) — it adds several minutes and this report doesn't need it; pass `runLighthouse: true` only when the user asks for performance/Core Web Vitals depth. Then check `get_audit_status` (the crawl takes a minute or two — wait between checks rather than polling in a loop) and read `get_audit_issues`. Use `get_audit_pages` when per-page evidence helps.
- `get_backlinks_overview`: backlink and referring-domain picture; usually the deciding data for the "one thing".
- `get_domain_overview`: estimated organic traffic and organic keyword count. Skip when the site is clearly dead.
- `research_keywords`: keyword ideas with volume and difficulty, used to propose a starting focus area. One call with 1-3 seeds taken from what the site is actually about. Skip when the site is down.
Keep total spend modest: one audit, one backlinks overview, at most one domain overview, and at most one keyword-research call. Only the overview and keyword lookups spend credits.
## Workflow
1. `whoami`, then resolve the `projectId`.
2. `run_site_audit` for the domain (Lighthouse stays off unless the user asked for performance depth). While it crawls, fetch `get_backlinks_overview`.
3. When the crawl finishes, read `get_audit_issues` (and `get_domain_overview` if the site is alive).
4. If the audit comes back broken or nearly empty (certificate errors, 5xx, one page crawled): investigate before writing. Check the certificate and redirect variants yourself, and search the web for the business. A dead domain often has a live successor site, which flips the whole recommendation to "redirect the old domain".
5. Verify every finding you plan to report against the live page HTML by fetching pages yourself. Report nothing you have not seen evidence for.
6. Decide the one thing. Derive it from the data, never from generic advice. Common patterns:
- Clean site, no backlinks: outreach to guests, partners, or directories, with a ready-to-send message.
- Dead domain, live successor site: permanent redirect via hosting support, with the exact sentence to send them.
- Blocked or noindexed pages: remove the block.
It must be doable this week by a non-technical person, with copy-paste-ready mechanics included.
7. When the site is healthy, propose a starting focus area: run one `research_keywords` call seeded from the site's actual topic, then pick one theme and 3 to 5 specific, low-difficulty keywords the site can realistically rank for, each with the page or post to make. This is a starting direction, not a keyword strategy; point the user at the `keyword-research` skill for the full workflow. Skip this step entirely when the site is down — the one thing is all that matters there.
8. Write the report using `template.html` in this skill directory (see Output format).
9. Review before delivering: run an adversarial pass with a second agent or model if your environment has one, otherwise do a fresh self-review. Give the reviewer the verified facts and have it attack four things: claims beyond the facts, unglossed jargon, anything overwhelming for a beginner, and dramatic language. The reviewer may also flag true facts it was not given; check those against your evidence instead of "fixing" them.
10. Deliver the report: if your environment can publish or preview HTML (for example as an artifact), do that; otherwise save the HTML file and tell the user to open it in their browser.
## Output format
Use `template.html` next to this file. Fill in content; keep the CSS and structure as they are (light palette only, no dark mode).
- Header: domain as the title, the review date on its own line under it, then a 2-3 sentence summary of the whole report (overall state; the main gap and the one thing; what the report covers).
- Section order: verdict, the one thing, small fixes (5 to 10 max, ordered by impact), where to focus first (healthy sites only), already working, method footer.
- Each fix row shows the exact evidence (a quoted tag or number) and concrete steps a non-technical person can follow.
- "Where to focus first" names one topic area and 3 to 5 keywords, each with its search volume in plain words and the page or post to make. Omit the section when the site is down.
## Guardrails
- Tone: calm and plain. No exclamation points, no drama words, no em dashes, no "Not X. Y." contrasts, no filler. Severity words only where literally true (a down site is critical; a long title is not).
- Gloss every term of art in plain English on first use: canonical, meta description, alt text, crawler, 301, structured data.
- Skip nitpicks that do not matter for the specific site. A beginner report with twenty findings has failed.
- Missing backlink or ranking data means "no recorded data", not a penalty; say so rather than dramatizing it.
- Favor keywords the site can win now: specific intent, low difficulty. Do not list head terms a new site cannot rank for yet.
- Separate what the tools reported from what you verified yourself, and note both in the method footer.
template.html›
<!-- SEO audit report template.
Replace ALL-CAPS placeholders and the example rows/items. Keep the CSS and structure.
If your agent publishes HTML through a pipeline that adds its own document wrapper
(for example an artifact viewer), strip this comment and the doctype/head/body tags;
as a standalone file opened in a browser, keep everything. -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DOMAIN SEO review</title>
<style>
:root {
--bg: #e2e9f3;
--ink: #122650;
--muted: #4f5f79;
--rule: #c2cddd;
--rule-strong: #122650;
}
html { background: var(--bg); color-scheme: light; }
body {
background: var(--bg); color: var(--ink);
font-family: Charter, Georgia, "Times New Roman", serif;
line-height: 1.55; margin: 0; padding: 3.5rem 1.5rem 5rem;
}
.page { max-width: 860px; margin: 0 auto; }
.mono {
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
}
h1 {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: 700; font-size: 1.6rem; letter-spacing: -0.01em;
margin: 0.75rem 0 0.25rem; text-wrap: balance;
}
.subtitle { color: var(--muted); margin: 0 0 2.5rem; font-size: 1.02rem; max-width: 46rem; }
.dateline { color: var(--muted); font-size: 0.92rem; margin: 0 0 1.1rem; }
h2 {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: 700; font-size: 1.25rem; margin: 3rem 0 0.75rem;
}
.lede { font-size: 1.05rem; max-width: 46rem; }
section > p { max-width: 46rem; }
hr.heavy { border: 0; border-top: 2px solid var(--rule-strong); margin: 3rem 0 0; }
section .cols:first-of-type { border-top: 1px solid var(--rule); }
.cols {
display: grid; grid-template-columns: minmax(180px, 5fr) 8fr;
gap: 1.25rem; padding: 0.6rem 0; border-bottom: 1px solid var(--rule);
}
.row-title { font-size: 1.12rem; margin: 0; }
.row-title .tag { display: block; margin-top: 0.35rem; }
.cols > div p { margin: 0 0 0.6rem; color: var(--muted); font-size: 0.95rem; }
.cols > div p:last-child { margin-bottom: 0; }
.cols > div p.fix { color: var(--ink); }
.fix b { font-weight: 600; }
code {
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
font-size: 0.85em; word-break: break-word;
}
ol { padding-left: 1.3rem; max-width: 44rem; }
ol li { margin-bottom: 0.5rem; }
ul.plain { list-style: none; padding: 0; max-width: 46rem; }
ul.plain li { padding: 0.5rem 0; border-bottom: 1px solid var(--rule); font-size: 0.98rem; }
ul.plain li:first-child { border-top: 1px solid var(--rule); }
ul.plain .why { color: var(--muted); }
footer { margin-top: 4rem; color: var(--muted); font-size: 0.88rem; max-width: 46rem; }
@media (max-width: 620px) {
.cols { grid-template-columns: 1fr; gap: 0.4rem; }
}
</style>
</head>
<body>
<div class="page">
<header>
<h1>DOMAIN</h1>
<p class="dateline">DATE</p>
<p class="subtitle">SUMMARY: 2-3 sentences covering the whole report. Sentence 1: overall state of the site. Sentence 2: the main gap and the one thing. Sentence 3: what the report covers.</p>
</header>
<section>
<h2>Where the site stands</h2>
<p class="lede">VERDICT-PARAGRAPH: what is working, in plain words.</p>
<p class="lede">VERDICT-PARAGRAPH-2: the main gap the one thing addresses.</p>
</section>
<hr class="heavy">
<section>
<h2>If you only do one thing</h2>
<p class="lede">THE-ONE-THING, one sentence.</p>
<p>WHY-IT-MATTERS, one or two sentences.</p>
<ol>
<li>STEP-1 (concrete, doable today).</li>
<li>STEP-2 (include any copy-paste message in <i>italics</i>).</li>
<li>STEP-3 (how to check it worked).</li>
</ol>
</section>
<section>
<h2>Small fixes, in order</h2>
<!-- one .cols block per finding; 5-10 max; tag = severity word only where literally true -->
<div class="cols">
<div><p class="row-title">FINDING-TITLE <span class="mono tag">low</span></p></div>
<div>
<p>WHAT-WE-FOUND with the exact evidence, e.g. a quoted tag in <code>code</code>.</p>
<p class="fix"><b>Fix:</b> CONCRETE-STEPS a non-technical person can follow.</p>
</div>
</div>
</section>
<section>
<h2>Where to focus first</h2>
<!-- healthy sites only: omit this whole section when the site is down -->
<p>FOCUS-INTRO: the one topic area to build toward and why it fits this site.</p>
<div class="cols">
<div><p class="row-title">KEYWORD <span class="mono tag">N searches/mo</span></p></div>
<div>
<p>WHY-THIS-KEYWORD: who searches it and how winnable it is, in plain words.</p>
<p class="fix"><b>Make:</b> WHAT-TO-CREATE, one page or post and its angle.</p>
</div>
</div>
</section>
<section>
<h2>Already working</h2>
<ul class="plain">
<li>GOOD-THING. <span class="why">Why it matters, one clause.</span></li>
</ul>
</section>
<footer>
<p>Reviewed DATE. DATA-SOURCES, e.g.: crawl and backlink data from OpenSEO; every page also fetched and reviewed individually.</p>
</footer>
</div>
</body>
</html>