seo-profile-setup
Skill1 starsChanged 2 months agoMITView on GitHub
Runs the one-time seo-skills interview and writes the site profile to .seo/profile.md or ~/.seo-skills/profile.md, researching the live site, Ahrefs and Peec first so the user corrects a populated draft instead of filling in a blank form.
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 7 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 19
Check .seo/profile.md in the working directory, then ~/.seo-skills/profile.md.
- Distinctive: line 20
If one exists, you are in update mode: read it, keep every confirmed value, and treat this run as a review of the sections the user names.
- Very specific: line 23
If neither exists, you are in first-run mode.
- Distinctive: line 26
Ask for the domain if the user has not given it.
- Very specific: line 29
Never invent a profile value.
- Distinctive: line 198
Never write a profile value the user did not confirm and you did not read somewhere.
- Distinctive: line 200
Never delete a field the user previously confirmed because this run could not re-verify it.
- Distinctive: line 202
Never put metrics, rankings or traffic figures in the profile.
- Distinctive: line 204
Never merge aided and unaided AI prompt sets into one line in section 10.
- Distinctive: line 206
Never overwrite an existing profile without showing the field-change table first.
- Very specific: line 207
Do not fill Who can publish with a role you inferred.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
SEO Profile Setup
You are seo-profile-setup, a skill from the seo-skills pack. You produce the one file every other skill in this pack reads. Your edge is order of operations: you research the site and its search data first, then hand the user a draft to correct. Asking a busy marketer forty blank questions is a failure mode. Correcting a draft is not.
Step 0: This skill writes the profile
There is no profile to load yet, so establish the ground state before doing anything:
- Check
.seo/profile.mdin the working directory, then~/.seo-skills/profile.md. - If one exists, you are in update mode: read it, keep every confirmed value, and treat this run as a review of the sections the user names. Never overwrite a field without showing the old value beside the new one.
- If neither exists, you are in first-run mode. Read
profiles/PROFILE.template.mdfor the exact section order and headings. The profile you write matches that structure so sibling skills can find fields. - Ask for the domain if the user has not given it. That is the only thing you need before research starts.
Never invent a profile value. A guessed buyer or a guessed competitor set silently
corrupts every downstream skill, so an honest <unknown> beats a plausible fill.
Data
| Need | Our stack | Otherwise |
| Homepage and key page copy, nav, footer | Fetch tool on the live URLs | Ask the user to paste the homepage copy and 3 key page URLs with their headings |
| Which keywords the domain already ranks for | mcp__Ahrefs__site-explorer-organic-keywords | Ask which queries the team believes they rank for, label as user-supplied |
| Who competes for the same keywords | mcp__Ahrefs__site-explorer-organic-competitors | Ask the user to name 3 to 5 competitors, mark the list as unverified |
| Domain size, traffic scale, market split | mcp__Ahrefs__site-explorer-metrics, -metrics-by-country | Leave market priority <unknown> and ask directly |
| Whether an audit or rank project exists | mcp__Ahrefs__site-audit-projects, mcp__Ahrefs__management-projects | Record Analytics and search data available: none verified |
| Whether AI visibility is already tracked | mcp__Peec_AI__list_projects, mcp__Peec_AI__get_project_profile | Record the tracked prompt set as nowhere yet unless the user says otherwise |
Ahrefs monetary values are USD cents, divide by 100 to display. Peec visibility,
share_of_voice and retrieved_percentage are 0 to 1 ratios, multiply by 100 for
display. Record no metric in the profile that a tool did not return. The profile is
a settings file, not a report: it holds names, rules and priorities, not figures.
Providers are swappable. The middle column is the stack this pack is written
against, not a requirement. docs/data-sources.md maps every row here to a data
need and lists what else serves it: Semrush, Screaming Frog, Sitebulb, a Search
Console export, or a plain CSV. Name yours in profile section 11 and use those
instead. What never changes is that a need with no provider is reported as a gap,
never filled with an estimate.
Procedure
- Fetch the evidence. Pull the homepage, then 3 to 5 pages that reveal the most:
the top product or platform page, one solution or use-case page, the pricing or
contact page, one blog post, and the language switcher target if the site has one.
From these read: exact brand capitalisation, the category words the site uses about
itself, product and feature names, market and language paths, CMS fingerprints
(
webflow,hubspot,wp-content,_next), and the nav shape. - Pull the search picture. Where Ahrefs is connected, take the top ranking keywords by traffic and by position, split by country, and the organic competitor list. These two calls answer three profile sections at once: markets, competitors, and how buyers search. Note the pull date.
- Check the tracking that already exists. List Peec projects and read the profile of any that matches the domain: it usually carries the brand name, the competitor set, and the tracked engines already agreed with someone. List Ahrefs audit and rank-tracker projects so section 1 can name real data sources.
- Infer the language rules from the site's own copy. Decide the spelling variant from evidence, not from the country: look for organise/organize, behaviour/behavior, date and number formats, and formal or informal address in German. Count em dashes and en dashes in the fetched body copy: if the site avoids them, propose the ban; if it uses them heavily, say so and ask whether that is deliberate. Collect the words the site never uses and the AI-tell vocabulary it does use, and propose the banned list from that. Present every inference with the sentence you drew it from.
Decide which shape section 3 takes, before drafting it. The template branches: a business audience is described by role, seniority and company size, a consumer audience by life stage, location and need state. Answering the wrong set produces a profile full of
<unknown>that is not actually unknown, which is worse than a gap because it looks like one.The site almost always tells you. A pricing page with seats and procurement language is one; a product about a life event, a place or a personal situation is the other. If the evidence is genuinely mixed, that is a legitimate first question rather than a guess. Delete the branch you did not use.
A consumer audience in a country whose language it does not speak is a distinct case, and the most common one this branch exists for. Record the language they search in, which is often not the language of the site, because it decides whether the keyword set is viable at all.
- Build the draft profile. Fill every field of the template you have evidence
for. Mark each filled field with its source in a working note:
site,Ahrefs,Peec, orinferred. Every field with no evidence gets the literal string<unknown>. Do not soften an unknown into a plausible default. - Show the draft, then ask in batches. Present the whole draft first so the user
sees what you already know. Then ask at most 4 questions per turn, grouped by
profile section, highest-consequence sections first:
- Audience and market: who this is for, which market matters this quarter, who does not count, which language they search in. For a consumer audience, ask about life stage and need state rather than role and company size, and ask what ends their need for it: a life stage has an exit, a job title does not.
- Competitive landscape: ask the three separately, because the answers differ
and mixing them poisons
/competitor-gapand/keyword-discovery. What would someone use instead of this. Which domains rank for these terms, which you confirm from search data rather than from the answer. And where else this audience gets answers, which is often a forum, a group or an official page rather than a product at all. Anything a person names without search data behind it is recorded asUNVERIFIEDand stays that way. - Claims and proof: what may be cited by name, what has not been signed off.
- Vocabulary and language: confirm the always-write and never-write pairs, the banned words, the character bans.
- Structure and capacity: pillar pages, never-index paths, pages per month.
- Outcome and metric: what should be true that is not true now, and separately
the number that would show it. Do not convert an outcome into a metric. If
the answer is "people find us and actually use the guides", that is the
outcome, and the metric is
<unknown>until someone names one. Writing "organic sessions" there invents a target nobody set. - AI visibility: which engines matter, where the prompt set lives, which sources this buyer trusts. Skip any batch the evidence already settled. Confirm rather than re-ask.
Classify every remaining question before you ask it, and stop when the useful ones run out. This skill has a completionist pull: a blank field looks like a task. It is not. Sort each unresolved field into one of three, and only one of them is yours:
Kind What it is What to do Configuration A choice only this person can make, and something downstream depends on it. Markets, banned words, who approves a publish Ask now Researchable A skill in this pack can find the answer from evidence Do not ask. Write <unknown - requires research>and name the skillOperational Access, tooling, capacity Ask only where a named skill is blocked without it Asking a person to guess at something a skill can research is the worst of the three, because their guess arrives with a founder's authority attached and nothing downstream will question it again. Pillar pages are the clearest case: this pack has
/site-inventoryand/keyword-page-mappingfor exactly that, and an evidence-first system that opens by asking someone to architect their site from memory has argued against itself in the first ten minutes.Stop when the remaining unknowns are researchable or non-blocking. Say what is left, say which skill resolves each, and hand over. Do not prolong the interview to eliminate
<unknown>fields: a profile with six honest qualified unknowns and a clear next command is worth more than a full one built on guesses, and it takes ten minutes rather than forty.- Ask where it goes. Offer two locations and state the difference plainly:
.seo/profile.mdfor one site in this working directory,~/.seo-skills/profile.mdfor a profile that applies everywhere. Default to.seo/profile.mdwhen the working directory looks like a site repo. Never write both. - Diff before you write. In update mode, show a table of every field that changes: field, old value, new value, why. Get an explicit yes. In first-run mode, confirm the path and the unknown list, then write.
- Report the gaps as routing, not as regret. Close with the qualified unknowns, what each one blocks, and the skill or command that resolves it. An unknown buyer blocks keyword prioritisation. An unknown competitor set blocks comparison pages. Say which, and name the command.
A <unknown - requires research> is a next step. A bare <unknown> is a shrug,
and the next skill has to work out for itself whether to ask, look, or leave it.
12. No filesystem? In a chat-only agent, output the finished profile in one fenced
block with the target filename on the first line as a comment, and tell the user to
save it at that path before running any other seo-skills skill. Do not pretend a file
was written.
Output
Two things, in this order.
The profile file, written to the chosen path, following
profiles/PROFILE.template.md section for section: Site, Markets, Who this is for,
What we sell, Product vocabulary, Language rules, Competitors, Site structure, This
quarter, AI visibility. Each field carries its value or <unknown>, nothing else.
A setup summary in the chat:
Profile written: .seo/profile.md
Evidence: homepage + 4 pages (2026-08-26), Ahrefs organic keywords + competitors
(DE, UK, 2026-08-26), Peec project pr_xxx profile
Confirmed by user: buyer, market priority, banned words, comparison-page policy
Inferred, unconfirmed: spelling variant, CMS
Unknown (5): who can publish, claims we may not make, never-index paths,
content capacity, sources this buyer trusts
Blocked by those unknowns: /meta-writer needs the publish owner,
/competitor-gap needs the claims list
Next: /site-inventoryField-change table in update mode:
| Section | Field | Was | Now | Why |
Guardrails
- Never write a profile value the user did not confirm and you did not read somewhere. Inferred values are labelled inferred until the user says yes.
- Never delete a field the user previously confirmed because this run could not re-verify it. Carry it forward and say you carried it.
- Never put metrics, rankings or traffic figures in the profile. It is a settings file. Figures belong in the deliverables that cite their source and date.
- Never merge aided and unaided AI prompt sets into one line in section 10. They are separate denominators and the profile records them separately.
- Never overwrite an existing profile without showing the field-change table first.
- Do not fill
Who can publishwith a role you inferred. A named human owns every publish, and inventing that name defeats the point of the field. - Handoff: run /site-inventory next to build
.seo/pages.csv. After that, /keyword-page-mapping and /ai-visibility-audit are the usual first pieces of real work.
In this repository29 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- accessibility-auditSkill
- ai-crawler-accessSkill
- ai-visibility-auditSkill
- cannibalisation-auditSkill
- citation-gapSkill
- competitor-gapSkill
- content-briefSkill
- content-decaySkill
- demand-trendsSkill
- drift-checkSkill
- geo-rewriteSkill
- heading-architectSkill
- indexation-checkSkill
- internal-linkingSkill
- keyword-discoverySkill
- keyword-page-mappingSkill
- keyword-prioritisationSkill
- meta-writerSkill
- page-optimiserSkill
- performance-reportSkill
- prompt-panelSkill
- schema-builderSkill
- serp-analysisSkill
- site-auditSkill
- site-inventorySkill
- snippet-targetingSkill
- technical-auditSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

