
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
@digestseo/mcp-geo
Advanced tools
Self-hostable MCP server for AI visibility tracking across ChatGPT, Claude, Perplexity, Gemini, Grok, and Google AI Overviews. Free OSS with an optional EUR 99 one-time AI Visibility Audit for teams that want a client-ready baseline.
Runs locally over stdio with your own API keys — all data stays on your machine (see Privacy Policy). Set at least one engine key (OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, PERPLEXITY_API_KEY, XAI_API_KEY, SERPAPI_API_KEY); engines without a key skip gracefully.
Runtime: Node.js 22.13+ (CI exercises Node 22 and 24).
Claude Desktop / any MCP client (npx):
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"],
"env": {
"OPENAI_API_KEY": "sk-...",
"GEMINI_API_KEY": "your_key_here"
}
}
}
}
ChatGPT (remote MCP): ChatGPT does not connect directly to local STDIO MCP servers. For ChatGPT, use the self-hosted remote MCP setup below, or the OpenAI Secure MCP Tunnel setup for a server running on a local/private machine. The public geo-mcp.digestseo.com/mcp endpoint is not a turnkey no-key fresh-scan service.
Claude Code:
claude mcp add --transport stdio digestseo -s user --env GEMINI_API_KEY=your_key_here -- npx -y @digestseo/mcp-geo
Or install the same local MCP integration through this repository's owner-controlled Claude Code marketplace:
/plugin marketplace add AKzar1el/mcp-geo
/plugin install digestseo-geo@digestseo-mcp
The marketplace plugin uses the repository's .mcp.json to launch npx -y @digestseo/mcp-geo. Zero provider keys are enough for tool discovery; for engine-backed scans, make only the provider keys you want available to the Claude Code process. The direct claude mcp add command above remains the simplest option when you want to attach provider keys explicitly to the server configuration.
Codex CLI:
codex mcp add digestseo -- npx -y @digestseo/mcp-geo
The zero-key command is enough for tool discovery. Add only the provider keys you want with repeated --env NAME=VALUE options before the -- when engine-backed scans are needed.
Amp CLI:
amp mcp add digestseo -- npx -y @digestseo/mcp-geo
Amp runs this as a local STDIO MCP server. The zero-key command is enough for tool discovery; before engine-backed scans, make only the provider keys you want available to the Amp process or configure them in Amp's local MCP env settings instead of committing secrets. See Amp's current MCP guide.
OpenCode v2:
opencode mcp add digestseo --global -- npx -y @digestseo/mcp-geo
OpenCode v2 runs this as a local STDIO server. Omit --global for project-only configuration; add only the provider keys you want with --env NAME=VALUE before the --. Zero keys still allow MCP tool discovery.
Mistral Vibe Code: add mcp-geo to the user-level ~/.vibe/config.toml or project-level ./.vibe/config.toml:
[[mcp_servers]]
name = "digestseo"
transport = "stdio"
command = "npx"
args = ["-y", "@digestseo/mcp-geo"]
The zero-key entry is enough for tool discovery. For engine-backed scans, pass only the provider keys you want through Vibe's STDIO environment configuration or the environment inherited by Vibe instead of committing secrets. Use /mcp digestseo (or /mcp) in Vibe to verify the server and tools. See Mistral's current MCP server guide and Vibe configuration reference.
GitHub Copilot CLI:
copilot mcp add digestseo -- npx -y @digestseo/mcp-geo
The base install starts with zero provider keys so tool discovery works. Add only the engine keys you want with Copilot CLI's --env NAME=VALUE option before running scans.
Qoder CLI:
qoder mcp add digestseo -- npx -y @digestseo/mcp-geo
qoder mcp list
Qoder launches this as a local STDIO MCP server. The zero-key command is enough for tool discovery; make only the provider keys you want available to the Qoder process before engine-backed scans. If Qoder is already running, use /mcp reload to rediscover the server and tools. See Qoder's current MCP server guide and MCP reference.
Docker Agent: Docker Agent can launch local STDIO MCP servers directly from agent YAML. Add this toolset to the agent that should use mcp-geo:
toolsets:
- type: mcp
command: npx
args: ["-y", "@digestseo/mcp-geo"]
The zero-key form is enough for tool discovery. For engine-backed scans, add only the provider keys you need under the toolset's env: map (Docker Agent supports ${env.NAME} expansion) instead of committing secret values. See Docker's current local MCP tool documentation.
goose: add mcp-geo as a local STDIO extension in ~/.config/goose/config.yaml (macOS/Linux) or %APPDATA%\Block\goose\config\config.yaml (Windows):
extensions:
digestseo-geo:
type: stdio
name: digestseo-geo
enabled: true
cmd: npx
args: ["-y", "@digestseo/mcp-geo"]
timeout: 300
The zero-key extension is enough for tool discovery. Before engine-backed scans, configure only the provider environment variables you want for this extension through goose's extension settings / secret storage instead of putting raw API keys in the YAML file. The same server can also be added interactively with goose configure -> Add Extension -> Command-Line Extension. See goose's current extension setup and configuration reference.
GitLab Duo CLI: current GitLab Duo CLI releases can consume Claude-compatible plugin marketplaces directly. Register this repository and install the existing digestseo-geo plugin:
glab duo plugin marketplace add https://github.com/AKzar1el/mcp-geo.git
glab duo plugin install digestseo-geo@digestseo-mcp
The installed plugin loads the same local npx -y @digestseo/mcp-geo MCP server from .mcp.json. Zero provider keys allow discovery; make only the provider keys you want available to the GitLab Duo CLI process before engine-backed scans.
Factory Droid:
droid mcp add digestseo "npx -y @digestseo/mcp-geo"
droid mcp list
Droid runs this as a local STDIO MCP server. The zero-key install is enough for tool discovery; add only the provider keys you choose in Droid's user-level MCP configuration before engine-backed scans. Keep provider secrets out of project-level .factory/mcp.json files.
Amazon Q Developer (IDE): open the Q Developer chat panel ? Tools ? +, choose STDIO, name the server digestseo, set Command to npx, and add Arguments -y and @digestseo/mcp-geo. Add only the provider environment variables you want before running scans; zero keys still allow MCP tool discovery.
JetBrains AI Assistant (IDE): open Settings > Tools > AI Assistant > Model Context Protocol (MCP) > Add, choose STDIO, and use:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}
JetBrains AI Assistant supports local STDIO and NPX MCP servers. The zero-key form is enough for tool discovery; before engine-backed scans, make only the provider keys you want available to the IDE process, or import an already-configured Claude MCP server.
JetBrains Air: this repository already ships the standard root .mcp.json that launches npx -y @digestseo/mcp-geo. In Air, open Settings > AI > MCP Servers, enable MCP support and Launch workspace MCP servers, then use the Workspace scope so Air reuses that checked-in file. The repository config contains no provider secrets and is sufficient for zero-key tool discovery. Engine-backed scans still require the selected provider keys in the local server process environment; keep them out of committed .mcp.json. See the JetBrains Air MCP server guide.
Visual Studio 2022 17.14+ / Visual Studio 2026: Visual Studio uses its own servers-shaped MCP configuration. Create %USERPROFILE%\.mcp.json for a user-wide install or <SOLUTIONDIR>\.mcp.json for one solution:
{
"servers": {
"digestseo": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}
Open GitHub Copilot Chat in Agent mode and use the Tools menu to verify digestseo is available. Zero provider keys are enough for tool discovery; before engine-backed scans, make only the provider keys you want available to the Visual Studio process rather than committing secrets into the solution file. See Microsoft's current Visual Studio MCP setup.
Cursor:
Windsurf: open Manage MCPs → View raw config and add the local stdio package:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"],
"env": {
"OPENAI_API_KEY": "sk-..."
}
}
}
}
Use only the provider keys you want; zero keys still allow MCP tool discovery.
Roo Code: open MCP Servers > Edit Global MCP, or create .roo/mcp.json for a project-scoped install, and add:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}
Roo Code supports local STDIO MCP servers. The zero-key form is enough for tool discovery; add only the provider keys you want before scans. On Windows, if Roo cannot launch npx directly, use "command": "cmd" with "args": ["/c", "npx", "-y", "@digestseo/mcp-geo"], matching Roo's documented Windows fallback.
VS Code: Install the local stdio server in VS Code. The base install starts with no provider keys so tool discovery works; add only the API keys you want in your VS Code MCP user configuration before running scans.
LM Studio: Add the local stdio server to LM Studio. The base install starts with no provider keys so tool discovery works; add only the API keys you want in LM Studio's mcp.json before running scans.
Kiro: for a one-click local install, or open the user MCP config (
~/.kiro/settings/mcp.json) / workspace config (.kiro/settings/mcp.json) and add the local stdio package manually:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}
Kiro supports local STDIO MCP servers across its current surfaces. The zero-key form is enough for discovery; add only the provider environment variables you want before engine-backed scans. For remote use, self-host the Worker below and configure your own deployed /mcp URL instead. The public geo-mcp.digestseo.com/mcp endpoint is not a turnkey no-key fresh-scan service.
Claude Desktop extension (one-click): download the .mcpb bundle from the latest release and double-click it — Claude Desktop prompts for the API keys.
First run: ask your client to "track acme.com as brand acme, then refresh it" — track_brand creates the brand with generated prompts, refresh_brand runs the first scan, check_visibility shows the scores.
AI agents installing this server: follow llms-install.md. Prefer a remote server with cron auto-refresh? Self-host on Cloudflare Workers below.
mcp-geo is an open-source AI visibility tracker that measures how often your brand is cited by ChatGPT, Claude, Perplexity, Gemini, Grok, and Google AI Overviews. It's the GEO (Generative Engine Optimization) and AEO (Answer Engine Optimization) equivalent of Google Search Console — built as an MCP server so you can query your AI visibility data directly inside ChatGPT through a configured remote MCP app, Claude.ai, Claude Desktop, Claude Code, GitHub Copilot CLI, Cursor, Codex CLI, or any MCP-compatible client.
Canonical product page: DigestSEO mcp-geo — AI Visibility MCP Server
Engineering case study: DigestSEO MCP Suite — AI visibility, Search Console, web validation, and trend intelligence
Need a client-ready baseline without running the stack yourself? The mcp-geo AI Visibility Audit is EUR 99 one time: one brand, up to three competitors, 20 buyer-intent prompts, checks across up to five supported AI surfaces where configured providers return usable results, citation evidence, and a prioritized action memo. The open-source package remains free.
See proof first: Open the sample report generated through mcp-geo to see the output style and evidence depth before requesting the audit.
Ready to request it? Open a prefilled email with your brand/domain and up to three competitors. No subscription or sales call is required.
Payment handoff: After fit and scope are confirmed, I reply with the normal invoice/payment instructions.
Methodology: The same 20 buyer-intent prompts are run as a point-in-time diagnostic and reported per engine, with citation/source evidence where available. The audit is an observed snapshot, not a proprietary ranking promise or guaranteed forecast.
Want the protocol before buying? Read the AI Visibility Audit methodology, including scope, engine coverage, interpretation limits, and what the audit does not claim.
Prefer zero setup? Try the hosted version at digestseo.com — managed Cloudflare infra, no API keys to manage, multi-brand, scheduled refresh, web UI. Waitlist now open. Join waitlist →
Connect via MCP, ask Claude "Run an AI visibility analysis on [my brand]", and within 90 seconds you get a strategist-quality memo grounded in real per-engine data:
View the full report including content gaps, engine recommendations, and synthesis →
Want to reproduce the same evidence-first structure with your own data? Use the reusable AI Visibility Audit report prompt.
The report above was generated by Claude through the digestseo-mcp MCP server. The conversation chained five hosted tools — visibility.check, visibility.compare, visibility.citations (Perplexity + Claude), and visibility.content_gaps — to produce a 4-engine analysis with citation excerpts and a 3-recommendation strategy memo.
set_prompts to replace a brand's active prompts with 1-50 agreed buyer questions while preserving historical runs; repeated identical sets are a no-op.gemini-3.1-flash-lite, avoiding the Gemini 2.5 access restriction Google applies to some new projects while preserving the same GenerateContent integration.list_prompts to review the exact active buyer-intent prompt set for a tracked brand without regenerating or changing it.track_brand, list_brands, and generate_prompts, matching the actual stdio server exposed after install.better-sqlite3 native binaries; local storage uses built-in node:sqlite on Node.js 22.13+.https://geo-mcp.digestseo.com/audit.@digestseo/mcp-geo with synchronized Worker, MCP Registry, and MCPB metadata.visibility.* namespaces with typed input/output schemas; local stdio tool names remain flat.mcp-geo-db D1 configuration, Cursor and Claude Code plugin metadata, and patched production dependency pins.npx -y @digestseo/mcp-geo): the same MCP tools backed by a local SQLite database (~/.digestseo/digestseo.sqlite) — no Cloudflare account needed. Engines run inline with your own API keys.track_brand, list_brands, generate_prompts. Workers deployments keep these behind the X-Seed-Secret-gated /admin/* routes.src/core/) shared by the Worker and the CLI, with a Db contract implemented by D1 and better-sqlite3 adapters. All 0.2.1 accuracy and security fixes carry over to both runtimes.server.json, MCPB desktop extension (.mcpb bundle), Dockerfile, llms-install.md for AI agents, release-publish workflow.CONNECT_SECRET gate on the OAuth flow. By default the OSS build auto-completes /authorize for any MCP client that knows your worker URL — anyone who finds the URL can connect and call visibility.refresh, spending your engine API credits. Set CONNECT_SECRET and the browser step of the connect flow now asks for it before issuing a token. See SECURITY.md.acme no longer matches "acmeshop"), and linked-citation checks require the exact domain or a subdomain (notacme.com no longer counts as a link to acme.com).aliases and exclude_terms. Aliases always count as a mention; exclude terms suppress the bare-word match on the brand name and domain root — so "Monday" the brand stops matching "monday" the weekday, while monday.com still counts. Apply migrations/0005_brand_alias_exclude.sql; existing brands behave exactly as before.visibility.history consistency. Partially-finished runs now count toward history (matching visibility.check's 0.2.0 behavior), and fully-failed runs no longer show up as fake zero scores.tsc --noEmit plus a pure-function unit suite (npm run test:unit) covering mention matching, citation extraction, and score aggregation on every push.SEED_SECRET / CONNECT_SECRET./admin/run-live now creates one runs row per engine and self-fetches /admin/run-engine once per engine. Each engine runs in its own worker invocation with its own free-plan 50-subrequest budget — a single-invocation fan-out used to burst past the cap mid-run and lose half the rows.env.SELF) dispatches the per-engine fan-out through Cloudflare's internal fabric instead of a public-URL fetch, dodging the "Worker called itself" guard (error 1042) that silently blocks the latter.prompt_responses (ok / failed / skipped) plus error_message. Failed engine calls used to write raw_response='ERROR: ...' rows that downstream scoring treated as real zero-mention hits; now they're explicitly excluded./admin/run-engine INSERT OR IGNOREs its runs row before persisting — D1 is eventually consistent across edge regions, and the upstream INSERT INTO runs from /admin/run-live doesn't always replicate before the downstream engine call lands. The IGNORE makes the FK happy either way.UPDATE runs SET status='completed' in a single D1.batch() call. Drops the per-invocation subrequest count from ~89 to ~26.getLatestCompletedRun anchors on EXISTS(ok rows) instead of status='completed', so partially-finished runs still surface their data in MCP tool output instead of silently disappearing.POST /admin/cleanup-failed-runs for one-shot deletion of legacy polluted rows after migrating to 0004.gpt-4o-mini), Claude (claude-haiku-4-5), Perplexity (sonar), Gemini (gemini-2.5-flash-lite), and Google AI Overviews (via SerpAPI).visibility.check, visibility.history, visibility.compare, visibility.citations, visibility.content_gaps, visibility.refresh.refresh_frequency (daily/weekly).See the example report above for what this looks like in practice.
The six analysis capabilities are shared across both transports, but the exposed MCP names are intentionally transport-specific: hosted/Worker connections use the visibility.* namespace, while the local stdio package uses flat names.
| Hosted / Worker | Local stdio | What it does | What you provide |
|---|---|---|---|
visibility.check | check_visibility | Latest AI visibility snapshot across all configured engines for a tracked brand, with per-engine scores, winning prompts, and losing prompts. | brand_id, optional engines[] filter |
visibility.history | get_visibility_history | Time-series history of overall and per-engine visibility, bucketed daily or weekly. | brand_id, optional days (default 30), optional granularity (daily/weekly) |
visibility.compare | compare_competitors | Share-of-voice comparison against competitor domains, with prompts you win and prompts they win. | brand_id, optional competitor_domains[], optional days |
visibility.citations | get_citations | The actual citation events — prompt, engine, response excerpt, citation type, brand URL when present. | brand_id, optional days, optional engine filter |
visibility.content_gaps | get_content_gaps | Prioritized Claude-Haiku-generated content recommendations targeting your losing prompts. | brand_id, optional max_recommendations (1-10) |
visibility.refresh | refresh_brand | Manually trigger a fresh scan across every engine whose API key is set. | brand_id, optional engines[] filter |
The local stdio CLI (npx, desktop extension, Docker) additionally provides brand management — on a Workers deployment the same operations live behind the X-Seed-Secret-gated /admin/* routes instead:
| Tool (local CLI only) | What it does | What you provide |
|---|---|---|
track_brand | Start tracking a brand: creates it locally and generates its buyer-intent prompt set (Claude Haiku when ANTHROPIC_API_KEY is set, three starter prompts otherwise). | brand_id, name, domain, optional category, competitors[], aliases[], exclude_terms[], prompt_count, refresh_frequency (daily/weekly, default weekly) |
list_brands | List tracked brands with domains, competitors, and active prompt counts. | — |
list_prompts | Inspect the exact active buyer-intent prompts for a tracked brand without changing them. | brand_id |
set_prompts | Replace the active prompt set with exact user-supplied buyer questions while preserving historical runs. | brand_id, prompts[] (1-50 unique questions) |
generate_prompts | Regenerate a brand's prompt set via Claude Haiku (replaces active prompts, keeps history). | brand_id, optional count (default 20) |
Engines are opt-in. Pick the ones you want; the rest skip silently.
gpt-5-search-api) with web search. OpenAI currently bills web search at $10 per 1,000 calls plus model token charges; see API pricing and API keys.gemini-3.1-flash-lite). Google currently offers free-tier token usage for this model, while paid usage is token-priced. Rate limits vary by model, project, and usage tier, and Google says actual capacity can vary; check your project's active limits in AI Studio rather than relying on a fixed RPM/RPD assumption. See Gemini pricing and rate limits.grok-4.6) with required Web Search grounding. xAI currently prices Web Search at $5 per 1,000 calls plus model tokens. console.x.ai · pricingRecommended starting pair: OpenAI + Anthropic (Claude). OpenAI provides grounded ChatGPT visibility through web search and bills search calls plus model tokens; Anthropic also powers prompt generation and content-gap analysis. Review current provider pricing before estimating recurring scan cost. Add Gemini, Perplexity, Grok, or SerpAPI deliberately once you want more coverage; Gemini capacity varies by model, project, and usage tier, and Google AI Overviews often returns no result (scored as a zero), so leading with the cheapest path can skew your first run.
The deploy is 6 commands and takes about 5 minutes. See SETUP.md for the full walkthrough with explanations and troubleshooting, or follow the quick version below.
# 1. Install deps
npm install
# 2. Log in to Cloudflare
npx wrangler login
# 3. Copy the config template
cp wrangler.example.jsonc wrangler.jsonc
# 4. Create KV namespace + D1 database, paste each printed id into wrangler.jsonc
npx wrangler kv namespace create OAUTH_KV
npx wrangler d1 create mcp-geo-db
# 5. Set the required secret + at least one engine API key
# Recommended starting pair — OpenAI uses web search plus model tokens; check current pricing:
npx wrangler secret put SEED_SECRET
npx wrangler secret put CONNECT_SECRET # recommended — gates who can connect (see SECURITY.md)
npx wrangler secret put OPENAI_API_KEY # ChatGPT engine
npx wrangler secret put ANTHROPIC_API_KEY # Claude engine + prompt generation
# 6. Apply migrations and deploy
npx wrangler d1 migrations apply mcp-geo-db --remote
npx wrangler deploy
After deploying your own Worker, use that deployment's /mcp URL as the
remote endpoint, for example:
https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp
Use your configured Worker URL for directory or client integrations. The
public geo-mcp.digestseo.com/mcp endpoint is not a no-key hosted substitute
for a deployment with engine provider credentials.
After wrangler deploy finishes, you get a URL like
https://digestseo-mcp.YOUR-SUBDOMAIN.workers.dev.
Settings → Connectors → Add custom connector. Paste:
https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp
Complete the OAuth handshake. The connector turns green when ready.
ChatGPT custom MCP apps connect to remote MCP servers, so use the /mcp URL
from your configured Worker deployment above. In ChatGPT, enable Developer
Mode/custom apps for your workspace and add that remote MCP URL. Availability
depends on your ChatGPT plan and workspace admin policy; OpenAI's current MCP
support does not require special search or fetch tool names.
https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp
OpenAI Secure MCP Tunnel is the supported bridge when you want ChatGPT to use
the local stdio package without exposing it as a public HTTPS server. Create a
tunnel in OpenAI Platform first, then keep tunnel-client running on the same
machine that launches mcp-geo. You need a tunnel ID, a tunnel runtime API key,
and ChatGPT developer-mode/tunnel permissions for the target workspace.
Make whichever provider keys you want to use available to the mcp-geo process, then initialize a tunnel profile with the local package command:
tunnel-client init --sample sample_mcp_stdio_local --profile digestseo --tunnel-id tunnel_0123456789abcdef0123456789abcdef --mcp-command "npx -y @digestseo/mcp-geo"
tunnel-client doctor --profile digestseo --explain
tunnel-client run --profile digestseo
While tunnel-client run is healthy, create a developer-mode app in ChatGPT,
choose Tunnel as the connection type, and select that tunnel. This path is
for private/local use; it does not publish mcp-geo as a public ChatGPT app.
Follow OpenAI's current Secure MCP Tunnel guide for tunnel creation, permissions, downloads, and troubleshooting.
claude mcp add --transport http digestseo https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp
Then run /mcp inside Claude Code to complete the OAuth handshake in your browser.
Edit your Claude Desktop config:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.json{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp"
]
}
}
}
Restart Claude Desktop after editing.
Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp"
]
}
}
}
Restart Cursor.
Add to ~/.codex/config.toml:
[mcp_servers.digestseo]
command = "npx"
args = [
"-y",
"mcp-remote",
"https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp",
]
| Variable | Required | Default | Description |
|---|---|---|---|
OPENAI_API_KEY | opt-in | unset | Enables the ChatGPT engine. Without it, ChatGPT is skipped. |
ANTHROPIC_API_KEY | opt-in | unset | Enables the Claude engine and the Claude-Haiku-powered prompt generator + content-gap analyzer. |
GEMINI_API_KEY | opt-in | unset | Enables the Gemini engine. Rate limits vary by model, project, and usage tier; check the project's active limits in Google AI Studio (see Troubleshooting). |
PERPLEXITY_API_KEY | opt-in | unset | Enables the Perplexity Sonar engine. Paid only. |
XAI_API_KEY | opt-in | unset | Enables the Grok engine (grok-4.6) with required Web Search grounding. |
SERPAPI_API_KEY | opt-in | unset | Enables the Google AI Overviews engine (via SerpAPI). |
SEED_SECRET | yes | unset | Shared secret that gates every /admin/* route. Pick a high-entropy string. |
CONNECT_SECRET | recommended | unset | When set, the OAuth connect flow asks for this secret in the browser before issuing a token. Without it, anyone who knows your worker URL can connect an MCP client. See SECURITY.md. |
TURNSTILE_SITE_KEY | no | unset | Reserved for forks that add a public /check form. Unused by the OSS build. |
TURNSTILE_SECRET_KEY | no | unset | Same — reserved for forks. |
All values are set via wrangler secret put VAR in production or .dev.vars locally. None are stored in wrangler.jsonc.
flowchart LR
C["MCP client<br/>(Claude.ai / Claude Code / Cursor / ...)"] -- "MCP over HTTP + OAuth" --> W["Cloudflare Worker<br/>digestseo-mcp"]
CRON["Cron Trigger<br/>every 6h"] --> W
W --> DO["GeoMcpAgent<br/>(Durable Object, 6 MCP tools)"]
W -- "one self-fetch per engine<br/>via SELF service binding" --> RE["/admin/run-engine<br/>(own invocation per engine)"]
RE --> E1["OpenAI"]
RE --> E2["Anthropic"]
RE --> E3["Gemini"]
RE --> E4["Perplexity"]
RE --> E5["xAI<br/>(Grok)"]
RE --> E6["SerpAPI<br/>(AI Overviews)"]
RE --> DB[("D1<br/>brands / prompts / runs /<br/>responses / cache")]
DO --> DB
Each engine runs in its own Worker invocation with its own free-plan 50-subrequest budget; results are flushed in a single D1.batch() per engine. The whole system fits the Cloudflare free tier for a single brand on a daily cadence.
/admin/* is gated by SEED_SECRET (constant-time compared)./mcp requires OAuth; set CONNECT_SECRET so only people with the secret can complete the connect flow — strongly recommended whenever your worker URL is shared anywhere, since connected clients can call visibility.refresh and spend your engine API credits.Full details and vulnerability reporting: SECURITY.md.
The example report above was generated by the first prompt below.
Once the connector is live in Claude.ai (or any MCP client), try:
| Tool | Example prompt |
|---|---|
visibility.check | "How visible is brand_id acme on AI right now?" |
visibility.history | "Show me the visibility trend for acme over the last 60 days, daily." |
visibility.compare | "Compare acme against asana.com and monday.com over the last 14 days." |
visibility.citations | "Show me real Perplexity citations for acme from the last week." |
visibility.content_gaps | "What content should acme publish to close its visibility gap? Give me the top 5." |
visibility.refresh | "Refresh acme across every available engine right now." |
visibility.refresh | "Refresh acme but only for Gemini and Claude." |
If you'd rather not run your own Cloudflare account, manage API keys, or pay individual engine bills, the hosted version of DigestSEO runs the same MCP server on managed infrastructure with multi-brand support, scheduled refresh, a web UI, and consolidated billing. Waitlist now open — join at digestseo.com.
wrangler secret list and add the keys you intend to use. Engines without keys are silently skipped, which can leave visibility.check with no data.no engines available error in logs — no engine API keys are set at all. Set at least one of OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, PERPLEXITY_API_KEY, XAI_API_KEY, SERPAPI_API_KEY.npx wrangler d1 migrations apply mcp-geo-db --remote (and also --local for wrangler dev). For ad-hoc fixes, npx wrangler d1 execute mcp-geo-db --remote --file=migrations/0001_initial.sql./mcp. The OAuth handshake auto-completes in the OSS build (single dev user); if you set CONNECT_SECRET, the browser step shows a one-field form — enter the secret you set during deploy. If it loops, clear the connector and re-add it. Double-check the Worker is publicly reachable (curl https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/healthz should return ok).0 */6 * * *. If it's missing, run npx wrangler deploy again — the trigger is registered on deploy. The handler also only dispatches engines for brands whose refresh_frequency cadence has elapsed, so a freshly-seeded brand might not fire on the next 6h boundary.401 unauthorized from /admin/* — X-Seed-Secret header is missing or doesn't match the deployed SEED_SECRET. Re-run npx wrangler secret put SEED_SECRET and update your .env.test.services binding in wrangler.jsonc is missing or the service name doesn't match the worker's name field. /admin/run-live self-fetches /admin/run-engine via env.SELF (a Cloudflare service binding) precisely because a public-URL fetch back to your own workers.dev hostname is blocked by Cloudflare's "Worker called itself" guard. Confirm the wrangler.jsonc you deployed contains "services": [{ "binding": "SELF", "service": "<your-worker-name>" }] with the same name you set in the top-level "name" field. After fixing, npx wrangler deploy and re-run.FOREIGN KEY constraint failed in wrangler tail during /admin/run-engine — the handler defensively INSERT OR IGNOREs the runs row before persisting prompt responses. This is an idempotency/FK guard for independently dispatched engine work, so you should not see this on the 0.2.0+ build; if you do, confirm you've deployed the latest src/index.ts (grep -n "INSERT OR IGNORE INTO runs" src/index.ts should match).Issues and PRs welcome. See CONTRIBUTING.md for the short version.
Full policy for the local package and Claude Desktop extension: https://geo-mcp.digestseo.com/privacy
When you run digestseo-mcp locally (npx, the desktop extension, or Docker), all of your data — brands, prompts, runs, responses, and the response cache — stays on your machine in a local SQLite database at ~/.digestseo/digestseo.sqlite (override with DIGESTSEO_DB_PATH). The scan prompts are sent only to the AI providers whose API keys you configure (OpenAI, Anthropic, Google, Perplexity, xAI, and/or SerpAPI); their handling of that traffic is governed by their respective privacy policies. Nothing is ever sent to the author of this project: no telemetry, no analytics, no account.
Data use and storage: Local brand configuration, prompts, scan runs, responses, and cached responses are used only to provide the MCP server features you invoke. They remain in the local SQLite database described above; this project does not operate an account service or collect telemetry.
Third-party processing: Prompt and scan traffic is sent only to the AI providers you explicitly configure. Those providers process and retain that traffic under their own privacy policies; the project author does not receive copies of it.
Retention and deletion: Local data remains on your machine until you delete the SQLite database (or the custom DIGESTSEO_DB_PATH you configured). Removing that local database removes mcp-geo's stored local history and cache. Provider-side retention is controlled by each configured provider.
Contact: Privacy questions about mcp-geo can be sent to info@tomiseregi.si.
MIT.
Built and maintained by Tomi Šeregi.
See CHANGELOG.md for the full version history.
@digestseo/mcp-geo with synchronized Worker, MCP Registry, and MCPB metadata.visibility.* tool namespaces with typed input/output schemas; local stdio names remain flat.mcp-geo-db D1 configuration and Cursor/Claude Code plugin metadata.npx -y @digestseo/mcp-geo) with SQLite storage and inline engine runs.track_brand, list_brands, generate_prompts.Db adapters.server.json, MCPB desktop extension, Dockerfile, llms-install.md.CONNECT_SECRET gate on the OAuth connect flow.aliases and exclude_terms (migration 0005) for homograph brands like Monday/Notion.visibility.history includes partial runs and drops fully-failed runs.env.SELF service binding (one worker invocation per engine, dodges Cloudflare's 1042 self-call guard).status + error_message columns on prompt_responses — failed engine calls are now explicit rows, no more ERROR: strings in raw_response.INSERT OR IGNORE on the runs row inside /admin/run-engine (handles D1 cross-region replication lag without dropping prompt_responses to FK violations).runLive (~26 subrequests/invocation instead of ~89; full 20-prompt runs now fit under the free-plan cap).getLatestCompletedRun anchored on EXISTS(ok rows); partially-finished runs still show their data.POST /admin/cleanup-failed-runs admin route.FAQs
Self-hostable MCP server for AI visibility tracking across ChatGPT, Claude, Perplexity, Gemini, Grok, and Google AI Overviews. Free OSS with an optional EUR 99 one-time AI Visibility Audit for teams that want a client-ready baseline.
The npm package @digestseo/mcp-geo receives a total of 143 weekly downloads. As such, @digestseo/mcp-geo popularity was classified as not popular.
We found that @digestseo/mcp-geo demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.