SEO MCP

SEOエビデンスのためのMCPサーバー — オンページ監査、クロール、GSC、PageSpeed、オプションのSERP

ドキュメント

mcp-server-seo

Rust MCP server for SEO evidence used by Grok Build and Claude Code: on-page audit, robots/sitemap, polite crawl, PageSpeed Insights, Google Search Console, optional paid SERP.

stdio + JSON-RPC via rmcp. No Docker.

Build

cargo build --release
# target/release/mcp-server-seo

Config

Optional: ~/.config/mcp-server-seo/config.toml (see config.example.toml).

mkdir -p ~/.config/mcp-server-seo
cp config.example.toml ~/.config/mcp-server-seo/config.toml
chmod 600 ~/.config/mcp-server-seo/config.toml

Phase 1 tools work with zero keys. GSC needs a service-account JSON; PageSpeed needs a free API key; SERP needs Serper (optional).

Tools (summary)

GroupTools
Foundationstatus, sites_list, site_resolve
On-pagepage_audit (mode=quick|full, target_keyword), page_text, redirect_trace, robots_check, sitemap_*, extract_structured_data, schema_validate, link_check, entity_coverage
Crawl / graphcrawl_run (resumable, seed_sitemap), crawl_report, crawl_results, crawl_diff, sitemap_coverage, sitemap_build, internal_link_graph (true orphans)
Local / architectureurl_architecture_plan, nap_consistency (schema-first), citation_prospects, gbp_audit, gbp_reviews_snapshot, local_audit
Content / KWcontent_brief (SERP-grounded), keyword_research (ranked), keyword_volumes, keyword_intent, keyword_suggest
Authorityauthority_snapshot (free, Open PageRank), backlink_overview (paid, gated)
Performancepagespeed_audit
GSCgsc_*, gsc_opportunities, gsc_trends, log_event
SERP / rankserp_fetch (num, local pack), rank_history (series), rank_watch
Compositespage_snapshot, page_history, audit_page, audit_site, verify_live, rank_diagnosis

Recommended free-first agent playbook (v0.5)

  1. page_audit mode=full (+ target_keyword) on home + key templates
  2. page_text on any page whose copy you need to judge — the audit returns counts, this returns the actual sections
  3. crawl_run with seed_sitemap=trueinternal_link_graph; if coverage.truncated, re-call with resume_crawl_id until the frontier drains, then read true_orphans
  4. local_audit for NAP/GBP/authority/reviews in one pass
  5. authority_snapshot before concluding a clean page "just needs more on-page" — a deficit verdict means links, not polish
  6. serp_fetch once per target query (~$0.001, confirm=YES-PAY) → content_brief reads the stored SERP for PAA questions and competitor-backed H2s
  7. rank_diagnosis when a specific keyword underperforms — ranks indexation vs relevance vs authority vs technical
  8. verify_live after deploy, then log_event so the movement has a cause attached

Weekly loop (schedule from your MCP client — this server runs no daemon)

gsc_trends site=<property> refresh=true      # stores today's snapshot, returns movers
rank_watch action=run confirm=YES-PAY        # re-checks tracked queries

Read movers_up / movers_down next to the events you logged.

New site, no GSC history (~$0.10)

keyword_research seed=<service> geo=<city> mode=all
keyword_volumes keywords=[...] confirm=YES-PAY        # one call, cached 90 days
serp_fetch <top terms> confirm=YES-PAY                # unlocks difficulty + SERP clustering
keyword_research ...                                  # now returns a ranked shortlist
url_architecture_plan / content_brief                 # human approval before publish

Content publish stays in the CMS — this server is evidence + briefs, not a writer.

Safety

  • SSRF: public http(s) only; private/reserved IPv4+IPv6 blocked; redirect hops re-checked
  • sitemap_build: writes only under storage.data_dir (relative out_path)
  • GSC submit: confirm=YES-SUBMIT (sitemaps API — not URL Inspection)
  • Paid SERP: dry_run=true default; confirm=YES-PAY + budget ledger
  • Paid authority (backlink_overview): same gate, separate [authority] budget ledger; dry run makes zero provider calls and the ledger records the provider's actual reported cost
  • Static HTML: rendered: false — use agent-browser for JS

Optional keys (v0.5)

KeyUnlocksCost
authority.open_pagerank_api_keyauthority_snapshot, authority step in local_audit, rank_diagnosis verdicts, keyword difficultyfree (domcop)
authority.dataforseo_login / _passwordbacklink_overview link gap, keyword_volumespay-as-you-go, budget-capped
serp.api_keyserp_fetch / rank_watch → grounds content_brief, keyword difficulty, citation presence checks~$0.001/query
local.places_api_keygbp_reviews_snapshot rating, review velocity, competitor gapfree tier + monthly call cap
gsc.credentials_filegsc_* incl. gsc_trends history and gsc_opportunitiesfree

Verify before trusting the numbers: your SERP provider's credit cost for num > 10 (serp.num_100_multiplier), the DataForSEO keywords.location_code for your country, and current Places API field pricing. All three are config values, not hardcoded.

Do not reimplement

Use sibling MCPs: google-analytics, google-adwords, cloudflare, namecheap, agent-browser.

Clients

Already registered as seo in Grok Build / Claude Code (restart clients after rebuild).

Tests

cargo test --release
./tests/test-stdio.sh

Plan

See PLAN.md (merged Grok + Fable + Kimi + critique amendments).

Module layout (v0.5)

src/
  server/           # thin MCP tool-router only (no SEO logic)
    params.rs       # all tool input schemas
    mod.rs          # SeoServer, shared helpers, chained tool_router()
    handlers/       # #[tool] wrappers grouped by domain, one sub-router per file
                    #   (site, page, crawl, pagespeed, gsc, serp, audit,
                    #    content, authority, local)
  tools/            # business logic per concern
    page/           # parse, og probe, structured data, text extraction, audit
    crawl/          # BFS crawl + report builder
    local/          # nap, citations, gbp, local_audit
    gsc/            # client (JWT) + ops (analytics/inspect/sitemaps)
    authority/      # open pagerank (free) + dataforseo (paid) adapters
    audit/          # composites: page, site, verify_live, rank_diagnosis
    serp_evidence.rs# stored-SERP parser shared by briefs/keywords
    html_dom.rs     # shared HTML extract helpers incl. main-text extraction
    …
  rules/            # pure rules (checklist, schema, patterns, intent, relevance, issue)
  storage/          # SQLite split by domain (crawls, snapshots, spend, authority,
                    #   keywords, gsc, rank, places, events) over one shared conn
  http.rs / config.rs / site.rs / util.rs

Rule: no God files — logic lives under tools/* / rules/*; server/ does not implement SEO algorithms. Shared issue builders live in rules/issue.rs.