AS

avansaber/seo-monster

Developer tools
552 stars 82 forks Quality 93 Trend 42MIT

SEOMonster: a local, user-credential-driven MCP server for SEO workflows over Google Search Console, GA4, PageSpeed Insights, and Cloudflare. Read-first, open source.

Overview

Don't learn another SEO dashboard. Just ask. The open-source SEO analyst that lives inside the AI assistant you already use — working from your own Search Console, Analytics, and PageSpeed data, on your machine. You don't open a new tool — you just ask, in plain English, inside (or Cursor / Cline / Codex):   "What should I write about next?"   Pulls your Search Console and surfaces three topics you're almost ranking for — positions 8–20 with real demand — ranked by opportunity. Say the word and it drafts the brief. across Search Console, GA4, PageSpeed, Cloudflare, AI-citation tracking, keyword discovery, and technical SEO — every one returning the same JSON result envelope, every one driven by your own credentials. No new dashboard to learn; you chat with the assistant you already use. Published on PyPI as (so the command is uvx seo-monster). The import package is seo_mcp; seo-mcp is a dev/local alias.

README


You don’t open a new tool — you just ask, in plain English, inside Claude (or Cursor / Cline / Codex):

You   “What should I write about next?”

🦖 SEOMonster   Pulls your Search Console and surfaces three topics you’re almost ranking for — positions 8–20 with real demand — ranked by opportunity. Say the word and it drafts the brief.

You ask … … SEOMonster does
“What should I write about next?” Surfaces near-ranking topics from your own Search Console demand
“Is this page ready to publish?” Runs the technical-SEO + structured-data checks before you ship
“Get this indexed.” Nudges Google (Indexing API) and Bing / Yandex (IndexNow)
“Did my change actually move rankings?” Before/after attribution vs a matched control group — with a confidence interval, not a guess
“Is ChatGPT recommending us, or our competitors?” Tracks your brand’s share of voice across the AI answer engines

70 tools across Search Console, GA4, PageSpeed, Cloudflare, AI-citation tracking, keyword discovery, and technical SEO — every one returning the same JSON result envelope, every one driven by your own credentials. No new dashboard to learn; you chat with the assistant you already use.

[!NOTE] Published on PyPI as seo-monster (so the command is uvx seo-monster). The import package is seo_mcp; seo-mcp is a dev/local alias. The package ships zero secrets — every credential is resolved at runtime from your own environment or config file.

  • Your data, your machine. User-credential-driven; nothing is sent to any third party.
  • Read-first, safe by default. Reads always work; the two routine writes (sitemap submit, indexing request) are on by default; the Cloudflare write tools (cache purge, redirects, settings, managed robots.txt) are gated behind SEO_MCP_ALLOW_DESTRUCTIVE, and the riskier ones also need a per-call confirm token.
  • Lean. Standard library + the mcp SDK + the Google client libraries; PageSpeed and Cloudflare ride on urllib, no extra HTTP dependency.

Quickstart

[!TIP] Fastest path: the one-click install buttons above. Or add it to any MCP client by hand:

{
  "mcpServers": {
    "seomonster": { "command": "uvx", "args": ["seo-monster"] }
  }
}

Run the one-time Google sign-in once — uvx --from seo-monster seo-monster auth — then ask your assistant to call system_status to confirm what’s connected. Full per-client setup and credentials are in Install and Auth.

How it works

flowchart LR
  U["You — plain English"] --> H["Claude · Cursor · Cline · Codex"]
  H -- "MCP · stdio" --> S["SEOMonster70 tools"]
  S --> GSC["Search Console · GA4"]
  S --> PSI["PageSpeed · CrUX"]
  S --> CF["Cloudflare · IndexNow"]
  S --> AI["AI engines · SERP(optional)"]
  S -. "your creds · your machine" .-> U

SEOMonster is a stdio MCP server: your AI host launches it, it calls Google / Cloudflare / the AI engines with your credentials, and returns a consistent JSON envelope the assistant reads back to you in plain language.

Requirements

For the .mcpb bundle path (Claude Desktop): just Claude Desktop on macOS or Windows. The bundle declares Python 3.11+ as a runtime; Claude Desktop materializes the environment for you. No prior uv install needed.

For the uvx path (Cursor, Cline, Codex, advanced Claude Desktop): Python 3.11 or newer plus uv (which provides uvx). Find the absolute path to uvx with which uvx; GUI hosts do not read your shell profile, so MCP configs need the full path.

Tools

70 tools, grouped by service. All return the same result envelope (see Result envelope). Call system_status first if unsure what is configured. The server also publishes thirteen named workflow prompts.

Cross-service

  • system_status - which services are configured/reachable, the Google auth method and scopes, whether destructive mode is on, the full tool catalog, and the list of registered prompts.

Workflow prompts

The server publishes thirteen named MCP prompts (via prompts/list / prompts/get) that chain the granular tools into common SEO workflows. Hosts that surface prompts (Claude Desktop’s slash menu, Cursor’s command palette, Cline’s prompt picker) advertise them automatically.

Prompt Arguments Chains
post_deploy_verify urls, zone?, skip_psi? cf_purge_cache -> gsc_request_indexing -> indexnow_bulk_submit -> psi_analyze
weekly_review days?, site_url? gsc_compare_periods (gainers + losers via sort_dir) -> gsc_query_opportunities -> gsc_query_gaps -> ga4_organic_search_overview
content_audit site_url?, days?, top_n_queries? gsc_top_queries -> per-query gsc_top_pages_by_query -> cannibalization recommendation
migration_check urls, site_url? gsc_batch_inspect_urls -> gsc_list_sitemaps -> canonical-agreement table -> remediation list
technical_seo_audit url inspect_meta -> check_canonical -> redirect_chain_audit -> mixed_content_check -> robots_txt_validate -> sitemap_health -> severity-ranked triage list
structured_data_audit urls per-URL inspect_schema -> validate_schema -> (if 2+ URLs) hreflang_consistency_check -> per-URL + cross-URL report
pre_deploy_check urls robots_txt_validate -> per-URL inspect_meta -> check_canonical -> validate_schema -> redirect_chain_audit -> mixed_content_check -> deploy-gate verdict (block on critical issues, approve otherwise)
content_brief (v0.7.1) topic, target_query, site_url? gsc_top_pages_by_query -> inspect_meta / inspect_schema on top rankers -> brief with required sections + validation rules
content_outline (v0.7.1) brief outline with rules: >=5 H2, >=70% target-query coverage, H1 has the primary keyword
content_article (v0.7.1) outline, brief article with rules: word count within +/-15%, per-section minimum, internal links, inline JSON-LD hint, no em-dashes
content_workflow (v0.7.1) site_url?, days? content_opportunities -> brief -> outline -> article -> pre_deploy_check -> gsc_request_indexing + indexnow_submit -> scheduled content_performance
content_performance (v0.7.1) url, target_queries?, site_url? gsc_compare_periods + gsc_search_analytics before / after the publish window
seo_setup_audit (v0.7.1) site_url?, property_id? ga4_setup_audit -> cf_settings_audit -> psi_opportunities -> robots_txt_validate -> consolidated stack-config report

Why prompts and not megatools: composability. A failed step inside a megatool poisons the megatool’s envelope and the host loses the ability to retry just the failing leg. Prompts hand the host a recipe; each step’s envelope arrives intact at the LLM.

Install

SEOMonster ships two install paths, both fully local:

  • .mcpb bundle for Claude Desktop. One-click install, GUI form for credentials, secret-typed inputs stored in the OS keychain. Recommended for most users.
  • uvx for Cursor, Cline, Codex, and Claude Desktop power users who prefer to hand-edit MCP config files.

Both paths run the same Python package (seo_mcp) and expose the same 52-tool surface. The difference is only how the host launches the server and how it collects credentials.

Claude Desktop (recommended): .mcpb bundle

Three short steps. The OAuth consent is run once from a terminal (the GUI flow inside Claude Desktop’s MCP subprocess times out before a real user can finish; see Why pre-flight auth? below).

1. Install the bundle. Download seo-monster-0.2.0.mcpb from GitHub releases (or, when listed, from the Claude Directory) and double-click it. Claude Desktop verifies the bundle, runs uv to materialize the Python environment, and shows a configuration form:

Field Type Required Notes
Google OAuth Client Secrets file picker yes Desktop-app client-secrets JSON from Google Cloud Console.
Google OAuth Token Cache Path string yes Defaults to ~/.config/seo-monster/token.json. Written on consent.
GSC Default Property string no e.g. sc-domain:example.com or https://www.example.com/.
GA4 Default Property ID string no properties/123456789 or bare 123456789.
PageSpeed Insights API Key string, secret no Stored in the OS keychain. Strongly recommended (why?).
Cloudflare API Token string, secret no Stored in the OS keychain. Required only for the Cloudflare tools.
Cloudflare Default Zone string no e.g. example.com.
IndexNow Key string, secret no Required only for IndexNow tools. Any 8-128 hex string you generate.
IndexNow Key File URL string no Override the default verification location (https:///.txt).

Fill the fields, click Save, then toggle the extension on. Quit Claude Desktop completely (⌘Q on macOS) and reopen.

2. Run the one-time OAuth consent from a terminal. Before using any Google-backed tool, run:

uvx seo-monster auth

A browser opens. Approve the requested scopes. The command writes token.json to the path you configured (default ~/.config/seo-monster/token.json) with 0600 permissions, then exits. This step is the recommended pattern; it sidesteps the timeout that Claude Desktop imposes on every tool call.

3. Start a new chat in Claude Desktop and use the tools. Click the 🔧 tools icon in the input box; you should see 52 SEOMonster tools. Try system_status first to verify everything is configured.

Why pre-flight auth?

The OAuth installed-app flow opens a local browser and waits for the user to finish the consent screen. Inside Claude Desktop, MCP servers are launched as subprocesses whose tool calls have a ~30-60 second timeout. Real users do not complete browser consent that fast, so the originating call times out, and since every Google tool retries the flow until a token exists, every call times out in turn. Running uvx seo-monster auth once from a terminal puts the token on disk; from that point on, Claude Desktop’s MCP server just reads the cached token and silently refreshes it as needed.

uvx for Cursor, Cline, Codex (and Claude Desktop power users)

uvx runs the published PyPI package seo-monster in an ephemeral environment. Add the snippet for your host below, using the absolute path to uvx (find it with which uvx; GUI hosts do not read your shell profile).

Cursor (~/.cursor/mcp.json or project .cursor/mcp.json)

{
  "mcpServers": {
    "seomonster": {
      "command": "/Users/me/.local/bin/uvx",
      "args": ["seo-monster"],
      "env": {
        "SEO_MCP_GOOGLE_OAUTH_CLIENT": "/Users/me/.config/seo-monster/client_secret.json",
        "SEO_MCP_GOOGLE_TOKEN": "/Users/me/.config/seo-monster/token.json",
        "SEO_MCP_GA4_PROPERTY_ID": "properties/123456789",
        "PSI_API_KEY": "AIza...",
        "CF_API_TOKEN": "..."
      }
    }
  }
}

Cline (cline_mcp_settings.json)

{
  "mcpServers": {
    "seomonster": {
      "command": "/Users/me/.local/bin/uvx",
      "args": ["seo-monster"],
      "env": {
        "SEO_MCP_GOOGLE_OAUTH_CLIENT": "/Users/me/.config/seo-monster/client_secret.json",
        "SEO_MCP_GOOGLE_TOKEN": "/Users/me/.config/seo-monster/token.json"
      },
      "alwaysAllow": ["system_status", "gsc_search_analytics", "ga4_run_report", "psi_analyze"]
    }
  }
}

alwaysAllow lists read tools so Cline does not prompt on each call. Leave the cache-purge tools off so they always prompt.

Codex (~/.codex/config.toml)

[mcp_servers.seomonster]
command = "/Users/me/.local/bin/uvx"
args = ["seo-monster"]

[mcp_servers.seomonster.env]
SEO_MCP_GOOGLE_OAUTH_CLIENT = "/Users/me/.config/seo-monster/client_secret.json"
SEO_MCP_GOOGLE_TOKEN = "/Users/me/.config/seo-monster/token.json"
SEO_MCP_GA4_PROPERTY_ID = "properties/123456789"

Claude Desktop, direct uvx (advanced)

If you prefer to hand-edit claude_desktop_config.json instead of using the .mcpb bundle, the same snippet shape as Cursor above works.

Auth

The four services authenticate independently. Configure only the ones you use; a tool for an unconfigured service returns a clear AUTH_MISSING error rather than failing the server.

Quick setup (recommended): seo-monster setup

Run seo-monster setup once from a terminal. It interactively collects your Cloudflare token, PageSpeed Insights key, IndexNow key, and the default GSC and GA4 properties, validates what it can against the live APIs, and writes them to ~/.config/seo-mcp/config.toml with 0600 permissions. Your MCP host config then needs no secrets in it:

{ "command": "uvx", "args": ["seo-monster"] }

Two things setup does not do, by design:

  • Google OAuth still uses the separate one-time browser step. After setup, run seo-monster auth to complete Google consent (see the next section).
  • It never overrides environment variables. Anything set in your host’s env block still wins over the config file, so CI and Docker keep using env vars.

setup is re-runnable: existing values are shown as defaults and kept when you leave a field blank. The sections below document the per-service env vars, which are what setup writes for you and what CI pipelines can set directly.

This is the lower-friction path: no Cloud service account, no per-property email grants.

  1. In the Google Cloud Console, create (or pick) a project and enable the APIs you will use:
    • Search Console API
    • Indexing API (for gsc_request_indexing)
    • Google Analytics Data API (for the GA4 tools)
    • PageSpeed Insights API (only if you want a PSI key; see below)
  2. Create an OAuth client of type Desktop app and download the client-secrets JSON.
  3. Point the server at it and at a writable token path:
    • SEO_MCP_GOOGLE_OAUTH_CLIENT = path to the client-secrets JSON
    • SEO_MCP_GOOGLE_TOKEN = a writable path where the token will be cached
  4. One-time: run uvx seo-monster auth from a terminal. A browser opens; approve the scopes. The command writes token.json (0600) and exits.
  5. Subsequent runs (server-side) refresh the token silently. The server never opens a browser; if the cached token is missing, tools return AUTH_MISSING pointing back at the auth command.

The signed-in Google account must have access to the Search Console properties and GA4 properties you query.

Token-cache hardening. The cached token is refresh-capable and equivalent to a long-lived credential for the requested scopes. The server writes it with 0600 and its parent directory with 0700. Keep SEO_MCP_GOOGLE_TOKEN under a directory you control (e.g. ~/.config/seo-monster/) and do not put it on a shared filesystem.

Google - service account (advanced, headless)

For fully headless or server deployments where a browser is not available:

  1. Create a service account and download its JSON key.
  2. Set SEO_MCP_GOOGLE_CREDENTIALS (or the standard GOOGLE_APPLICATION_CREDENTIALS) to the key path.
  3. Grant the service-account email access on each property:
    • Search Console: add it as a user on the property.
    • GA4: add it as a Viewer on the property.

If both OAuth and a service account are configured, OAuth is used.

Coverage note. The OAuth installed-app path is exercised in our validation pass and in production-style smoke tests. The service-account path is documented but not independently validated against a live Cloud project. If you hit issues on the SA path, please open an issue.

Scopes (minimal vs full)

The default consent requests the scopes needed for every tool, including the two writes:

Capability Scope
GSC read webmasters (covers readonly)
GSC sitemap submit webmasters
GSC indexing request indexing
GA4 reporting analytics.readonly

If you only want reads, you can consent to a narrower set (webmasters.readonly + analytics.readonly) and simply not call gsc_submit_sitemap / gsc_request_indexing; calling a write tool without its scope returns SCOPE_INSUFFICIENT with remediation, never a crash.

PageSpeed Insights

PSI works without a key in principle, but in practice the anonymous quota is shared across every caller without a key and is frequently exhausted: a single psi_analyze call against the anonymous endpoint often returns RATE_LIMITED. Treat the anonymous mode as a fallback, not the steady state.

To get reliable PSI access:

  1. In Cloud Console, enable the PageSpeed Insights API.
  2. Create an API key (Credentials > Create credentials > API key). It takes a minute. The key is free.
  3. Set PSI_API_KEY (or use the field in the .mcpb configuration form).

The PSI API only accepts the key as a URL query parameter (not a header), so treat PSI keys as low-sensitivity. Scope the key to the PageSpeed Insights API only and attach no other GCP roles.

Cloudflare

Create an API token at dash.cloudflare.com/profile/api-tokens and set CF_API_TOKEN (and optionally CF_ZONE for a default zone). Grant only the permissions you need:

Permission Needed for
Zone: Zone:Read cf_list_zones, cf_zone_info
Zone: DNS:Read cf_list_dns
Account: Account Analytics:Read cf_web_analytics
Zone: Cache Purge:Purge cf_purge_cache, cf_purge_cache_all (only if you enable destructive mode)
Zone: Single Redirect:Edit cf_create_redirect, cf_delete_redirect (only if you enable destructive mode); cf_list_redirects reads with it
Zone: Zone Settings:Edit cf_settings_update (only if you enable destructive mode); cf_settings_audit only needs Zone Settings Read
Account: Account Rulesets:Edit + Account Filter Lists:Edit cf_bulk_redirect_upsert (only if you enable destructive mode)

IndexNow

IndexNow notifies Bing, Yandex, Naver, Seznam, and Yep when a URL is created or updated. Google does not participate, so the IndexNow tools complement rather than replace gsc_request_indexing.

One-time setup

  1. Generate a key. Any 8-128 character string of letters, digits, or hyphens (a-z, A-Z, 0-9, -) per the IndexNow spec. Common patterns: a 32-char lowercase hex string (e.g. python -c "import secrets; print(secrets.token_hex(16))") or any random alphanumeric of similar length. Treat it like an API key; do not commit it.
  2. Configure SEOMonster by setting SEO_MCP_INDEXNOW_KEY to that string (or use the .mcpb configuration form; the field is marked sensitive and lands in the OS keychain).
  3. Host the verification file at https:///.txt. The file body MUST be exactly the key string with no trailing newline, no BOM, no extra whitespace, no HTML wrapper. The Content-Type should be text/plain. Confirm with curl -i https:///.txt before moving on; the response body must be byte-identical to the key.
  4. (Optional) Set SEO_MCP_INDEXNOW_KEY_LOCATION if the verification file lives at a non-standard URL (some CDNs rewrite /key.txt paths). The default location is https:///.txt derived from the URLs you submit, so you usually do not need this.

Same-host constraint

Every URL submitted in one indexnow_submit or indexnow_bulk_submit call must share the same host as the verification file. Mixed-host batches are rejected by IndexNow with HTTP 422; indexnow_bulk_submit enforces this client-side and returns INVALID_INPUT before any network call when it detects mixed hosts.

If you have multiple hosts, host a verification file per host and either make separate calls per host or override SEO_MCP_INDEXNOW_KEY_LOCATION per call (the tool does not currently expose per-call override; set distinct env values per session).

Common errors

Symptom Likely cause
AUTH_INVALID from indexnow_submit Engines could not fetch https:///.txt. Confirm the file returns HTTP 200 with the exact key as the body
INVALID_INPUT from indexnow_bulk_submit mentioning mixed hosts URL list spans multiple hosts; split into per-host batches
RATE_LIMITED Hit IndexNow’s per-host rate cap. Wait before retrying

Verify your setup

After configuring, call system_status to see what is detected. Call it with {"probe": true} to make one cheap live request per configured service and confirm the credentials actually work (GSC lists properties, GA4 runs a 1-row report against the default property, Cloudflare lists one zone, PSI pings the endpoint). With probe off (the default) it does a config-only check and makes no network calls.

Destructive mode

Cache purges affect every visitor, so they are off by default. Set SEO_MCP_ALLOW_DESTRUCTIVE=true to enable cf_purge_cache and cf_purge_cache_all. While off, those tools return DESTRUCTIVE_DISABLED and make no network call.

cf_purge_cache_all (purge the whole zone) carries an extra safeguard: it requires a confirm argument equal to the resolved zone hostname. A missing or mismatched confirm returns CONFIRM_REQUIRED and issues no purge.

The two GSC writes (gsc_submit_sitemap, gsc_request_indexing) are not gated; they are routine, low-blast-radius SEO tasks.

Configuration

Resolution is environment-first, with a TOML file fallback. Environment always wins. The config file is normally written for you by seo-monster setup (with 0600 permissions); you can also write it by hand or set the env vars below.

Env var Service Purpose
SEO_MCP_GOOGLE_OAUTH_CLIENT Google OAuth client-secrets JSON path (recommended).
SEO_MCP_GOOGLE_TOKEN Google Writable cached-token path (OAuth).
SEO_MCP_GOOGLE_CREDENTIALS Google Service-account key path (alternative).
GOOGLE_APPLICATION_CREDENTIALS Google Standard service-account fallback.
SEO_MCP_GSC_DEFAULT_SITE GSC Default property, e.g. sc-domain:example.com.
SEO_MCP_GA4_PROPERTY_ID GA4 Default property, e.g. properties/123456789.
SEO_MCP_DATA_STATE GSC all (default) or final.
PSI_API_KEY PSI PageSpeed Insights API key (optional).
CF_API_TOKEN CF Cloudflare API token.
CF_ZONE CF Default zone hostname.
SEO_MCP_INDEXNOW_KEY IndexNow Shared key for the IndexNow tools (sensitive).
SEO_MCP_INDEXNOW_KEY_LOCATION IndexNow Override default key-file URL (optional).
SEO_MCP_ALLOW_DESTRUCTIVE all true enables cache-purge tools. Default off.
SEO_MCP_CONFIG all Path to the TOML config file.
DATAFORSEO_LOGIN / DATAFORSEO_PASSWORD DataForSEO Optional (v0.9): SERP/PAA, keyword volume/difficulty/intent, competitor gap, Google AIO.
OPENPAGERANK_API_KEY Open PageRank Optional (v0.9): free competitor domain authority.
PERPLEXITY_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY / GEMINI_API_KEY AI engines Optional (v0.9): engines for ai_citation_track (any subset).
GOOGLE_ADS_DEVELOPER_TOKEN / GOOGLE_ADS_CUSTOMER_ID Google Ads Optional (v0.9): volume alt to DataForSEO (needs adwords-scope consent).

Config file fallback at ~/.config/seo-mcp/config.toml (or SEO_MCP_CONFIG):

[google]
oauth_client = "/Users/me/.config/seo-mcp/client_secret.json"
token        = "/Users/me/.config/seo-mcp/token.json"
# credentials = "/Users/me/.config/seo-mcp/sa.json"   # service-account alternative

[gsc]
default_site = "sc-domain:example.com"
data_state   = "all"

[ga4]
property_id  = "properties/123456789"

[psi]
api_key = "AIza..."

[cloudflare]
api_token = "..."
zone      = "example.com"

[server]
allow_destructive = false

# Optional v0.9 providers (discovery + AI/GEO). The free GSC/GA4/HTTP core
# works without any of these; each tool degrades gracefully when unset.
[dataforseo]
# login    = "..."
# password = "..."

[openpagerank]
# api_key = "..."

[ai_engines]
# perplexity = "..."
# openai     = "..."
# anthropic  = "..."
# gemini     = "..."

[google_ads]
# developer_token = "..."   # volume alt to DataForSEO; needs adwords-scope OAuth
# customer_id     = "..."

Result envelope

Every tool returns the same shape. On success:

{ "ok": true, "data": { /* tool-specific */ }, "error": null }

On failure:

{
  "ok": false,
  "data": null,
  "error": {
    "code": "AUTH_MISSING",
    "service": "gsc",
    "message": "No Google credentials found for Search Console.",
    "remediation": "Configure OAuth ... or a service-account key. See README > Auth.",
    "docs_url": "https://seomonster.avansaber.com#auth",
    "details": null
  }
}

Error codes:

Code Meaning
AUTH_MISSING No credential configured for the service.
AUTH_INVALID Credential present but rejected (401/403, bad key, expired).
SCOPE_INSUFFICIENT Token lacks the scope this tool needs.
DESTRUCTIVE_DISABLED A cache-purge tool was called with destructive mode off.
CONFIRM_REQUIRED cf_purge_cache_all called without a matching confirm.
NOT_FOUND Site / property / zone / record not found or not visible.
INVALID_INPUT Argument failed validation (bad date, missing required arg).
RATE_LIMITED Upstream 429.
SERVICE_DISABLED A Google Cloud API is not enabled; details has the activation URL.
UPSTREAM_ERROR Any other non-2xx from an upstream API.

Development

git clone https://github.com/avansaber/seo-monster
cd seo-monster
uv venv && uv pip install -e ".[dev]"
uv run pytest               # offline test suite
uv run seo-monster          # run the server over stdio
uv run seo-monster auth     # one-time OAuth consent (or `uv run seo-mcp auth`)

The package exposes two console-script aliases: seo-monster (canonical, matches the PyPI distribution) and seo-mcp (a v0.1.x dev alias kept for back-compat). Both invoke the same entry point. As of v0.2.0, invoking the server via seo-mcp emits a one-line stderr deprecation notice; nothing on stdout, so the MCP protocol channel is unaffected. Production configs should use seo-monster; the alias will be removed in a future major release.

Tests are fully offline: they mock at the client layer, so no network and no credentials are needed to run them.

Server identity note. Some MCP host UIs display the server name as seo-mcp and the version as the mcp SDK version (e.g. 1.27.1). The server-name string is the value we passed to Server("seo-mcp") and is kept stable for back-compat; the version readout is a quirk of the SDK (create_initialization_options() does not propagate the package version). The package’s real version is in pyproject.toml and seo_mcp.__version__.

Changelog

Release-by-release notes, including the validation checks each version’s external testing pass should cover, live in CHANGELOG.md.

Privacy

SEOMonster runs entirely on your machine and talks only to the upstream APIs you configure. The maintainers do not see any of your data, credentials, queries, or tool calls. See PRIVACY.md for the full statement.

License

MIT. See LICENSE.

View the full README on GitHub

Install

uvx seo-monster
New to MCP? Start with the mcpskill.org guide →

Configuration

{ "mcpServers": { "seomonster": { "command": "uvx", "args": ["seo-monster"] } } }