GEO MCP by DigestSEO
This server tracks and analyzes how often your brand is cited by AI engines (ChatGPT, Claude, Perplexity, Gemini, Grok, Google AI Overviews/AI Mode) and helps you improve that AI visibility.
Check AI visibility — view latest per-engine scores, winning prompts, and losing prompts.
View history — get daily or weekly visibility trends over time.
Compare competitors — see share of voice, mentions, and prompts you win or lose against rivals.
Get citation evidence — inspect actual AI citations plus top cited source domains.
Find content gaps — get prioritized content topic and format recommendations.
Refresh scans — trigger fresh visibility scans on selected configured engines.
Manage brands — track, update, and list brands with domains, aliases, competitors, and exclusions.
Manage prompts — list, replace, or generate buyer-intent prompt sets for scanning.
Tracks how often a brand is cited in Google Gemini and Google AI Overviews, with per-prompt visibility, competitor comparisons, and citation history.
Tracks how often a brand is cited by ChatGPT/OpenAI AI answers and provides per-prompt visibility, competitor comparisons, and content-gap recommendations.
Tracks how often a brand is cited by Perplexity AI answers and provides per-prompt visibility, competitor comparisons, and citation history.
DigestSEO — AI Visibility MCP for SEO & GEO
Quick Install
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.
Perplexity Computer (remote MCP): Perplexity Computer supports custom remote MCP connectors on eligible plans. After self-hosting mcp-geo, open Account settings > Connectors > + Custom connector, choose Remote, name it digestseo, and enter your own deployment's https://<worker-host>/mcp URL. Use the connector's OAuth option for the Worker flow; if you configured CONNECT_SECRET, complete that browser gate during connection. Do not use the public geo-mcp.digestseo.com/mcp endpoint as a turnkey no-key scan service. See Perplexity's current Computer connector guidance.
Replit Agent (remote MCP): after self-hosting mcp-geo, open Integrations -> MCP Servers for Replit Agent -> Add MCP server, name it digestseo, and enter your own deployment's https://<worker-host>/mcp URL. Choose the OAuth flow when prompted: Replit supports OAuth dynamic client registration (DCR), which the self-hosted Worker exposes through its standard discovery and registration endpoints. Select Test & Save, then complete the browser authorization step; if you configured CONNECT_SECRET, enter it in that gate. Replit supports remote HTTPS MCP servers rather than this package's local stdio process, so use your configured Worker URL and do not treat the public geo-mcp.digestseo.com/mcp endpoint as a turnkey provider-key service. See Replit's current MCP guide.
Claude Code:
claude mcp add --transport stdio digestseo -s user --env GEMINI_API_KEY=your_key_here -- npx -y @digestseo/mcp-geoOr 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-mcpThe 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-geoThe 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-geoAmp 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-geoOpenCode v2 runs this as a local STDIO server. Omit --global for project-only configuration. Zero keys are enough for MCP tool discovery. For engine-backed scans, edit the generated OpenCode v2 config and add only the provider variables you want under mcp.servers.digestseo.environment, mapping each to an environment reference such as "OPENAI_API_KEY": "{env:OPENAI_API_KEY}"; keep the actual secret value in the process environment rather than in the config file. Verify the connection with opencode mcp list. See the current OpenCode v2 MCP guide.
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.
LibreChat: add mcp-geo to librechat.yaml as a local STDIO server:
mcpServers:
digestseo:
type: stdio
command: npx
args:
- -y
- '@digestseo/mcp-geo'Restart LibreChat after changing librechat.yaml. The zero-key entry is enough for MCP tool discovery. Before engine-backed scans, expose only the provider API keys you intend to use to the LibreChat process rather than committing secret values into the YAML file. See LibreChat's current MCP configuration guide and MCP feature guide.
AnythingLLM: add mcp-geo from Settings -> Agent Configuration -> MCP, or merge this entry into anythingllm_mcp_servers.json in AnythingLLM's storage plugins directory:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}AnythingLLM treats command-backed servers as local STDIO MCP servers and can start them when an agent needs their tools. The zero-key entry is enough for MCP discovery; before engine-backed scans, add only the provider environment variables you intend to use through AnythingLLM's MCP configuration or the process environment instead of committing raw secrets. See AnythingLLM's current MCP compatibility guide.
Langflow: open Settings -> MCP Servers (or the MCP sidebar -> Add MCP Server), choose STDIO, name the server digestseo, set Command to npx, and add Arguments -y and @digestseo/mcp-geo. The zero-key server is enough for MCP tool discovery; before engine-backed scans, add only the provider keys you intend to use in Langflow's MCP Environment Variables fields rather than storing raw secrets in a flow. Then select the saved server from an MCP Tools component and connect its tools to a Langflow Agent. If Langflow itself runs in Docker, its image must include Node.js before it can launch an npx server. See Langflow's current MCP client guide.
Flowise: for a local/self-hosted Flowise instance, add a Custom MCP tool to an Agent and use STDIO with {"command":"npx","args":["-y","@digestseo/mcp-geo"]}. Refresh Available Actions to load the twelve mcp-geo tools. Zero provider keys are enough for discovery; before engine-backed scans, make only the provider keys you intend to use available to the Flowise process/service environment. Flowise explicitly recommends STDIO only when it is running locally rather than in a cloud service because the npx package is launched on the Flowise host. See Flowise's current Tools & MCP guide.
Kilo Code: open Settings -> Agent Behaviour -> MCP Servers, add a Local (stdio) server named digestseo, and launch npx with arguments -y and @digestseo/mcp-geo. The equivalent macOS/Linux kilo.jsonc entry is:
{
"mcp": {
"digestseo": {
"type": "local",
"command": ["npx", "-y", "@digestseo/mcp-geo"],
"enabled": true
}
}
}On Windows, Kilo's current guidance uses "command": ["cmd", "/c", "npx", "-y", "@digestseo/mcp-geo"]. Zero provider keys are enough for discovery. Before engine-backed scans, add only the provider keys you intend to use through Kilo's MCP environment settings or the local process environment, and keep raw secrets out of project-level kilo.jsonc. See Kilo Code's current MCP configuration guide and CLI MCP guide.
Google Antigravity: Antigravity 2.0, Antigravity CLI, and Antigravity IDE can launch custom local STDIO MCP servers. In the IDE, open the agent panel -> MCP Servers -> Manage MCP Servers -> View raw config; from the CLI, /mcp opens the interactive MCP manager. Add digestseo to the global ~/.gemini/config/mcp_config.json or a workspace .agents/mcp_config.json:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}The zero-key configuration is enough for MCP tool discovery. Before engine-backed scans, expose only the provider keys you intend to use through the local server environment; if you use workspace .agents/mcp_config.json, keep raw secrets out of any shared or committed copy. See Google's current Antigravity MCP guide.
Cherry Studio: open Settings -> MCP -> MCP Servers -> Add, choose STDIO, name the server digestseo, set Command to npx, and add Arguments -y and @digestseo/mcp-geo. The zero-key server is enough for MCP tool discovery. Before engine-backed scans, add only the provider keys you intend to use in Cherry Studio's MCP environment-variable fields rather than putting secrets in prompts or screenshots. Enable the server, inspect its Tools, then bind it to the intended Agent under Work -> Agent -> Edit -> MCP. See Cherry Studio's current official MCP configuration guide and MCP workflow guide.
Raycast AI: open Install MCP Server (or Manage MCP Servers -> Install New Server), choose Standard Input/Output, set Command to npx, and set Arguments to -y and @digestseo/mcp-geo. The zero-key install is enough for tool discovery. Before engine-backed scans, add only the provider keys you want in Raycast's MCP Environment fields rather than hard-coding them into shared project files. Restart Raycast if npx was added to PATH after Raycast started. See Raycast's current MCP manual.
Msty Studio: open Toolbox -> Add New Tool, choose STDIO / JSON, and use:
{
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}The zero-key tool is enough for MCP discovery. For engine-backed scans, define only the provider keys you want in Msty Studio Environments and attach them to the tool rather than storing raw secrets in shared files. Msty Studio Desktop can run the tool locally; Studio Web needs its documented Desktop/Sidecar connection for local MCP tools. See Msty Studio's current Toolbox MCP guide and environment guide.
Jan Desktop / Jan Agent: in Jan Desktop open Settings -> MCP Servers -> + Add MCP Server, choose STDIO, set Command to npx, and add Args -y and @digestseo/mcp-geo. The zero-key server is enough for tool discovery; add only the provider keys you intend to use through Jan's MCP Env fields. Jan Agent reads the same MCP configuration, or you can add it from the terminal with jan cli mcp add digestseo --command npx --arg -y --arg @digestseo/mcp-geo and then enable it. If you run Path B on your own Worker, Jan also supports HTTP MCP servers at https://<worker-host>/mcp and handles advertised OAuth with metadata discovery, dynamic client registration, and authorization-code + PKCE. Do not present the public DigestSEO endpoint as a turnkey provider-key service. See Jan's current MCP server guide and Agent MCP guide.
Zed: open Settings -> AI -> MCP Servers, choose Add Server -> Add Local Server, and configure digestseo with command npx and arguments -y, @digestseo/mcp-geo. The zero-key local server is enough for tool discovery; for engine-backed scans, add only the provider keys you intend to use in Zed's local MCP env map rather than committing secrets into shared project settings. If you run Path B on your own Worker instead, choose Add Remote Server and use https://<worker-host>/mcp; when no Authorization header is configured, Zed uses the standard MCP OAuth flow. Do not treat the public DigestSEO endpoint as a turnkey provider-key service. See Zed's current MCP guide.
TraeCode: open Settings -> MCP -> Add -> Manually add and paste this local STDIO configuration, or save the same mcpServers object as .trae/mcp.json in a trusted project:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}TraeCode recommends NPX/UVX for local MCP servers and supports env values when engine-backed scans need provider keys. The zero-key form is enough for discovery; keep raw provider secrets out of project-level .trae/mcp.json. TraeCode CLI can also load that project-level MCP file, or you can add an equivalent stdio entry through traecli config edit and inspect it with /mcp. See TraeCode's current IDE MCP setup and CLI MCP guide.
Qwen Code: this repository already ships the portable Agent Plugins v1 metadata that Qwen Code can load directly from GitHub:
qwen extensions install AKzar1el/mcp-geoOr add only the local MCP server as a user-scoped STDIO entry:
qwen mcp add --scope user digestseo npx -y @digestseo/mcp-geo
qwen mcp listQwen Code natively supports Agent Plugins v1, including the repository's root plugin.json + mcp.json, so the extension path reuses the same npx -y @digestseo/mcp-geo server without another wrapper. Direct MCP configuration is stored in ~/.qwen/settings.json; project-scoped servers can instead live in .qwen/settings.json under mcpServers. The zero-key setup is enough for tool discovery. Before engine-backed scans, expose only the provider variables you intend to use to the Qwen process, or reference existing environment variables from the MCP env map instead of committing raw keys to project settings. Start Qwen Code and run /mcp to verify the server and tools. See Qwen Code's current extension guide and MCP server guide.
Augment Code / Auggie: in the Augment extension for VS Code or JetBrains, open Settings -> MCP servers and use Import from JSON with:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}For Auggie CLI, the equivalent user-level install is:
auggie mcp add digestseo -- npx -y @digestseo/mcp-geo
auggie mcp listAuggie persists MCP servers in ~/.augment/settings.json; run /mcp in an Auggie session to inspect them. The zero-key setup is enough for tool discovery. Before engine-backed scans, add only the provider keys you intend to use through Augment's MCP environment fields or Auggie's --env NAME=VALUE option rather than committing raw secrets. If the twelve local tools consume too much agent context, Augment's optional MCP Tool Search can load tool schemas on demand. See Augment's current MCP setup guide and Auggie integrations/MCP guide.
GitHub Copilot CLI:
copilot mcp add digestseo -- npx -y @digestseo/mcp-geoThe 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.
GitHub Copilot cloud agent / code review: repository administrators can also add mcp-geo under Settings -> Copilot -> MCP servers. Use the local npm package rather than the hosted OAuth endpoint, because Copilot cloud agent and code review do not currently support remote MCP servers that rely on OAuth.
Start with a conservative read-only profile because repository MCP tools can run autonomously:
{
"mcpServers": {
"digestseo": {
"type": "local",
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"],
"tools": [
"check_visibility",
"get_visibility_history",
"compare_competitors",
"get_citations",
"list_brands",
"list_prompts"
]
}
}
}Copilot code review only accepts tools whose MCP metadata marks them read-only; the tools above already publish readOnlyHint: true. This profile is useful when the task has access to an mcp-geo local database created during that run. For a task that should create/refresh visibility data, explicitly add only the mutating tools you intend to permit (for example track_brand and refresh_brand) and remember that refresh_brand can make billable provider calls.
Provider credentials belong in Copilot Agents secrets/variables, not in repository JSON. GitHub only exposes names prefixed COPILOT_MCP_; map a selected secret into mcp-geo with env, for example "OPENAI_API_KEY": "$COPILOT_MCP_OPENAI_API_KEY". See GitHub's current repository MCP configuration guide.
Portable Agent Plugin (GitHub Copilot / VS Code / Kiro and other Agent Plugins 1.0 clients): this repository now ships the standard root plugin.json + mcp.json pair. GitHub Copilot CLI can install it directly from GitHub:
copilot plugin install AKzar1el/mcp-geoIn VS Code, run Chat: Install Plugin from Source and enter https://github.com/AKzar1el/mcp-geo. In Kiro, use Powers -> Add Custom Power -> Import power from GitHub with the same repository URL. The portable plugin launches npx -y @digestseo/mcp-geo; zero provider keys are enough for discovery, while engine-backed scans inherit only the provider keys you intentionally make available to the host client. Existing native install paths above remain valid.
Qoder CLI:
qoder mcp add digestseo -- npx -y @digestseo/mcp-geo
qoder mcp listQoder 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: 300The 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-mcpThe 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 listDroid 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.
Amazon Q Developer CLI: add the same local STDIO server through Q's native MCP manager:
q mcp add --name digestseo --command npx --args '["-y", "@digestseo/mcp-geo"]'
q mcp listThe zero-key server is enough for MCP tool discovery. Before engine-backed scans, add only the provider variables you intend to use to the Q CLI MCP configuration instead of committing secrets to the repository. Amazon Q Developer CLI supports local process-backed MCP servers and manages them through q mcp; use /tools inside a Q session to inspect the tools that loaded. See AWS's current Amazon Q Developer MCP guide and CLI MCP configuration reference.
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 Junie (CLI / IDE): run /mcp in Junie CLI to open the MCP Installation Assistant. You can search the Official MCP Registry for mcp-geo, or add the local server manually in .junie/mcp/mcp.json for one project or ~/.junie/mcp/mcp.json for your user:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": ["-y", "@digestseo/mcp-geo"]
}
}
}Junie CLI and the Junie IDE plugin use the same MCP configuration. The zero-key server is enough for tool discovery; before engine-backed scans, make only the provider keys you intend to use available to the Junie process and keep raw secrets out of a shared or committed project .junie/mcp/mcp.json. Use /mcp to verify the active server and tools. See JetBrains' current Junie CLI MCP guide and Junie IDE MCP settings.
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, Google AI Overviews, and Google AI Mode. 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 →
Related MCP server: websearch-mcp
What it produces
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.
What's New
[0.3.26] - September 24, 2026
OAuth 1.0 resource correctness: self-hosted Workers now bind OAuth grants and tokens to the canonical
${SELF_URL}/mcpresource required by@cloudflare/workers-oauth-provider1.0.0, with deployment guidance that prevents resource-host mismatches.Broader coding-agent onboarding: Google Antigravity, JetBrains Junie, GitHub Copilot cloud agent/code review, Qwen Code, and Augment Code / Auggie now have first-party-aligned local MCP setup paths using the published
npx -y @digestseo/mcp-geopackage.
[0.3.25] - September 24, 2026
Complete hosted safety metadata: all six hosted visibility tools now explicitly declare read-only, destructive, and open-world behavior for stricter MCP clients and plugin validators.
Broader native onboarding: Langflow, Cherry Studio, Flowise, and Kilo Code setup now reuse the published local/self-hosted mcp-geo paths with zero-key discovery and secret-safe provider configuration.
Stronger audit fulfillment: the reusable report prompt now turns the existing
top_sourcescitation summary into recurring-source evidence before individual citation examples, without manufacturing derived metrics.
[0.3.24] - September 23, 2026
Source-domain intelligence:
get_citations/visibility.citationsnow summarizes the most frequently cited engine-native source domains across the requested window, with prompt counts, contributing engines, representative URLs, and tracked-brand-domain flags.Clear hosted MCP identity: modern SDK-v2 discovery now exposes the human-readable GEO Tracker title, concise description, and canonical product URL without changing the stateless transport contract.
More native client onboarding: Replit Agent remote-MCP and Jan Desktop / Jan Agent setup now reuse the existing local or self-hosted mcp-geo paths without introducing another package or hosted turnkey-provider claim.
[0.3.23] - September 23, 2026
Current Grok model: grounded Grok visibility scans now use xAI's current
grok-4.7model while preserving the existing Responses API, required Web Search grounding, and BYOK flow.AnythingLLM onboarding: MCP Management /
anythingllm_mcp_servers.jsonsetup now covers the published local stdio package with zero-key discovery and secret-safe optional provider configuration.Accurate Perplexity guidance: setup text now matches the already-shipped Agent API
fastpreset and points to live pricing instead of stale Sonar/fixed per-prompt wording.
[0.3.22] - September 23, 2026
Perplexity retirement-safe: Perplexity scans now use the Agent API
fastpreset instead of the retiring fixed Sonar model selector, preserving grounded web-search visibility after the September 27 Sonar retirement.Current plugin discovery truth: portable Agent Plugin and Claude marketplace metadata now include Google AI Mode alongside the other supported AI-search surfaces.
Amazon Q Developer CLI: native
q mcponboarding now covers the existing local stdio package with zero-key discovery and secret-safe provider configuration.Accurate self-hosting guidance: setup documentation now reflects the stateless SDK-v2 hosted MCP path and current manual-refresh scheduling behavior.
[0.3.21] - September 22, 2026
Stateless hosted MCP: OAuth-protected
/mcptraffic now uses Cloudflare's SDK-v2createMcpHandlerpath with legacy stateless compatibility and explicit Host/Origin validation, while the old Durable Object binding remains only as a conservative migration hold.Leaner tool context: all twelve MCP tools now expose concise example-led descriptions and complete input-parameter guidance, reducing client context overhead and making tool selection clearer.
[0.3.20] - September 22, 2026
Bounded provider requests: external AI-provider and SerpAPI calls now time out after 90 seconds instead of allowing a stalled upstream API to hang a scan indefinitely.
Durable manual Worker scans: authenticated
/admin/run-liverequests can setwait_for_completion: trueso manual/operator refreshes remain attached until service-binding engine work finishes.
[0.3.19] - September 22, 2026
Google AI Mode: opt in with
SERPAPI_AI_MODE_ENABLED=trueto measure Google AI Mode separately through SerpAPI, including citation/source evidence when returned.Safe tracked-brand corrections: local MCP users can call
update_brandto change identity, competitors, aliases, exclusions, or refresh cadence without replacing prompts or historical runs.Manual scheduling: set
refresh_frequencytomanualto pause self-hosted scheduled scans while keeping explicitrefresh_brandavailable.
[0.3.18] - September 21, 2026
Grok visibility coverage: opt in with XAI_API_KEY to measure grounded Grok answers via xAI Web Search alongside ChatGPT, Claude, Perplexity, Gemini, and Google AI Overviews.
[0.3.17] - September 21, 2026
Exact user-defined measurement sets: local MCP users can now call
set_promptsto replace a brand's active prompts with 1-50 agreed buyer questions while preserving historical runs; repeated identical sets are a no-op.
[0.3.16] - September 21, 2026
New-project Gemini compatibility: Gemini scans now default to
gemini-3.1-flash-lite, avoiding the Gemini 2.5 access restriction Google applies to some new projects while preserving the same GenerateContent integration.
[0.3.15] - September 20, 2026
Clearer provider setup failures: an explicit refresh request for an unconfigured engine now names the unavailable engine and explains how to recover instead of reporting that no engines at all are available.
Broader local-client onboarding: copy-paste setup now covers Roo Code, Codex CLI, and OpenCode v2 in addition to the existing MCP clients.
Reliable installed README links: npm-package readers are routed to durable GitHub URLs for documentation and report assets that are intentionally excluded from the tarball.
[0.3.14] - September 20, 2026
Inspectable measurement inputs: local MCP users can now call
list_promptsto review the exact active buyer-intent prompt set for a tracked brand without regenerating or changing it.Correct ChatGPT onboarding: ChatGPT guidance now uses a configured remote MCP server or OpenAI Secure MCP Tunnel for local/private servers instead of advertising unsupported direct local STDIO registration.
[0.3.13] - September 20, 2026
More faithful citation evidence: get_citations now preserves the exact engine-native cited page URL, including path and query, when the provider returns one.
Current Gemini CLI gallery metadata: the extension manifest now stays version-synchronized with the package, preventing stale gallery version labels after release.
[0.3.12] - September 20, 2026
Better agent workflow guidance: local and hosted MCP initialize responses now include concise server-level instructions for the correct brand → refresh → visibility flow, asynchronous hosted refresh behavior, and unavailable-engine semantics.
[0.3.11] - September 19, 2026
More reliable scheduled tracking: per-engine freshness and due-engine fan-out keep stale providers updating without needlessly rescanning fresh ones, while brands can choose daily or weekly cadence.
Safer request handling: duplicate engine selections are deduplicated in hosted refresh and visibility reads, and hosted brand seeding rejects invalid refresh cadence values before persistence.
Complete Claude Desktop metadata: the MCPB manifest now declares all nine fixed local tools, including
track_brand,list_brands, andgenerate_prompts, matching the actual stdio server exposed after install.
[0.3.10] - September 19, 2026
Safer BYOK refreshes: duplicate engine names are deduplicated before provider dispatch so one request cannot accidentally trigger duplicate scans or provider charges.
Stronger MCP contracts: winning/losing prompt and content-gap structured outputs now publish concrete schemas instead of opaque records, improving client-side validation and agent interoperability.
Better Registry installs: Official MCP Registry metadata now advertises all five supported provider API keys as optional secret configuration for the npm stdio package.
[0.3.9] - September 19, 2026
Transparent snapshot freshness: visibility snapshots now expose each engine's own observation timestamp so older engine data cannot be mistaken for uniformly fresh results.
Auditable history trends: visibility history now includes the usable-prompt denominator, brand-mention count, and observation time behind every per-engine score.
[0.3.8] - September 19, 2026
More reliable audit evidence: competitor comparisons now honor their requested multi-day window across all usable runs and return exact mention counts; citation excerpts and provider-free content-gap fallbacks are grounded in the same underlying evidence.
Broader local install reach: added Amazon Q Developer IDE setup for the existing local stdio package.
[0.3.7] - September 19, 2026
Exact audit prompt count: prompt generation now persists exactly the requested number of unique prompts or leaves the existing prompt set untouched, protecting the paid audit's fixed 20-prompt scope.
[0.3.6] - September 18, 2026
Grounded ChatGPT scans: live ChatGPT visibility uses web search, and domain-lookalike mention scoring was tightened.
Broader local install reach: added Gemini CLI metadata plus one-click VS Code and LM Studio install paths.
[0.3.5] - September 17, 2026
Provider/runtime correctness: migrated Perplexity to the Agent API and kept plugin installs on the local stdio package rather than the unconfigured public Worker.
Trust/readiness: added owned privacy disclosure, production-only MCPB packaging, and transparent audit score formulas.
[0.3.4] - September 15, 2026
Claude Desktop MCPB portability: the bundle no longer ships
better-sqlite3native binaries; local storage uses built-innode:sqliteon Node.js 22.13+.Registry accuracy: official metadata now advertises the npm stdio package only while the public hosted endpoint is not a turnkey configured fresh-scan service.
[0.3.3] - September 10, 2026
Optional one-time audit: the open-source package stays free; teams that want a client-ready baseline can request the EUR 99 mcp-geo AI Visibility Audit from the CTA above.
Lower-friction request path: the README now opens a prefilled, source-marked email, while the audit details remain available at
https://geo-mcp.digestseo.com/audit.
[0.3.2] — July 27, 2026
Published scoped package:
@digestseo/mcp-geowith synchronized Worker, MCP Registry, and MCPB metadata.Hosted tool metadata:
visibility.*namespaces with typed input/output schemas; local stdio tool names remain flat.Distribution and deployment: dedicated
mcp-geo-dbD1 configuration, Cursor and Claude Code plugin metadata, and patched production dependency pins.
[0.3.0] — July 2026
Local stdio CLI on npm (
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.Local brand-management tools (CLI only):
track_brand,list_brands,generate_prompts. Workers deployments keep these behind theX-Seed-Secret-gated/admin/*routes.Runtime-agnostic core (
src/core/) shared by the Worker and the CLI, with aDbcontract implemented by D1 and better-sqlite3 adapters. All 0.2.1 accuracy and security fixes carry over to both runtimes.Distribution metadata: official MCP Registry
server.json, MCPB desktop extension (.mcpbbundle), Dockerfile,llms-install.mdfor AI agents, release-publish workflow.
[0.2.1] — June 2026
Optional
CONNECT_SECRETgate on the OAuth flow. By default the OSS build auto-completes/authorizefor any MCP client that knows your worker URL — anyone who finds the URL can connect and callvisibility.refresh, spending your engine API credits. SetCONNECT_SECRETand the browser step of the connect flow now asks for it before issuing a token. See SECURITY.md.Accurate citation matching. Brand/competitor mentions now require word boundaries (
acmeno longer matches "acmeshop"), and linked-citation checks require the exact domain or a subdomain (notacme.comno longer counts as a link toacme.com).Per-brand
aliasesandexclude_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, whilemonday.comstill counts. Applymigrations/0005_brand_alias_exclude.sql; existing brands behave exactly as before.visibility.historyconsistency. Partially-finished runs now count toward history (matchingvisibility.check's 0.2.0 behavior), and fully-failed runs no longer show up as fake zero scores.CI + unit tests. GitHub Actions runs
tsc --noEmitplus a pure-function unit suite (npm run test:unit) covering mention matching, citation extraction, and score aggregation on every push.Docs now recommend OpenAI + Anthropic as the starting engine pair — Gemini capacity varies by model, project, and usage tier, so provider-specific quota variability could produce misleading first-run data as the documented cheapest path.
Constant-time comparison for
SEED_SECRET/CONNECT_SECRET.
[0.2.0] — May 2026
Per-engine HTTP fan-out.
/admin/run-livenow creates one runs row per engine and self-fetches/admin/run-engineonce 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.Service binding (
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.Status column on
prompt_responses(ok/failed/skipped) pluserror_message. Failed engine calls used to writeraw_response='ERROR: ...'rows that downstream scoring treated as real zero-mention hits; now they're explicitly excluded.FK-resistant inserts.
/admin/run-engineINSERT OR IGNOREs its runs row before persisting — D1 is eventually consistent across edge regions, and the upstreamINSERT INTO runsfrom/admin/run-livedoesn't always replicate before the downstream engine call lands. The IGNORE makes the FK happy either way.Bulk D1 batch. Each engine collects its 20 prompt results in memory then flushes inserts + cache writes + the final
UPDATE runs SET status='completed'in a singleD1.batch()call. Drops the per-invocation subrequest count from ~89 to ~26.Relaxed visibility queries.
getLatestCompletedRunanchors onEXISTS(ok rows)instead ofstatus='completed', so partially-finished runs still surface their data in MCP tool output instead of silently disappearing.New admin route
POST /admin/cleanup-failed-runsfor one-shot deletion of legacy polluted rows after migrating to 0004.
[0.1.1] — May 2026
Manual install is now the canonical path. The unreliable bash setup script was removed; SETUP.md is self-contained and copy-pasteable, with every interactive wrangler prompt documented inline.
[0.1.0] — May 2026
Initial public release.
5-engine support: ChatGPT (
gpt-4o-mini), Claude (claude-haiku-4-5), Perplexity (sonar), Gemini (gemini-2.5-flash-lite), and Google AI Overviews (via SerpAPI).6 hosted MCP tools:
visibility.check,visibility.history,visibility.compare,visibility.citations,visibility.content_gaps,visibility.refresh.Engines are opt-in based on which API keys you provide — set only the credentials you have, the rest skip gracefully.
Cloudflare Cron Trigger that auto-refreshes tracked brands every 6h, respecting per-brand
refresh_frequency(daily/weekly).D1-backed storage for brands, prompts, runs, citations, and a shared prompt cache.
What Can This Do?
See which AI tools cite your brand and which don't — get a per-engine breakdown of who's citing you for buyer-intent queries.
Track AI visibility weekly, automatically — the built-in Cron Trigger re-runs scans on the cadence you configure per brand.
Compare your AI visibility to competitors — share-of-voice percentages, prompts you win, prompts they win.
Find content gaps — Claude-Haiku-synthesized recommendations grounded in your actual losing prompts.
Use it inside Claude.ai conversations — add the deployed Worker URL as a custom MCP connector and ask in natural language.
Self-hosted on your own Cloudflare account — your API keys, your data, your cost ceiling. The free Workers + D1 tiers cover a single brand with daily refreshes.
See the example report above for what this looks like in practice.
Available Tools
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 |
|
| Latest AI visibility snapshot across all configured engines for a tracked brand, with per-engine scores, winning prompts, and losing prompts. |
|
|
| Time-series history of overall and per-engine visibility, bucketed daily or weekly. |
|
|
| Share-of-voice comparison against competitor domains, with prompts you win and prompts they win. |
|
|
| The actual citation events — prompt, engine, response excerpt, citation type, brand URL when present. |
|
|
| Prioritized Claude-Haiku-generated content recommendations targeting your losing prompts. |
|
|
| Manually trigger a fresh scan across every engine whose API key is set. |
|
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 |
| Start tracking a brand: creates it locally and generates its buyer-intent prompt set (Claude Haiku when |
|
| Correct an existing brand's domain, name, category, competitors, aliases, exclusions, or refresh cadence without replacing active prompts or historical runs. Set cadence to |
|
| List tracked brands with domains, competitors, aliases, exclusions, and active prompt counts. | — |
| Inspect the exact active buyer-intent prompts for a tracked brand without changing them. |
|
| Replace the active prompt set with exact user-supplied buyer questions while preserving historical runs. |
|
| Regenerate a brand's prompt set via Claude Haiku (replaces active prompts, keeps history). |
|
Getting Started
Step 1 — Get API keys
Engines are opt-in. Pick the ones you want; the rest skip silently.
OpenAI — ChatGPT engine (
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.Anthropic — Claude engine, plus prompt generation and content-gap analysis (both call Claude Haiku). ~€0.0002 per prompt. Free trial credits are usually enough to evaluate. console.anthropic.com
Google AI Studio (Gemini) — Gemini engine (
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.Perplexity — Agent API
fastpreset for grounded web-search visibility. Paid API usage; pricing depends on the preset workload, so check current Agent API pricing before estimating scan cost. Perplexity Agent API · pricingxAI — Grok engine (
grok-4.7) with required Web Search grounding. xAI currently prices Web Search at $5 per 1,000 calls plus model tokens. console.x.ai · pricingSerpAPI — Google AI Overviews plus optional Google AI Mode. One SerpAPI key powers both, but AI Mode is deliberately off by default because it adds a separate paid search per prompt; set
SERPAPI_AI_MODE_ENABLED=truewhen you want that seventh surface. Google AI Mode API · serpapi.com/dashboard
Recommended 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). Google AI Mode is a separate SerpAPI call and stays disabled until SERPAPI_AI_MODE_ENABLED=true, preventing an existing SerpAPI setup from silently doubling Google search calls.
Step 2 — Deploy to your Cloudflare account
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 deployAfter deploying your own Worker, use that deployment's /mcp URL as the
remote endpoint, for example:
https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcpUse 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.
Step 3 — Connect to your MCP client
After wrangler deploy finishes, you get a URL like
https://digestseo-mcp.YOUR-SUBDOMAIN.workers.dev.
Claude.ai (web)
Settings → Connectors → Add custom connector. Paste:
https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcpComplete the OAuth handshake. The connector turns green when ready.
ChatGPT (remote MCP)
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/mcpChatGPT (local/private via OpenAI Secure MCP Tunnel)
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 digestseoWhile 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 Code
claude mcp add --transport http digestseo https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcpThen run /mcp inside Claude Code to complete the OAuth handshake in your browser.
Claude Desktop
Edit your Claude Desktop config:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%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.
Cursor
Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"digestseo": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp"
]
}
}
}Restart Cursor.
Codex CLI
Add to ~/.codex/config.toml:
[mcp_servers.digestseo]
command = "npx"
args = [
"-y",
"mcp-remote",
"https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp",
]Environment Variables Reference
Variable | Required | Default | Description |
| opt-in | unset | Enables the ChatGPT engine. Without it, ChatGPT is skipped. |
| opt-in | unset | Enables the Claude engine and the Claude-Haiku-powered prompt generator + content-gap analyzer. |
| 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). |
| opt-in | unset | Enables the Perplexity Agent API |
| opt-in | unset | Enables the Grok engine ( |
| opt-in | unset | Enables Google AI Overviews via SerpAPI. Also provides the credential for Google AI Mode when the explicit flag below is enabled. |
| no |
| Set to |
| yes | unset | Shared secret that gates every |
| 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. |
| no | unset | Reserved for forks that add a public |
| no | unset | Same — reserved for forks. |
Provider credentials are set via wrangler secret put VAR in production or .dev.vars locally. SERPAPI_AI_MODE_ENABLED is a non-secret runtime flag and may be stored under Wrangler vars or set in the local process environment.
Architecture
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 --> MCP["Stateless MCP handler<br/>(SDK v2, 6 hosted 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 / AI Mode)"]
RE --> DB[("D1<br/>brands / prompts / runs /<br/>responses / cache")]
MCP --> DBThe legacy GeoMcpAgent / MCP_OBJECT Durable Object binding is retained temporarily for migration compatibility, but current /mcp traffic is served by the stateless SDK v2 handler shown above.
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.
Security
/admin/*is gated bySEED_SECRET(constant-time compared)./mcprequires OAuth; setCONNECT_SECRETso only people with the secret can complete the connect flow — strongly recommended whenever your worker URL is shared anywhere, since connected clients can callvisibility.refreshand spend your engine API credits.All engine keys live in Cloudflare's encrypted secret store; all data stays in your own D1 database.
Full details and vulnerability reporting: SECURITY.md.
Sample Prompts
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 |
| "How visible is brand_id |
| "Show me the visibility trend for |
| "Compare |
| "Show me real Perplexity citations for |
| "What content should |
| "Refresh |
| "Refresh |
Hosted Version
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.
Troubleshooting
Worker deploys but tools return empty data — at least one engine API key is missing. Check
wrangler secret listand add the keys you intend to use. Engines without keys are silently skipped, which can leavevisibility.checkwith no data.no engines availableerror in logs — no engine API keys are set at all. Set at least one ofOPENAI_API_KEY,ANTHROPIC_API_KEY,GEMINI_API_KEY,PERPLEXITY_API_KEY,XAI_API_KEY,SERPAPI_API_KEY.D1 migration fails — make sure you've run
npx wrangler d1 migrations apply mcp-geo-db --remote(and also--localforwrangler dev). For ad-hoc fixes,npx wrangler d1 execute mcp-geo-db --remote --file=migrations/0001_initial.sql.Custom MCP connector in Claude.ai not connecting — the URL must end in
/mcp. The OAuth handshake auto-completes in the OSS build (single dev user); if you setCONNECT_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/healthzshould returnok).Cron not firing — check the Cloudflare dashboard at Workers & Pages → digestseo-mcp → Settings → Triggers. The "Cron Triggers" section should list
0 */6 * * *. If it's missing, runnpx wrangler deployagain — the trigger is registered on deploy. The handler also only dispatches engines for brands whoserefresh_frequencycadence has elapsed, so a freshly-seeded brand might not fire on the next 6h boundary.401 unauthorizedfrom/admin/*—X-Seed-Secretheader is missing or doesn't match the deployedSEED_SECRET. Re-runnpx wrangler secret put SEED_SECRETand update your.env.test.Worker returns 404 on self-fetch / error code 1042 — the
servicesbinding inwrangler.jsoncis missing or theservicename doesn't match the worker'snamefield./admin/run-liveself-fetches/admin/run-engineviaenv.SELF(a Cloudflare service binding) precisely because a public-URL fetch back to your ownworkers.devhostname is blocked by Cloudflare's "Worker called itself" guard. Confirm thewrangler.jsoncyou 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 deployand re-run.Gemini rate limit (HTTP 429) on prompts — Gemini API limits vary by model, project, and usage tier, and Google notes that actual capacity can vary. Check the project's current limits in Google AI Studio and Google's rate-limit documentation. When a request is rate-limited, mcp-geo records that engine row as failed and excludes it from successful scoring. Google recommends waiting and retrying after a short period or reducing request rate; if the limit is consistently too low for your scan cadence, consider an appropriate paid tier rather than assuming a universal free-tier RPM/RPD quota.
FOREIGN KEY constraint failedin wrangler tail during/admin/run-engine— the handler defensivelyINSERT 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 latestsrc/index.ts(grep -n "INSERT OR IGNORE INTO runs" src/index.tsshould match).
Contributing
Issues and PRs welcome. See CONTRIBUTING.md for the short version.
Privacy Policy
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.
License
MIT.
Built and maintained by Tomi Šeregi.
Changelog
See CHANGELOG.md for the full version history.
[0.3.2] — July 27, 2026
Published
@digestseo/mcp-geowith synchronized Worker, MCP Registry, and MCPB metadata.Hosted
visibility.*tool namespaces with typed input/output schemas; local stdio names remain flat.Dedicated
mcp-geo-dbD1 configuration and Cursor/Claude Code plugin metadata.Patched production dependency pins.
[0.3.0] — July 2026
Local stdio CLI on npm (
npx -y @digestseo/mcp-geo) with SQLite storage and inline engine runs.Local brand-management tools:
track_brand,list_brands,generate_prompts.Runtime-agnostic core shared by Worker and CLI; D1 + better-sqlite3
Dbadapters.MCP Registry
server.json, MCPB desktop extension, Dockerfile,llms-install.md.
[0.2.1] — June 2026
Optional
CONNECT_SECRETgate on the OAuth connect flow.Word-boundary brand/competitor matching; exact-domain-or-subdomain linked-citation checks.
Per-brand
aliasesandexclude_terms(migration 0005) for homograph brands like Monday/Notion.visibility.historyincludes partial runs and drops fully-failed runs.CI workflow (typecheck + unit tests) and a pure-function unit test suite.
Docs recommend OpenAI + Anthropic as the starting engine pair.
Constant-time secret comparison.
[0.2.0] — May 2026
Per-engine HTTP fan-out via
env.SELFservice binding (one worker invocation per engine, dodges Cloudflare's 1042 self-call guard).status+error_messagecolumns onprompt_responses— failed engine calls are now explicit rows, no moreERROR:strings inraw_response.INSERT OR IGNOREon the runs row inside/admin/run-engine(handles D1 cross-region replication lag without dropping prompt_responses to FK violations).Bulk D1 batch in each engine's
runLive(~26 subrequests/invocation instead of ~89; full 20-prompt runs now fit under the free-plan cap).getLatestCompletedRunanchored onEXISTS(ok rows); partially-finished runs still show their data.New
POST /admin/cleanup-failed-runsadmin route.
[0.1.1] — May 2026
Removed the unreliable bash setup script. Manual install via SETUP.md is now the canonical path.
[0.1.0] — May 2026
Initial public release.
5-engine support: ChatGPT, Claude, Perplexity, Gemini, Google AI Overviews.
6 MCP tools.
Engines opt-in based on which API keys you provide.
Cloudflare Cron Trigger for auto-refresh.
Available Tools
12 toolscheck_visibilityCheck AI visibilityARead-only
Read the latest stored visibility snapshot, including scores and winning/losing prompts; call refresh_brand first for fresh data. Example: brand_id='acme', engines=['chatgpt','perplexity'].
| Name | Required | Description | Default |
|---|---|---|---|
| engines | No | Engines to include; omit or pass [] for all stored engines. | |
| brand_id | Yes | Tracked brand ID to inspect. |
Output Schema
| Name | Required | Description |
|---|---|---|
| brand | Yes | |
| per_engine | Yes | |
| refreshed_at | Yes | |
| overall_score | Yes | |
| top_losing_prompts | Yes | |
| top_winning_prompts | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds non-obvious behavioral context: the data is a stored snapshot, not live, and may be stale unless refresh_brand is called first. This is meaningful beyond the annotations, though it does not cover error cases or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tight sentences plus a concrete example, with the core action and scoping front-loaded. No filler is present and every sentence contributes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (2 params, 1 required), has an output schema, and has annotations covering safety. The description adds the key prerequisite workflow (refresh_brand first) and enough context for correct invocation; nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents brand_id and engines. The inline example reinforces the parameter shape and valid engine values, but it adds little meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Read') and resource ('latest stored visibility snapshot') and adds what is included (scores, winning/losing prompts). It also differentiates itself from refresh_brand by explicitly noting this reads stored data rather than producing fresh data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly routes the agent to refresh_brand when fresh data is needed, giving a clear when-to-use condition. It does not explicitly contrast with get_visibility_history or state when not to use this tool, so it stops short of full alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_competitorsCompare competitor AI visibilityARead-only
Compare stored brand and competitor mentions, share of voice, and prompt wins over a time window. Example: brand_id='acme', competitor_domains=['rival.com'], days=7.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Previous days to compare. | |
| brand_id | Yes | Tracked brand ID to compare. | |
| competitor_domains | No | Competitor domains; omit to use the brand's configured list. |
Output Schema
| Name | Required | Description |
|---|---|---|
| days | Yes | |
| brand_id | Yes | |
| competitors | Yes | |
| your_mentions | Yes | |
| prompts_you_win | Yes | |
| your_share_of_voice_pct | Yes | |
| requested_competitor_domains | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds that this operates on stored mentions over a time window, reinforcing the read-only comparison nature. It does not describe return formatting or behavior beyond that, but the output schema exists and no contradiction is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One focused sentence plus a minimal working example; no filler or redundancy. The core comparison scope is front-loaded and every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only comparison tool with fully documented parameters and an existing output schema, the description covers what is needed to make a correct call. Explicitly naming sibling tools or selection conditions would improve it, but nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains all three parameters. The description's example adds useful concrete values, but it does not need to compensate for missing schema detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Compare') and a clear resource: stored brand and competitor mentions, share of voice, and prompt wins over a time window. It does not explicitly distinguish itself from sibling tools like check_visibility or get_visibility_history, so it falls just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The time-window wording and example imply a comparison use case, but the description gives no explicit when-to-use or when-not-to-use guidance and names no alternatives. With many sibling tools present, the agent must infer the boundary from context rather than being told.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_promptsGenerate brand promptsADestructive
Replace active prompts with Claude-Haiku-generated buyer-intent prompts; requires ANTHROPIC_API_KEY and preserves history. Example: brand_id='acme', count=20.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Buyer-intent prompts to generate. | |
| brand_id | Yes | Tracked brand ID to update. |
Output Schema
| Name | Required | Description |
|---|---|---|
| prompts | Yes | |
| brand_id | Yes | |
| next_steps | Yes | |
| prompt_source | Yes | |
| prompts_inserted | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already carrying destructiveHint=true, the description adds real value: it specifies exactly what gets destroyed ('active prompts'), what is preserved ('history'), and the auth requirement (ANTHROPIC_API_KEY). These details materially shape how an agent should treat the call, going well beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core action is front-loaded in the first clause, and the second half packs the two highest-value caveats (API key requirement, history preservation) plus a one-line example. No filler — every clause earns its place for an agent deciding whether to invoke safely.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter tool with a fully covered schema, an output schema, and annotations carrying the safety profile, the description ties everything together: what happens, what is needed, and what survives the call. No critical operational fact an agent needs to invoke it correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both brand_id and count are already described in the input schema; the baseline is therefore 3. The description adds only a compact usage example ('brand_id='acme', count=20') and frames parameters as producing buyer-intent prompts — mild added value, but no semantic depth the schema lacks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action ('Replace active prompts') with a distinctive mechanism ('Claude-Haiku-generated buyer-intent prompts') and scoping detail ('preserves history'). The generation mechanism clearly differentiates it from near-sibling set_prompts and read-only siblings like list_prompts, even without naming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states a prerequisite ('requires ANTHROPIC_API_KEY') and gives an invocation example, which implies when the tool is usable. However, it never explicitly names alternatives or when-not-to-use conditions — e.g., when the agent should prefer set_prompts or a non-destructive path. Guidance is mostly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_citationsGet AI citation evidenceBRead-only
Return stored brand citation evidence plus the top engine-native source domains across the same tracked-prompt window. Example: brand_id='acme', days=14, engine='perplexity'.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Previous days to search. | |
| engine | No | Engine to filter by; omit for all engines. | |
| brand_id | Yes | Tracked brand ID to inspect. |
Output Schema
| Name | Required | Description |
|---|---|---|
| days | Yes | |
| engine | Yes | |
| brand_id | Yes | |
| citations | Yes | |
| top_sources | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds useful behavioral context about returning stored evidence and scoping to the same tracked-prompt window, which goes slightly beyond annotations. It does not, however, explain result ordering, limits, or empty-result behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero filler, and the example is an efficient way to convey parameter combination. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with full schema coverage and an output schema, the description is largely complete: it states the returned data, the scoping concept, and gives a call example. Minor ambiguity remains around what 'same tracked-prompt window' means and what happens when no citations exist, but these are not blocking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all three parameters. The description's example reinforces valid values like brand_id='acme', days=14, and engine='perplexity', but it does not add meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: it returns stored brand citation evidence plus top engine-native source domains. It also scopes the query to a tracked-prompt window and provides a concrete example. However, it does not explicitly contrast with sibling tools like get_visibility_history or check_visibility.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives such as get_visibility_history or check_visibility. The description explains what the tool returns but does not mention when it is preferred or what conditions make another tool more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_content_gapsFind AI visibility content gapsARead-only
Prioritize content topics and formats from prompts where competitors beat the brand; falls back deterministically if AI analysis is unavailable. Example: brand_id='acme', max_recommendations=5.
| Name | Required | Description | Default |
|---|---|---|---|
| brand_id | Yes | Tracked brand ID to analyze. | |
| max_recommendations | No | Maximum recommendations to return. |
Output Schema
| Name | Required | Description |
|---|---|---|
| reason | No | |
| brand_id | Yes | |
| prompt_source | Yes | |
| recommendations | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld annotations, the description discloses a meaningful behavioral trait: a deterministic fallback when AI analysis is unavailable. It also indicates the output is ordered/prioritized, which affects how an agent interprets results. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single focused sentence followed by a concrete example; no filler or repetition. It front-loads the primary action and includes the fallback behavior economically.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema, complete parameter documentation, and annotations, the description supplies everything needed to decide and invoke the tool correctly. The example and fallback note cover the main contextual ambiguities.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented. The description's example (brand_id='acme', max_recommendations=5) reinforces usage but adds little semantic meaning beyond the schema's own descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses a specific verb ('Prioritize') and identifies the exact resource ('content topics and formats from prompts where competitors beat the brand'). It clearly distinguishes itself from general visibility tools by describing gap-based recommendation output, and the example reinforces scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'where competitors beat the brand' and the title 'Find AI visibility content gaps' signal when the tool is relevant: competitive gap analysis. However, it does not explicitly name alternatives or state when not to use it, though sibling names like compare_competitors imply related but distinct tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_visibility_historyGet AI visibility historyBRead-only
Return daily or weekly visibility history with per-engine evidence. Example: brand_id='acme', days=30, granularity='weekly'.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Previous calendar days to include. | |
| brand_id | Yes | Tracked brand ID to inspect. | |
| granularity | No | Time bucket for the series. | weekly |
Output Schema
| Name | Required | Description |
|---|---|---|
| days | Yes | |
| series | Yes | |
| brand_id | Yes | |
| granularity | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful context about per-engine evidence and granularity but does not disclose behaviors like pagination, date handling, or potential lack of data coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two terse sentences with no filler. The functional statement and example are both valuable, and the example is compact enough to aid understanding without bloating the description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only query with full schema documentation, an output schema, and safety annotations, the description is nearly sufficient. The main missing element is explicit sibling differentiation for when to call this instead of check_visibility, but the example and function statement cover correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents all three parameters. The example maps brand_id, days, and granularity to concrete values, which is helpful illustration, but it does not add meaning beyond what the schema and enum definitions provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Return') and resource ('daily or weekly visibility history with per-engine evidence'), making the basic action unambiguous. It does not explicitly distinguish itself from the sibling check_visibility, but the 'history' framing and granularity options provide enough differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives like check_visibility or compare_competitors. The example shows how to invoke it but gives no exclusions, prerequisites, or context for choosing this tool over related siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_brandsList tracked brandsARead-onlyIdempotent
List tracked brands with metadata and active-prompt counts. Example: call before other tools when you need a brand_id.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | |
| brands | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds context about the return content (metadata, active-prompt counts) but does not disclose additional behavioral traits beyond what annotations provide. This meets the baseline for annotation-covered tools but does not go beyond it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste. The primary action and return content are front-loaded, followed by a practical usage example. Every word earns its place, making it an exemplary concise definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters), the presence of an output schema, and annotations covering safety, the description is complete. It tells the agent what the tool returns, when to use it, and why it matters (getting a brand_id). Nothing essential is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema trivially covers everything. Per the rubric, 0 params earns a baseline of 4. The description does not need to explain parameter semantics because none exist, and it appropriately focuses on output and usage instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('List') and resource ('tracked brands'), and adds specificity with 'metadata and active-prompt counts'. It gives an example usage, which implies differentiation from sibling tools that operate on a single brand, though it does not explicitly name a sibling. This is clear but stops short of the explicit contrast seen in top-tier definitions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a direct usage instruction: 'call before other tools when you need a brand_id.' This tells the agent when to use it, but it does not mention alternative tools or when not to use it. The guidance is helpful and context-rich, but lacks explicit exclusions or named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_promptsList active promptsARead-onlyIdempotent
List a brand's active buyer-intent prompts without changing them. Example: brand_id='acme' before an audit or refresh.
| Name | Required | Description | Default |
|---|---|---|---|
| brand_id | Yes | Brand ID whose active prompts to list. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| prompts | Yes | |
| brand_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, and destructiveHint=false. The description adds the behavioral constraint that only active prompts are listed, which is useful beyond the schema. It does not discuss pagination or auth, but the output schema and annotations cover the main safety/behavioral expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the first states the verb, resource, and non-mutation guarantee; the second provides a concrete example. The most decision-relevant information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one required parameter fully described in the schema, an output schema present, and annotations covering the read-only/idempotent nature, the description adds the remaining context needed (active-only scope and an example use case). Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and brand_id is already described as 'Brand ID whose active prompts to list.' The description adds an example value ('acme') but no additional semantic detail beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific operation ('List') and resource ('a brand's active buyer-intent prompts'), and explicitly adds 'without changing them', which distinguishes it from mutation siblings like set_prompts and generate_prompts. The example reinforces the intended scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'before an audit or refresh' gives a clear practical context for when to call this tool. It does not explicitly name alternatives or state when not to use it, but the non-mutation framing and sibling list make the intended usage fairly obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
refresh_brandRefresh AI visibility scanA
Run a fresh scan on selected configured engines using the brand's active prompts and return after completion. Example: brand_id='acme', engines=['chatgpt','gemini'].
| Name | Required | Description | Default |
|---|---|---|---|
| engines | No | Engines to run; omit for every configured engine. | |
| brand_id | Yes | Tracked brand ID to refresh. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | Yes | |
| run_ids | Yes | |
| brand_id | Yes | |
| estimated_completion_seconds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly=false and destructive=false. The description adds that the scan uses the brand's active prompts, runs only on selected configured engines, and returns only after completion – a useful synchronous behavior note. It stops short of explaining side effects or whether previous results are replaced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences plus an example; the main verb and object are front-loaded and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the small parameter surface, full schema descriptions, and presence of an output schema, the description covers the core behavior, input example, and completion semantics. It leaves minor gaps like runtime expectations and relationship to visibility-check siblings, but nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents both parameters at 100% coverage. The description adds a concrete example mapping brand_id and engines to values, but does not need to re-explain semantics; the schema's 'omit for every configured engine' note is the key guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action ('run a fresh scan'), the resource (brand visibility on configured engines), and the input context (active prompts). It distinguishes the tool from history/listing siblings by emphasizing 'fresh scan,' though it does not explicitly name or contrast siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'fresh scan' phrasing implies the tool is for regenerating current visibility data, and the example shows a concrete invocation. However, it never states when to prefer this over check_visibility or get_visibility_history, and gives no exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_promptsSet active promptsADestructiveIdempotent
Replace a brand's active prompts with an exact supplied set; history is preserved. Example: brand_id='acme', prompts=['What is the best X for Y?'].
| Name | Required | Description | Default |
|---|---|---|---|
| prompts | Yes | Exact 1-50 prompt set for future scans. | |
| brand_id | Yes | Tracked brand ID to update. |
Output Schema
| Name | Required | Description |
|---|---|---|
| changed | Yes | |
| prompts | Yes | |
| brand_id | Yes | |
| next_steps | Yes | |
| prompts_inserted | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate destructiveHint=true and idempotentHint=true. The description adds that history is preserved, which is important context not captured in annotations: although destructive, it doesn't destroy the history. This enriches the behavioral understanding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first is the core function, the second provides a concrete example. It is front-loaded and has no filler. Every word contributes to clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple two-parameter tool with full schema coverage and an output schema, the description is sufficient. It covers the replacement behavior, preservation of history, and an example. The only minor gap is not specifying the return value, but the output schema likely provides that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are well-documented in the schema. The description adds the example, which clarifies the exact format expected, and clarifies that 'prompts' is the exact set to be set. It does not add new meaning beyond the schema but reinforces the purpose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it replaces a brand's active prompts with an exact supplied set, distinguishing it from sibling list_prompts and generate_prompts. It uses a specific verb 'Replace' and indicates the resource (brand's active prompts) and the nature of the operation (overwrite with exact set).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a concrete example showing the expected parameters (brand_id and prompts) and implies the tool is for setting prompts, contrasting with siblings like generate_prompts. It does not explicitly state when not to use it, but the example and wording provide clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
track_brandTrack a brandAIdempotent
Create a local tracked brand and starter buyer-intent prompts; uses Claude Haiku when configured, otherwise three generic prompts. Example: brand_id='acme', name='Acme', domain='acme.com'. Call refresh_brand next.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Brand display name. | |
| domain | Yes | Primary domain, e.g. 'acme.com'. | |
| aliases | No | Additional names that count as brand mentions. | |
| brand_id | Yes | New stable brand ID, e.g. 'acme'. | |
| category | No | Market/category for prompt generation. | |
| competitors | No | Competitor domains to compare. | |
| prompt_count | No | Buyer-intent prompts to create. | |
| exclude_terms | No | Bare terms to ignore in mention matching; the full domain still matches. | |
| refresh_frequency | No | Worker cron cadence; 'manual' disables cron scans. Local stdio stores this setting only. | weekly |
Output Schema
| Name | Required | Description |
|---|---|---|
| domain | No | |
| reason | No | |
| seeded | Yes | |
| brand_id | Yes | |
| next_steps | Yes | |
| competitors | No | |
| prompt_source | No | |
| prompts_inserted | No | |
| refresh_frequency | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false. The description adds meaningful behavioral context beyond those: it mentions the model selection behavior ('uses Claude Haiku when configured, otherwise three generic prompts'), the local scope ('local tracked brand'), and the follow-up action. No contradictions with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences plus a short example: purpose, model behavior, example values, and next-step instruction. Every segment carries weight, no filler, and the core action is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 9 parameters, annotations, and an output schema, the description covers purpose, a usage example, model configuration, and the next step. It does not explicitly clarify when to use alternatives such as update_brand or generate_prompts, nor explain 'starter' prompt semantics, but the high schema coverage and output schema carry much of the load.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 even without parameter info in the description. The description provides a compact example mapping brand_id, name, and domain, but adds little beyond what the schema already documents; it does not explain parameter interactions like prompt_count or exclude_terms.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Create a local tracked brand') and a concrete additional output ('starter buyer-intent prompts'), which distinguishes it from siblings like refresh_brand, update_brand, and generate_prompts. The example clarifies the exact resource being created.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear workflow context is provided: it creates a brand plus prompts, and then explicitly instructs 'Call refresh_brand next.' There is no explicit 'use this instead of X' guidance or exclusions, but the purpose is unambiguous enough for an agent to know when to select it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_brandUpdate tracked brandAIdempotent
Change tracked-brand metadata without replacing prompts or history. Example: brand_id='acme', competitors=['rival.com'], refresh_frequency='manual' pauses cron scans but keeps manual refresh.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New display name. | |
| domain | No | New primary domain. | |
| aliases | No | Replacement mention aliases. | |
| brand_id | Yes | Tracked brand ID to update. | |
| category | No | New category, or null to clear it. | |
| competitors | No | Replacement competitor domains. | |
| exclude_terms | No | Replacement bare terms to ignore in mention matching. | |
| refresh_frequency | No | New cadence; 'manual' pauses cron scans. |
Output Schema
| Name | Required | Description |
|---|---|---|
| brand | Yes | |
| updated | Yes | |
| brand_id | Yes | |
| next_steps | Yes | |
| changed_fields | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry the idempotent and non-destructive profile. The description adds genuine value by disclosing what it does NOT destroy ('without replacing prompts or history') and by revealing the cron behavior ('refresh_frequency='manual' pauses cron scans but keeps manual refresh'), which is behavioral nuance not present in the annotations or schema. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero filler: the purpose and scope are front-loaded first, followed by a single illustrative example that demonstrates the non-obvious cron-pause behavior. Every sentence earns its place and nothing extraneous is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool this is well covered: the output schema exists so return values need not be described, annotations carry the idempotent/destructive profile, and the openWorldHint/readOnlyHint are set. The description adds the key behavioral caveats (no prompt/history loss, cron pause). Minor gaps remain—there is no explicit note about partial-update semantics (whether omitted fields are preserved) and no error-case guidance—but these are modest against the rich schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every one of the 8 parameters is individually documented and the baseline is 3. The example (brand_id='acme', competitors=['rival.com'], refresh_frequency='manual') adds a small amount of combinational usage context tying parameters to behavior, but does not add per-parameter meaning beyond the schema. The description itself contains no parameter syntax details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb-plus-resource ('Change tracked-brand metadata') and clarifies scope by explicitly excluding what it does not touch ('without replacing prompts or history'). This differentiates it from sibling tools like set_prompts (prompts) and refresh_brand (data refresh), and from track_brand (creation), which share the brand domain.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for metadata updates by contrasting with prompt/history replacement, but it never explicitly names siblings or states when-not-to-use it (e.g., 'to fetch fresh data use refresh_brand'). The example hints at the refresh-frequency behavior but leaves the selection logic to the agent's inference rather than stating it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.3.24- Changed
get_citations2 fields changed- added
Output schema / properties / top_sourcesAdded value: +{ + "items": { + "additionalProperties": false, + "properties": { + "citation_count": { + "type": "number" + }, + "domain": { + "type": "string" + }, + "engines": { + "items": { + "type": "string" + }, + "type": "array" + }, + "is_brand_domain": { + "type": "boolean" + }, + "prompt_count": { + "type": "number" + }, + "sample_url": { + "type": "string" + } + }, + "required": [ + "domain", + "citation_count", + "prompt_count", + "engines", + "sample_url", + "is_brand_domain" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / requiredPrevious value: -[ - "brand_id", - "days", - "engine", - "citations" -]New value: +[ + "brand_id", + "days", + "engine", + "top_sources", + "citations" +]
11 tool updates
v0.3.23- Changed
check_visibility2 fields changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to inspect."New value: +"Tracked brand ID to inspect." - changed
Input schema / properties / engines / descriptionPrevious value: -"Optional engine filter. If omitted or empty, return results for every engine with stored data."New value: +"Engines to include; omit or pass [] for all stored engines."
- Changed
compare_competitors3 fields changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to compare."New value: +"Tracked brand ID to compare." - changed
Input schema / properties / competitor_domains / descriptionPrevious value: -"Optional competitor domains to compare; otherwise use the brand's configured competitors."New value: +"Competitor domains; omit to use the brand's configured list." - changed
Input schema / properties / days / descriptionPrevious value: -"Number of previous days to include in the comparison."New value: +"Previous days to compare."
- Changed
generate_prompts2 fields changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to update."New value: +"Tracked brand ID to update." - changed
Input schema / properties / count / descriptionPrevious value: -"Number of buyer-intent prompts to generate."New value: +"Buyer-intent prompts to generate."
- Changed
get_citations3 fields changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to inspect."New value: +"Tracked brand ID to inspect." - changed
Input schema / properties / days / descriptionPrevious value: -"Number of previous days from which to return citations."New value: +"Previous days to search." - changed
Input schema / properties / engine / descriptionPrevious value: -"Optional engine filter for the citation events."New value: +"Engine to filter by; omit for all engines."
- Changed
get_content_gaps2 fields changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to analyze."New value: +"Tracked brand ID to analyze." - changed
Input schema / properties / max_recommendations / descriptionPrevious value: -"Maximum number of content recommendations to return."New value: +"Maximum recommendations to return."
- Changed
get_visibility_history3 fields changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to inspect."New value: +"Tracked brand ID to inspect." - changed
Input schema / properties / days / descriptionPrevious value: -"Number of previous calendar days to include."New value: +"Previous calendar days to include." - changed
Input schema / properties / granularity / descriptionPrevious value: -"Time bucket for the returned visibility series."New value: +"Time bucket for the series."
- Changed
list_prompts1 field changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand whose active prompts to inspect."New value: +"Brand ID whose active prompts to list."
- Changed
refresh_brand2 fields changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to refresh."New value: +"Tracked brand ID to refresh." - changed
Input schema / properties / engines / descriptionPrevious value: -"Optional engine filter. If omitted, refresh every configured engine."New value: +"Engines to run; omit for every configured engine."
- Changed
set_prompts2 fields changed- changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to update."New value: +"Tracked brand ID to update." - changed
Input schema / properties / prompts / descriptionPrevious value: -"Exact active prompt set to use for future scans (1-50 questions)."New value: +"Exact 1-50 prompt set for future scans."
- Changed
track_brand9 fields changed- changed
Input schema / properties / aliases / descriptionPrevious value: -"Extra terms that always count as a brand mention (product names, abbreviations)."New value: +"Additional names that count as brand mentions." - changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier to assign to the new tracked brand."New value: +"New stable brand ID, e.g. 'acme'." - changed
Input schema / properties / category / descriptionPrevious value: -"Optional product or market category for prompt generation."New value: +"Market/category for prompt generation." - changed
Input schema / properties / competitors / descriptionPrevious value: -"Optional competitor domains to include in visibility analysis."New value: +"Competitor domains to compare." - changed
Input schema / properties / domain / descriptionPrevious value: -"Primary domain of the brand, such as acme.com."New value: +"Primary domain, e.g. 'acme.com'." - changed
Input schema / properties / exclude_terms / descriptionPrevious value: -"Terms suppressed from bare-word matching — for brand names that are everyday words (\"Monday\", \"Notion\"). The full domain still matches."New value: +"Bare terms to ignore in mention matching; the full domain still matches." - changed
Input schema / properties / name / descriptionPrevious value: -"Display name of the brand to track."New value: +"Brand display name." - changed
Input schema / properties / prompt_count / descriptionPrevious value: -"Number of buyer-intent prompts to generate for the brand."New value: +"Buyer-intent prompts to create." - changed
Input schema / properties / refresh_frequency / descriptionPrevious value: -"Refresh cadence used by self-hosted Worker cron scheduling. Choose 'manual' to disable cron scans while keeping the brand, prompts, and history. Local stdio stores this setting but does not run a background scheduler."New value: +"Worker cron cadence; 'manual' disables cron scans. Local stdio stores this setting only."
- Changed
update_brand8 fields changed- added
Input schema / properties / aliases / descriptionAdded value: +"Replacement mention aliases." - changed
Input schema / properties / brand_id / descriptionPrevious value: -"Stable identifier of the tracked brand to update."New value: +"Tracked brand ID to update." - added
Input schema / properties / category / descriptionAdded value: +"New category, or null to clear it." - added
Input schema / properties / competitors / descriptionAdded value: +"Replacement competitor domains." - added
Input schema / properties / domain / descriptionAdded value: +"New primary domain." - added
Input schema / properties / exclude_terms / descriptionAdded value: +"Replacement bare terms to ignore in mention matching." - added
Input schema / properties / name / descriptionAdded value: +"New display name." - added
Input schema / properties / refresh_frequency / descriptionAdded value: +"New cadence; 'manual' pauses cron scans."
6 tool updates
v0.3.19- Changed
check_visibility1 field changed- changed
Input schema / properties / engines / items / enumPrevious value: -[ - "chatgpt", - "claude", - "perplexity", - "gemini", - "grok", - "ai_overviews" -]New value: +[ + "chatgpt", + "claude", + "perplexity", + "gemini", + "grok", + "ai_overviews", + "ai_mode" +]
- Changed
get_citations1 field changed- changed
Input schema / properties / engine / enumPrevious value: -[ - "chatgpt", - "claude", - "perplexity", - "gemini", - "grok", - "ai_overviews" -]New value: +[ + "chatgpt", + "claude", + "perplexity", + "gemini", + "grok", + "ai_overviews", + "ai_mode" +]
- Changed
list_brands3 fields changed- added
Output schema / properties / brands / items / properties / aliasesAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / brands / items / properties / exclude_termsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / properties / brands / items / requiredPrevious value: -[ - "brand_id", - "name", - "domain", - "category", - "competitors", - "refresh_frequency", - "active_prompts", - "created_at" -]New value: +[ + "brand_id", + "name", + "domain", + "category", + "competitors", + "aliases", + "exclude_terms", + "refresh_frequency", + "active_prompts", + "created_at" +]
- Changed
refresh_brand1 field changed- changed
Input schema / properties / engines / items / enumPrevious value: -[ - "chatgpt", - "claude", - "perplexity", - "gemini", - "grok", - "ai_overviews" -]New value: +[ + "chatgpt", + "claude", + "perplexity", + "gemini", + "grok", + "ai_overviews", + "ai_mode" +]
- Changed
track_brand3 fields changed- changed
Input schema / properties / refresh_frequency / descriptionPrevious value: -"Refresh cadence used by self-hosted Worker cron scheduling. Local stdio stores this setting but does not run a background scheduler."New value: +"Refresh cadence used by self-hosted Worker cron scheduling. Choose 'manual' to disable cron scans while keeping the brand, prompts, and history. Local stdio stores this setting but does not run a background scheduler." - changed
Input schema / properties / refresh_frequency / enumPrevious value: -[ - "daily", - "weekly" -]New value: +[ + "daily", + "weekly", + "manual" +] - changed
Output schema / properties / refresh_frequency / enumPrevious value: -[ - "daily", - "weekly" -]New value: +[ + "daily", + "weekly", + "manual" +]
- Added
update_brand
3 tool updates
v0.3.18- Changed
check_visibility1 field changed- changed
Input schema / properties / engines / items / enumPrevious value: -[ - "chatgpt", - "claude", - "perplexity", - "gemini", - "ai_overviews" -]New value: +[ + "chatgpt", + "claude", + "perplexity", + "gemini", + "grok", + "ai_overviews" +]
- Changed
get_citations1 field changed- changed
Input schema / properties / engine / enumPrevious value: -[ - "chatgpt", - "claude", - "perplexity", - "gemini", - "ai_overviews" -]New value: +[ + "chatgpt", + "claude", + "perplexity", + "gemini", + "grok", + "ai_overviews" +]
- Changed
refresh_brand1 field changed- changed
Input schema / properties / engines / items / enumPrevious value: -[ - "chatgpt", - "claude", - "perplexity", - "gemini", - "ai_overviews" -]New value: +[ + "chatgpt", + "claude", + "perplexity", + "gemini", + "grok", + "ai_overviews" +]
1 tool update
v0.3.17- Added
set_prompts
5 tool updates
v0.3.15- Changed
check_visibility12 fields changed- added
Output schema / properties / per_engine / items / additionalPropertiesAdded value: +false - added
Output schema / properties / per_engine / items / propertiesAdded value: +{ + "engine": { + "type": "string" + }, + "prompts_appeared_in": { + "type": "number" + }, + "refreshed_at": { + "type": "string" + }, + "score": { + "type": "number" + }, + "total_prompts": { + "type": "number" + } +} - added
Output schema / properties / per_engine / items / requiredAdded value: +[ + "engine", + "score", + "prompts_appeared_in", + "total_prompts", + "refreshed_at" +] - added
Output schema / properties / per_engine / items / typeAdded value: +"object" - added
Output schema / properties / top_losing_prompts / items / additionalPropertiesAdded value: +false - added
Output schema / properties / top_losing_prompts / items / propertiesAdded value: +{ + "competitors_cited": { + "items": { + "type": "string" + }, + "type": "array" + }, + "prompt": { + "type": "string" + } +} - added
Output schema / properties / top_losing_prompts / items / requiredAdded value: +[ + "prompt", + "competitors_cited" +] - added
Output schema / properties / top_losing_prompts / items / typeAdded value: +"object" - added
Output schema / properties / top_winning_prompts / items / additionalPropertiesAdded value: +false - added
Output schema / properties / top_winning_prompts / items / propertiesAdded value: +{ + "engines_cited_in": { + "items": { + "type": "string" + }, + "type": "array" + }, + "prompt": { + "type": "string" + } +} - added
Output schema / properties / top_winning_prompts / items / requiredAdded value: +[ + "prompt", + "engines_cited_in" +] - added
Output schema / properties / top_winning_prompts / items / typeAdded value: +"object"
- Changed
get_content_gaps4 fields changed- added
Output schema / properties / recommendations / items / additionalPropertiesAdded value: +false - added
Output schema / properties / recommendations / items / propertiesAdded value: +{ + "priority": { + "maximum": 5, + "minimum": 1, + "type": "integer" + }, + "rationale": { + "type": "string" + }, + "suggested_format": { + "enum": [ + "comparison_page", + "listicle", + "how_to_guide", + "faq_page", + "case_study", + "pricing_page", + "integration_landing_page" + ], + "type": "string" + }, + "topic": { + "type": "string" + } +} - added
Output schema / properties / recommendations / items / requiredAdded value: +[ + "priority", + "topic", + "rationale", + "suggested_format" +] - added
Output schema / properties / recommendations / items / typeAdded value: +"object"
- Changed
get_visibility_history2 fields changed- added
Output schema / properties / series / items / properties / per_engine_evidenceAdded value: +{ + "additionalProperties": { + "additionalProperties": false, + "properties": { + "brand_mentions": { + "type": "number" + }, + "observed_at": { + "type": "string" + }, + "usable_prompts": { + "type": "number" + } + }, + "required": [ + "brand_mentions", + "usable_prompts", + "observed_at" + ], + "type": "object" + }, + "propertyNames": { + "type": "string" + }, + "type": "object" +} - changed
Output schema / properties / series / items / requiredPrevious value: -[ - "date", - "overall_score", - "per_engine" -]New value: +[ + "date", + "overall_score", + "per_engine", + "per_engine_evidence" +]
- Added
list_prompts - Changed
track_brand2 fields changed- added
Input schema / properties / refresh_frequencyAdded value: +{ + "default": "weekly", + "description": "Refresh cadence used by self-hosted Worker cron scheduling. Local stdio stores this setting but does not run a background scheduler.", + "enum": [ + "daily", + "weekly" + ], + "type": "string" +} - added
Output schema / properties / refresh_frequencyAdded value: +{ + "enum": [ + "daily", + "weekly" + ], + "type": "string" +}
1 tool update
v0.3.8- Changed
compare_competitors4 fields changed- added
Output schema / properties / competitors / items / properties / mentionsAdded value: +{ + "type": "number" +} - changed
Output schema / properties / competitors / items / requiredPrevious value: -[ - "domain", - "share_of_voice_pct", - "prompts_won_against_you" -]New value: +[ + "domain", + "share_of_voice_pct", + "mentions", + "prompts_won_against_you" +] - added
Output schema / properties / your_mentionsAdded value: +{ + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "brand_id", - "days", - "your_share_of_voice_pct", - "competitors", - "prompts_you_win", - "requested_competitor_domains" -]New value: +[ + "brand_id", + "days", + "your_share_of_voice_pct", + "your_mentions", + "competitors", + "prompts_you_win", + "requested_competitor_domains" +]
3 tool updates
v0.3.4- Changed
check_visibility3 fields changed- changed
Input schema / properties / engines / descriptionPrevious value: -"Optional engine filter. If omitted, return results for every engine with stored data."New value: +"Optional engine filter. If omitted or empty, return results for every engine with stored data." - removed
Output schema / properties / brand / properties / category / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / brand / properties / category / typeAdded value: +[ + "string", + "null" +]
- Changed
get_citations4 fields changed- removed
Output schema / properties / citations / items / properties / cited_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / citations / items / properties / cited_url / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / engine / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / engine / typeAdded value: +[ + "string", + "null" +]
- Changed
list_brands2 fields changed- removed
Output schema / properties / brands / items / properties / category / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / brands / items / properties / category / typeAdded value: +[ + "string", + "null" +]
9 tool updates
v0.3.2- First observed
check_visibility - First observed
compare_competitors - First observed
generate_prompts - First observed
get_citations - First observed
get_content_gaps - First observed
get_visibility_history - First observed
list_brands - First observed
refresh_brand - First observed
track_brand
TDQS
Scored across 12 tools
Most tools are clearly separated by resource and action, and descriptions clarify temporal or comparison scope. The main ambiguity is between generate_prompts and set_prompts, which both replace active prompts and preserve history, and check_visibility versus get_visibility_history could cause a minor misselection for current data.
All tools use a consistent snake_case verb_noun pattern such as get_, list_, set_, refresh_, track_, update_, compare_, and check_. There are no mixed naming conventions or vague verbs.
Twelve tools is within the ideal 3-15 range and matches the server's scope: brand management, prompt management, visibility retrieval, and competitor analysis. Each tool has a distinct role without feeling padded or redundant.
The server covers brand creation/update/listing, prompt listing/setting/generation, and comprehensive visibility, citation, and competitor reads. The main gap is lifecycle deletion: there is no delete_brand or remove_prompt, though set_prompts can replace prompt sets as a partial workaround.
Maintenance
Related MCP Connectors
Open-source AI SEO over MCP: audits, ranks, keywords, backlinks + AI visibility (GEO).
Cloudflare Workers MCP server: ai-rate-limit-tracker
Cloudflare Workers MCP server: ai-provider-status
Track brand visibility in ChatGPT, Gemini and Google AI answers: competitors, cited sources, checks.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceA production-ready MCP server for AI agents, providing deep web research and RAG capabilities via Cloudflare Workers.-
- AlicenseAqualityDmaintenanceA self-hosted MCP server that gives AI agents deep internet research capabilities — no API keys required, powered by SearxNG, Playwright, and Docker.497 npmISC

seocrawl-mcpofficial
AlicenseBqualityDmaintenanceSEO + GEO MCP server: live Google Search Console & GA4 data, keyword and page analysis, AI-visibility tracking across ChatGPT, Claude, Gemini & Perplexity, site audit and SEO task management — all from chat.382MIT- AlicenseAqualityAmaintenanceEnables AI coding assistants to validate HTML/CSS markup using W3C APIs, perform technical SEO audits, check broken links, and validate JSON-LD schemas directly in local workspaces.82,854 npm7MIT