Cursor SEO MCP
Cursor SEO MCP (cursor-seo-mcp) is an open-source SEO MCP server for Cursor: AEO, GEO, technical SEO, on-page SEO, crawls, schema, image SEO, and local patches — with evidence JSON, not invented rankings.
Search terms this repo is built for: cursor seo mcp, Cursor MCP SEO, SEO MCP for Cursor, Cursor SEO.
Repository: github.com/engrmaziz/cursor-seo-mcp
License: MIT · Contributing · Code of Conduct · Security
pip install cursor-seo-mcp
cursor-seo-mcp doctor
cursor-seo-mcp audit https://example.com --no-serp
Add Cursor SEO MCP to Cursor (.cursor/mcp.json or Cursor Settings → Tools & MCP):
{
"mcpServers": {
"cursor-seo-mcp": {
"command": "cursor-seo-mcp-server"
}
}
}
No global install? Use uvx (downloads the PyPI package on first run):
{
"mcpServers": {
"cursor-seo-mcp": {
"command": "uvx",
"args": ["--from", "cursor-seo-mcp", "cursor-seo-mcp-server"]
}
}
}
Python import remains seocur (python -m seocur is the same CLI as cursor-seo-mcp).
What is Cursor SEO MCP?
Cursor SEO MCP is a Cursor-first SEO engine exposed as:
- An MCP stdio server (
cursor-seo-mcp-server/seocur.mcp_server) so Cursor can call audit, AEO, GEO, on-page, technical, SERP, Radar, Graph, drift, and images tools. - Cursor Agent Skills in
skills/that tell the agent to run the CLI and trust JSON. - A CLI (
cursor-seo-mcp/python -m seocur) for CI and terminals.
Every score is a list of evidence items (check, evidence, source_url, confidence). When a data source is missing, the component is UNAVAILABLE — Cursor SEO MCP never invents search volume, domain rating, traffic, or rankings.
This is not an official Cursor product. It is an open-source SEO MCP you run locally with Cursor.
Why this exists
Most “AI SEO skill” packs look large (dozens of /seo commands) and then wrap paid APIs (DataForSEO, Firecrawl, Ahrefs, SE Ranking) or print a 0–100 after a single HTML download.
Cursor SEO MCP is a clean-room engine: we implement the jobs those tools advertise, with open data and code you can run offline in CI.
Related work we measured against: seo-skills-ai (MIT). That project is useful, but its public scripts are thinner than the README:
| Their claim | What the public scripts actually do | Cursor SEO MCP |
|---|---|---|
| Full-site audit / 15 agents | One HTML fetch + checkbox heuristics | Multi-page crawl, per-URL evidence |
| Information gain / Google patent | Count % and Title Case words |
Novelty vs fetched SERP competitor bodies (not claimed as a patent) |
| SERP + volume | DataForSEO or empty | DuckDuckGo → Brave/Bing HTML; Google Suggest only; Trends labeled relative |
| Scrape | Firecrawl API key | httpx + optional Playwright |
| Backlinks | Common Crawl stub (UNAVAILABLE) + paid MCP |
Mention search, then verify the href; CDX host sample |
| CWV | PSI / Unlighthouse MCP | Local Lighthouse CLI (--lighthouse) |
| Fixes | Print snippets | Review patches; --apply writes locally with backups |
| Scores | Opaque 0–100 | Weighted passed checks; UNAVAILABLE parts excluded, not zero-filled |
The comparison harness is tests/compare: same fixtures, more named checks than a nine-gate single-page baseline, and JSON must not contain invented search_volume or domain_rating.
What ships
AEO, GEO, on-page, technical, Radar, Graph, drift, images, plus crawl/schema/SERP. Later catalog: Discover RSS, ecommerce, dedicated hreflang, local.
| Command | What it does |
|---|---|
cursor-seo-mcp doctor |
Python, httpx, selectolax, pydantic, ddgs, Pillow; optional Playwright / Lighthouse |
cursor-seo-mcp audit <url> |
Technical + on-page + AEO + GEO + schema + images + crawl + novelty + optional CWV |
cursor-seo-mcp seo <url> |
Page pack: technical + on-page + AEO + GEO + content + schema + images |
cursor-seo-mcp aeo <url> |
AEO — PAA/snippet-shaped answers (not a featured-snippet rank) |
cursor-seo-mcp geo <url> |
GEO — 130–170 word passages, author/dates, llms.txt, AI robots |
cursor-seo-mcp onpage <url> |
On-page — title, H1, canonical, URL slug, keyword placement, links |
cursor-seo-mcp technical <url> |
Technical — HTTPS, headers, indexability, robots, sitemap, mixed content |
cursor-seo-mcp crawl <url> |
BFS crawl, depth, orphans, PageRank on fetched in-site URLs only |
cursor-seo-mcp content <url> |
Page-type word gates, EAV from headings/schema, numeric claims, optional Wikidata |
cursor-seo-mcp schema <url> |
JSON-LD vs vendored schema.org subset; reduced types (FAQPage, HowTo) |
cursor-seo-mcp serp "<q>" |
Open SERP + autocomplete + optional Trends |
cursor-seo-mcp cluster "<seed>" |
Live overlap: ≥4 shared top-10 URLs → one pillar |
cursor-seo-mcp backlinks <host> |
Verified inbound hrefs + Common Crawl CDX sample |
cursor-seo-mcp info-gain <url> |
Same novelty method used inside audit |
cursor-seo-mcp fix <url> |
Generate llms.txt, robots snippet, JSON-LD, meta; --apply is local-only |
cursor-seo-mcp radar keywords |
Radar — Semrush analog: open SERP keyword explorer + crowding heuristic |
cursor-seo-mcp radar gap |
Content gap from competitor SERP occupancy |
cursor-seo-mcp radar ranks |
Local rank snapshots (SQLite) |
cursor-seo-mcp graph profile |
Graph — Ahrefs analog: href-verified link sample + CDX |
cursor-seo-mcp graph intersect |
Referring hosts a competitor has in-sample and you lack |
cursor-seo-mcp drift baseline |
Store an on-page snapshot (title, canonical, robots, schema, words) |
cursor-seo-mcp drift compare |
Diff live (or fixture) HTML vs last local baseline |
cursor-seo-mcp drift history |
List stored snapshots for a URL |
cursor-seo-mcp images <url> |
Image SEO: alt, filenames, dimensions, format, OG; optional WebP optimize |
python -m seocur … accepts the same arguments.
Page-type word gates
A product page is not a blog.
page_type |
Minimum body words |
|---|---|
| article | 800 |
| homepage | 400 |
| product | 300 |
| other | 500 |
Radar and Graph (Semrush / Ahrefs jobs, open data)
Paid suites sell a keyword database and a backlink index. Those private crawls do not exist in open source. Cursor SEO MCP replacements are better on evidence (you can reopen every URL) and honest about coverage.
Radar — keyword & competitor intel (Semrush analog)
| Semrush-style job | Cursor SEO MCP | What we refuse to fake |
|---|---|---|
| Keyword overview / KD / volume | Autocomplete expansion + live SERP + serp_crowding_0_100 |
Google Ads volume, Semrush KD, traffic |
| Keyword gap / content gap | Occupancy: competitor URL in sampled SERP, you absent | Their ranking database |
| Position tracking | SQLite snapshots in .cursor-seo-mcp/ranks.sqlite |
Panel-wide rank history |
cursor-seo-mcp radar keywords "technical seo" --site example.com
cursor-seo-mcp radar gap example.com "technical seo" --competitor rival.com --competitor other.com
cursor-seo-mcp radar ranks example.com --keyword "technical seo"
cursor-seo-mcp radar ranks example.com --history
Crowding is labeled not_semrush_kd / not_ahrefs_kd. Higher = more major properties and homepages in the sample SERP.
Graph — link explorer (Ahrefs analog)
| Ahrefs-style job | Cursor SEO MCP | What we refuse to fake |
|---|---|---|
| Site Explorer / DR | Href-verified mention sample + CDX host coverage | Domain Rating, organic traffic |
| Backlink profile | Anchors, follow vs nofollow, referring hosts in this sample | Full web index |
| Link intersect | Hosts that link to a competitor in-sample and not to you | Ahrefs Link Intersect |
cursor-seo-mcp graph profile example.com
cursor-seo-mcp graph intersect example.com --competitor rival.com
cursor-seo-mcp backlinks remains the lower-level verified-mention command; Graph adds summary + intersect.
Drift — on-page regression
Radar ranks track SERP position. Drift tracks the page itself after deploys: title, canonical, noindex, H1, JSON-LD types, word count, citable passages, hreflang, OG. Snapshots live in .cursor-seo-mcp/drift.sqlite. No baseline → UNAVAILABLE, never an invented diff.
cursor-seo-mcp drift baseline https://example.com/page
cursor-seo-mcp drift compare https://example.com/page
cursor-seo-mcp drift history https://example.com/page
Images — SEO audit, optimize, generate
Markup checks always run: alt, camera filenames, width/height, next-gen URL, og:image, LCP not loading=lazy. Byte size and intrinsic pixels are only reported after a fetch or a local file.
cursor-seo-mcp images https://example.com/page
cursor-seo-mcp images https://example.com/page --optimize --apply --project .
AEO, GEO, on-page, technical
| Pillar | Command | What we measure | What we refuse |
|---|---|---|---|
| AEO | cursor-seo-mcp aeo |
Question headings, lede length, lists/tables, heading ids, answer passages | Featured-snippet or AI Overview placement |
| GEO | cursor-seo-mcp geo |
130–170 word blocks, OG, author/date, llms.txt, AI robots | ChatGPT/Perplexity citation counts |
| On-page | cursor-seo-mcp onpage |
Title, unique H1, canonical, slug, keyword in title/URL/lede, links | CTR, “keyword density” scores |
| Technical | cursor-seo-mcp technical |
HTTPS, headers, noindex, charset, mixed content, robots, sitemap | Invented CrUX / crawl-stats |
| SEO pack | cursor-seo-mcp seo |
All of the above plus content, schema, images | GSC graphs |
Honest limits
- Not Google Ads search volume. Autocomplete is query expansion. Optional
pytrendsis relative interest 0–100. - Not Ahrefs DR or Semrush traffic. Radar crowding and Graph samples are documented heuristics on pages we fetched.
- Google SERP HTML is not scraped (ToS). Engines: DuckDuckGo, then Brave/Bing HTML.
- Lighthouse is lab data, not CrUX field data.
- GSC / GA4 are out of v1. They must never become a score dependency.
- Search engines may block or rate-limit. That is
UNAVAILABLE, not a reason to fabricate rows.
Install Cursor SEO MCP
Requires Python 3.11+.
From PyPI
pip install cursor-seo-mcp
cursor-seo-mcp doctor
Optional JS render: pip install 'cursor-seo-mcp[browser]' then playwright install chromium.
From source (Windows PowerShell)
git clone https://github.com/engrmaziz/cursor-seo-mcp.git
cd cursor-seo-mcp
python -m venv .venv
.venv\Scripts\activate
pip install -e ".[dev]"
cursor-seo-mcp doctor
pytest -q
macOS / Linux
git clone https://github.com/engrmaziz/cursor-seo-mcp.git
cd cursor-seo-mcp
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cursor-seo-mcp doctor
pytest -q
Optional JS render
pip install 'cursor-seo-mcp[browser]'
playwright install chromium
cursor-seo-mcp audit https://example.com --js --no-serp
Optional lab Core Web Vitals
cursor-seo-mcp audit https://example.com --lighthouse --no-serp
If lighthouse / npx lighthouse is missing, the CWV component is UNAVAILABLE.
CLI reference
JSON goes to stdout. Exit 0 for OK / PARTIAL / UNAVAILABLE, 1 for hard errors.
cursor-seo-mcp --help
cursor-seo-mcp --version
python -m seocur --help
python -m cursor_seo_mcp --help
Audit
cursor-seo-mcp audit https://example.com
cursor-seo-mcp audit https://example.com --max-pages 15 --no-serp
cursor-seo-mcp audit https://example.com --js --lighthouse
cursor-seo-mcp audit https://example.test/page --html-file tests/fixtures/good_article.html --no-dns
cursor-seo-mcp audit https://example.com --html-out report.html --json-out report.json
Other commands
cursor-seo-mcp crawl https://example.com --max-pages 25
cursor-seo-mcp aeo https://example.com
cursor-seo-mcp geo https://example.com
cursor-seo-mcp onpage https://example.com
cursor-seo-mcp technical https://example.com
cursor-seo-mcp seo https://example.com
cursor-seo-mcp serp "cursor seo mcp"
cursor-seo-mcp cluster "technical seo"
cursor-seo-mcp radar keywords "technical seo" --site example.com
cursor-seo-mcp graph profile example.com
cursor-seo-mcp drift compare https://example.com/page
cursor-seo-mcp images https://example.com/page --optimize --apply --project .
cursor-seo-mcp backlinks example.com
cursor-seo-mcp fix https://example.com --apply --project .
--apply copies backups under .cursor-seo-mcp/backups/ and writes llms.txt / robots / JSON-LD snippets locally. Never run --apply against a remote server.
Common flags
| Flag | Meaning |
|---|---|
--js |
Playwright HTML (audit/crawl) |
--lighthouse |
Local Lighthouse (audit) |
--no-serp |
Skip live SERP / competitor fetch |
--no-dns |
Skip DNS (fixtures, some offline flows) |
--html-out PATH |
Write the HTML evidence report |
--json-out PATH |
Write the same JSON as stdout |
How scoring works
- Each component produces
EvidenceItems. - Component score =
100 * (sum of weights of passed checks) / (sum of weights). - Overall
health_score= weighted average of components that are notUNAVAILABLE. score_partial: truemeans at least one provider was skipped.- Critical failures stay in
critical_issues.
Architecture
seocur/ Python engine (imports stay `seocur`)
cursor_seo_mcp/ `python -m cursor_seo_mcp` entry
skills/ Cursor Agent Skills (Cursor SEO MCP)
.cursor/skills/ Workspace orchestrator
.cursor/mcp.json MCP server id: cursor-seo-mcp
seocur/mcp_server.py SEO MCP stdio (`cursor-seo-mcp-server`)
tests/fixtures/ Offline HTML / SERP samples
tests/compare/ Beats checkbox-style baseline; no invented metrics
Safety (seocur/safety.py, seocur/robots.py): http/https only; DNS fail-closed; private IPs blocked; redirects re-checked; robots.txt unless SEOCUR_RESPECT_ROBOTS=0; per-host delay.
Environment
| Variable | Role |
|---|---|
CURSOR_SEO_MCP_OUT_DIR or SEOCUR_OUT_DIR |
Report/backup directory (default ./.cursor-seo-mcp) |
SEOCUR_USER_AGENT |
HTTP User-Agent |
SEOCUR_TIMEOUT |
Request timeout seconds |
SEOCUR_RATE_LIMIT |
Seconds between hits per host |
SEOCUR_ALLOWED_HOSTS |
Comma-separated host allowlist |
SEOCUR_MAX_REDIRECTS |
Redirect cap |
SEOCUR_RESPECT_ROBOTS |
0 to ignore robots.txt |
Cursor SEO MCP — skills
Skills live in skills/. The orchestrator is skills/cursor-seo-mcp: run cursor-seo-mcp … and do not fabricate GSC/Ahrefs numbers.
Tests
pytest -q
CI runs Python 3.11–3.13. Tests use fixtures; they must not require paid keys or a live SERP.
Roadmap
Discover / Media RSS, ecommerce schema depth, dedicated hreflang maps, local/maps (open data). Optional free GSC/GA4 OAuth stays optional.
Contributing
See CONTRIBUTING.md. By participating you agree to the Code of Conduct.
- Bugs: issue template
- Features: issue template
After you rename the GitHub repo, set About to: Cursor SEO MCP — open-source SEO MCP server for Cursor (AEO, GEO, technical & on-page) and topics: cursor, seo, mcp, cursor-seo-mcp, aeo, geo.
License
MIT © 2026 Cursor SEO MCP Contributors.
seo-skills-ai is cited as related work only. Their code is not vendored here.
Metadata
Release files for cursor-seo-mcp 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| cursor_seo_mcp-0.3.0.tar.gz | 73.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cursor_seo_mcp-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 153.9 kB
Release files / cursor_seo_mcp-0.3.0.tar.gz
| Download URL | cursor_seo_mcp-0.3.0.tar.gz |
|---|---|
| Size | 73.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dd49e8acd729dc647720c5c1ab107bc53249a0786f0ad49141cb8b34c8c868ef
|
|
BLAKE2b-256 checksum How to use checksums |
3a19633ba33aa636eeb39d4a161b65c9afbad4db8788f7b445695ca107f6e72b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Release files / cursor_seo_mcp-0.3.0-py3-none-any.whl
| Download URL | cursor_seo_mcp-0.3.0-py3-none-any.whl |
|---|---|
| Size | 80.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cee38b64a4056a4c90adc18b211057c65a4e252d1f985b8192faf25404a837b2
|
|
BLAKE2b-256 checksum How to use checksums |
3940d3333fcfe89b13d4f9454c5a0f7c7d2ca6c7a8c432b8e32e47be5b72a273
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Security for cursor-seo-mcp 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.