OpenSEO Competitor Analysis
Analyze one competitor deeply enough to decide what to learn from, avoid, counter-position against, or outrank. Findings merge into brand/competitors.md — mktg's competitor memory that competitive-intel maintains qualitatively and this skill now grounds in measured rows.
On Activation
- Catalog + binding:
mktg catalog info openseo --json --fields configured + .seo/openseo.json. No OpenSEO → hand off to competitive-intel (Exa qualitative), labeling metrics unknown.
- Brand grounding: read
brand/competitors.md + brand/positioning.md (tolerate templates). If the competitor isn't named, ask — never guess the domain.
OpenSEO MCP Tools
get_domain_overview: baseline organic traffic + keyword count (both domains when comparing).
get_ranked_keywords: exact keyword/URL/rank/intent/traffic rows. Use maxRank, minSearchVolume, excludeBrandTerms, resultTypes filters to keep rows relevant.
get_backlinks_overview: backlink/referring-domain profile (may be unavailable — continue without it).
find_serp_competitors: validate the named competitor actually overlaps in search.
get_serp_results: head-to-head SERP checks for the important shared terms.
get_search_console_performance: when comparing to the user's domain and GSC is connected, the USER's baseline is first-party — never estimate your own side from third-party data.
research_keywords: expand gap terms.
Workflow
get_domain_overview for the competitor (and the user's domain when comparing).
get_ranked_keywords for the competitor with sensible filters; same for the user, or get_serp_results for shared terms when a lighter check suffices.
find_serp_competitors when the supplied competitor's search overlap is unclear.
- Group keywords into themes: product/category, alternatives/comparisons, templates/tools, educational guides, branded demand.
get_backlinks_overview when authority appears to explain rankings.
get_serp_results for the important head-to-head terms.
- Synthesize the plan: what they do well, where they're vulnerable, which pages/keywords to pursue, what NOT to copy.
- Merge into
brand/competitors.md (preserve existing sections; date the entry; confirm before overwriting populated competitor entries).
- Hand off:
competitor-alternatives for "X vs Y" pages, seo-content for gap-driven briefs, openseo-keyword-clustering for page mapping.
Output Format
Start with: snapshot, biggest lesson, best opportunity to beat them. Then:
| Area |
Competitor pattern |
Evidence |
OpenSEO opportunity |
Anti-Patterns
- Treating every competitor keyword as desirable — because ranking for a term and PROFITING from a term are different things; filter through positioning before anything lands in a plan.
- Inferring page-level content strategy from keyword rows alone — because a keyword list can't tell you WHY a page works (structure, depth, format). Use SERP/web evidence for page-level claims.
- Estimating the user's own performance from third-party data when GSC exists — because first-party clicks/impressions/position are free and exact; third-party estimates of your own site are the worst data in the room.
- Recommending "copy what they do" — because imitation pages lose to the original on authority and freshness. Recommend a stronger angle on the same intent, never a replica.
- Separating evidence from inference nowhere — because "they rank for X" (evidence) and "their content strategy is Y" (inference) carry different confidence and must read differently in
brand/competitors.md.
Close the loop
After writing files, log completion so mktg plan / mktg status count the work (bare mktg run only logs loaded):
mktg run openseo-competitor-analysis --complete --writes <paths written> --result success --json
Adapted from every-app/open-seo .agents/skills/competitor-analysis (MIT). Workflow upstream; mktg brand-memory writes and handoff wiring added here.
1---2name: openseo-competitor-analysis3description: Deep-dive ONE competitor's organic footprint — exact ranking keywords and URLs, content themes, backlink profile, and exploitable gaps — with findings written into brand/competitors.md. Use this skill when the user names a competitor and wants to know what to learn from them, counter, or outrank, including head-to-head comparisons against the user's own domain. For market-level mapping first, use openseo-competitive-landscape. Triggers: "analyze competitor", "competitor keywords", "competitor backlinks", "beat <competitor>", "competitor seo teardown".4---56# OpenSEO Competitor Analysis78Analyze one competitor deeply enough to decide what to learn from, avoid, counter-position against, or outrank. Findings merge into `brand/competitors.md` — mktg's competitor memory that `competitive-intel` maintains qualitatively and this skill now grounds in measured rows.910## On Activation11121. **Catalog + binding**: `mktg catalog info openseo --json --fields configured` + `.seo/openseo.json`. No OpenSEO → hand off to `competitive-intel` (Exa qualitative), labeling metrics `unknown`.132. **Brand grounding**: read `brand/competitors.md` + `brand/positioning.md` (tolerate templates). If the competitor isn't named, ask — never guess the domain.1415## OpenSEO MCP Tools1617- `get_domain_overview`: baseline organic traffic + keyword count (both domains when comparing).18- `get_ranked_keywords`: exact keyword/URL/rank/intent/traffic rows. Use `maxRank`, `minSearchVolume`, `excludeBrandTerms`, `resultTypes` filters to keep rows relevant.19- `get_backlinks_overview`: backlink/referring-domain profile (may be unavailable — continue without it).20- `find_serp_competitors`: validate the named competitor actually overlaps in search.21- `get_serp_results`: head-to-head SERP checks for the important shared terms.22- `get_search_console_performance`: when comparing to the user's domain and GSC is connected, the USER's baseline is first-party — never estimate your own side from third-party data.23- `research_keywords`: expand gap terms.2425## Workflow26271. `get_domain_overview` for the competitor (and the user's domain when comparing).282. `get_ranked_keywords` for the competitor with sensible filters; same for the user, or `get_serp_results` for shared terms when a lighter check suffices.293. `find_serp_competitors` when the supplied competitor's search overlap is unclear.304. Group keywords into themes: product/category, alternatives/comparisons, templates/tools, educational guides, branded demand.315. `get_backlinks_overview` when authority appears to explain rankings.326. `get_serp_results` for the important head-to-head terms.337. Synthesize the plan: what they do well, where they're vulnerable, which pages/keywords to pursue, what NOT to copy.348. Merge into `brand/competitors.md` (preserve existing sections; date the entry; confirm before overwriting populated competitor entries).359. Hand off: `competitor-alternatives` for "X vs Y" pages, `seo-content` for gap-driven briefs, `openseo-keyword-clustering` for page mapping.3637## Output Format3839Start with: snapshot, biggest lesson, best opportunity to beat them. Then:4041| Area | Competitor pattern | Evidence | OpenSEO opportunity |42| ---- | ------------------ | -------- | ------------------- |4344## Anti-Patterns4546- **Treating every competitor keyword as desirable** — because ranking for a term and PROFITING from a term are different things; filter through positioning before anything lands in a plan.47- **Inferring page-level content strategy from keyword rows alone** — because a keyword list can't tell you WHY a page works (structure, depth, format). Use SERP/web evidence for page-level claims.48- **Estimating the user's own performance from third-party data when GSC exists** — because first-party clicks/impressions/position are free and exact; third-party estimates of your own site are the worst data in the room.49- **Recommending "copy what they do"** — because imitation pages lose to the original on authority and freshness. Recommend a stronger angle on the same intent, never a replica.50- **Separating evidence from inference nowhere** — because "they rank for X" (evidence) and "their content strategy is Y" (inference) carry different confidence and must read differently in `brand/competitors.md`.5152## Close the loop5354After writing files, log completion so `mktg plan` / `mktg status` count the work (bare `mktg run` only logs `loaded`):5556```bash57mktg run openseo-competitor-analysis --complete --writes <paths written> --result success --json58```596061---6263*Adapted from [every-app/open-seo](https://github.com/every-app/open-seo) `.agents/skills/competitor-analysis` (MIT). Workflow upstream; mktg brand-memory writes and handoff wiring added here.*