Skip to main content
Glama
AKzar1el

GEO MCP by DigestSEO

DigestSEO — AI Visibility MCP for SEO & GEO

CI npm version MCP Registry License: MIT TypeScript Cloudflare Workers MCP mcp-geo MCP server GitHub stars

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, SERPAPI_API_KEY); engines without a key skip gracefully.

Runtime: Node.js 22+ (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"
      }
    }
  }
}

Claude Code:

claude mcp add --transport stdio digestseo -s user --env GEMINI_API_KEY=your_key_here -- npx -y @digestseo/mcp-geo

Cursor:

Add to Cursor

Kiro (hosted endpoint):

Add to Kiro

Uses the hosted OAuth endpoint, so no engine API keys are placed in the Kiro install link.

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, and Google AI Overviews. It's the GEO (Generative Engine Optimization) and AEO (Answer Engine Optimization) equivalent of Google Search Console — built as an MCP server so you can query your AI visibility data directly inside Claude.ai, Claude Desktop, Claude Code, 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

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:

Example AI visibility report

View the full report including content gaps, engine recommendations, and synthesis →

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.2] — July 27, 2026

  • Published scoped package: @digestseo/mcp-geo with 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-db D1 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 the X-Seed-Secret-gated /admin/* routes.

  • Runtime-agnostic core (src/core/) shared by the Worker and the CLI, with a Db contract implemented by D1 and better-sqlite3 adapters. All 0.2.1 accuracy and security fixes carry over to both runtimes.

  • Distribution metadata: official MCP Registry server.json, MCPB desktop extension (.mcpb bundle), Dockerfile, llms-install.md for AI agents, release-publish workflow.

[0.2.1] — June 2026

  • Optional CONNECT_SECRET gate on the OAuth flow. By default the OSS build auto-completes /authorize for any MCP client that knows your worker URL — anyone who finds the URL can connect and call visibility.refresh, spending your engine API credits. Set CONNECT_SECRET and the browser step of the connect flow now asks for it before issuing a token. See SECURITY.md.

  • Accurate citation matching. Brand/competitor mentions now require word boundaries (acme no longer matches "acmeshop"), and linked-citation checks require the exact domain or a subdomain (notacme.com no longer counts as a link to acme.com).

  • Per-brand aliases and exclude_terms. Aliases always count as a mention; exclude terms suppress the bare-word match on the brand name and domain root — so "Monday" the brand stops matching "monday" the weekday, while monday.com still counts. Apply migrations/0005_brand_alias_exclude.sql; existing brands behave exactly as before.

  • visibility.history consistency. Partially-finished runs now count toward history (matching visibility.check's 0.2.0 behavior), and fully-failed runs no longer show up as fake zero scores.

  • CI + unit tests. GitHub Actions runs tsc --noEmit plus 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 — the Gemini free tier rate-limits brands with more than ~5 prompts and produced 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-live now creates one runs row per engine and self-fetches /admin/run-engine once per engine. Each engine runs in its own worker invocation with its own free-plan 50-subrequest budget — a single-invocation fan-out used to burst past the cap mid-run and lose half the rows.

  • 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) plus error_message. Failed engine calls used to write raw_response='ERROR: ...' rows that downstream scoring treated as real zero-mention hits; now they're explicitly excluded.

  • FK-resistant inserts. /admin/run-engine INSERT OR IGNOREs its runs row before persisting — D1 is eventually consistent across edge regions, and the upstream INSERT INTO runs from /admin/run-live doesn't always replicate before the downstream engine call lands. The IGNORE makes the FK happy either way.

  • 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 single D1.batch() call. Drops the per-invocation subrequest count from ~89 to ~26.

  • Relaxed visibility queries. getLatestCompletedRun anchors on EXISTS(ok rows) instead of status='completed', so partially-finished runs still surface their data in MCP tool output instead of silently disappearing.

  • New admin route POST /admin/cleanup-failed-runs for 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

Tool

What it does

What you provide

visibility.check

Latest AI visibility snapshot across all configured engines for a tracked brand, with per-engine scores, winning prompts, and losing prompts.

brand_id, optional engines[] filter

visibility.history

Time-series history of overall and per-engine visibility, bucketed daily or weekly.

brand_id, optional days (default 30), optional granularity (daily/weekly)

visibility.compare

Share-of-voice comparison against competitor domains, with prompts you win and prompts they win.

brand_id, optional competitor_domains[], optional days

visibility.citations

The actual citation events — prompt, engine, response excerpt, citation type, brand URL when present.

brand_id, optional days, optional engine filter

visibility.content_gaps

Prioritized Claude-Haiku-generated content recommendations targeting your losing prompts.

brand_id, optional max_recommendations (1-10)

visibility.refresh

Manually trigger a fresh scan across every engine whose API key is set.

brand_id, optional engines[] filter

The local stdio CLI (npx, desktop extension, Docker) additionally provides brand management — on a Workers deployment the same operations live behind the X-Seed-Secret-gated /admin/* routes instead:

Tool (local CLI only)

What it does

What you provide

track_brand

Start tracking a brand: creates it locally and generates its buyer-intent prompt set (Claude Haiku when ANTHROPIC_API_KEY is set, three starter prompts otherwise).

brand_id, name, domain, optional category, competitors[], aliases[], exclude_terms[], prompt_count

list_brands

List tracked brands with domains, competitors, and active prompt counts.

generate_prompts

Regenerate a brand's prompt set via Claude Haiku (replaces active prompts, keeps history).

brand_id, optional count (default 20)


Getting Started

Step 1 — Get API keys

Engines are opt-in. Pick the ones you want; the rest skip silently.

  • OpenAI — ChatGPT engine. ~€0.0004 per prompt with gpt-4o-mini. Batch path roughly halves that. platform.openai.com

  • 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. ~€0.0001 per prompt. The free tier has a low per-minute cap, so brands with more than ~5 prompts hit HTTP 429 and drop out of scoring (see Troubleshooting) — treat it as an opt-in add-on, not a starting engine. aistudio.google.com

  • Perplexity — Perplexity Sonar engine. ~€0.005-0.008 per prompt. Paid only. perplexity.ai/settings/api

  • SerpAPI — Google AI Overviews engine. ~€0.005 (free tier) / ~€0.0015 (volume) per prompt. Free tier covers 250 searches/month — enough for development. serpapi.com/dashboard

Recommended starting pair: OpenAI + Anthropic (Claude). Both bill per token with no rate-limit surprises, so your first scan returns clean, scorable data across the ChatGPT and Claude engines — and the Anthropic key also powers prompt generation and content-gap analysis. Solo evaluation runs comfortably under €1/month on the two together. Add Gemini, Perplexity, or SerpAPI deliberately once you want more coverage; Gemini's free tier rate-limits and Google AI Overviews often returns no result (scored as a zero), so leading with the cheapest path can skew your first run.

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 — both bill per token, clean first-run data:
npx wrangler secret put SEED_SECRET
npx wrangler secret put CONNECT_SECRET      # recommended — gates who can connect (see SECURITY.md)
npx wrangler secret put OPENAI_API_KEY      # ChatGPT engine
npx wrangler secret put ANTHROPIC_API_KEY   # Claude engine + prompt generation

# 6. Apply migrations and deploy
npx wrangler d1 migrations apply mcp-geo-db --remote
npx wrangler deploy

The production MCP endpoint is the product-based custom domain:

https://geo-mcp.digestseo.com/mcp

Use that exact URL when publishing digestseo/mcp-geo on Smithery.ai. The endpoint is OAuth-protected, so Smithery will complete its normal MCP authorization flow during inspection.

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/mcp

Complete the OAuth handshake. The connector turns green when ready.

Claude Code

claude mcp add --transport http digestseo https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/mcp

Then run /mcp inside Claude Code to complete the OAuth handshake in your browser.

Claude Desktop

Edit your Claude Desktop config:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %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

OPENAI_API_KEY

opt-in

unset

Enables the ChatGPT engine. Without it, ChatGPT is skipped.

ANTHROPIC_API_KEY

opt-in

unset

Enables the Claude engine and the Claude-Haiku-powered prompt generator + content-gap analyzer.

GEMINI_API_KEY

opt-in

unset

Enables the Gemini engine. Free tier is rate-limited for brands with more than ~5 prompts (see Troubleshooting); opt-in add-on.

PERPLEXITY_API_KEY

opt-in

unset

Enables the Perplexity Sonar engine. Paid only.

SERPAPI_API_KEY

opt-in

unset

Enables the Google AI Overviews engine (via SerpAPI).

SEED_SECRET

yes

unset

Shared secret that gates every /admin/* route. Pick a high-entropy string.

CONNECT_SECRET

recommended

unset

When set, the OAuth connect flow asks for this secret in the browser before issuing a token. Without it, anyone who knows your worker URL can connect an MCP client. See SECURITY.md.

TURNSTILE_SITE_KEY

no

unset

Reserved for forks that add a public /check form. Unused by the OSS build.

TURNSTILE_SECRET_KEY

no

unset

Same — reserved for forks.

All values are set via wrangler secret put VAR in production or .dev.vars locally. None are stored in wrangler.jsonc.


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 --> DO["GeoMcpAgent<br/>(Durable Object, 6 MCP tools)"]
    W -- "one self-fetch per engine<br/>via SELF service binding" --> RE["/admin/run-engine<br/>(own invocation per engine)"]
    RE --> E1["OpenAI"]
    RE --> E2["Anthropic"]
    RE --> E3["Gemini"]
    RE --> E4["Perplexity"]
    RE --> E5["SerpAPI<br/>(AI Overviews)"]
    RE --> DB[("D1<br/>brands / prompts / runs /<br/>responses / cache")]
    DO --> DB

Each engine runs in its own Worker invocation with its own free-plan 50-subrequest budget; results are flushed in a single D1.batch() per engine. The whole system fits the Cloudflare free tier for a single brand on a daily cadence.


Security

  • /admin/* is gated by SEED_SECRET (constant-time compared).

  • /mcp requires OAuth; set CONNECT_SECRET so only people with the secret can complete the connect flow — strongly recommended whenever your worker URL is shared anywhere, since connected clients can call visibility.refresh and spend your engine API credits.

  • 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

visibility.check

"How visible is brand_id acme on AI right now?"

visibility.history

"Show me the visibility trend for acme over the last 60 days, daily."

visibility.compare

"Compare acme against asana.com and monday.com over the last 14 days."

visibility.citations

"Show me real Perplexity citations for acme from the last week."

visibility.content_gaps

"What content should acme publish to close its visibility gap? Give me the top 5."

visibility.refresh

"Refresh acme across every available engine right now."

visibility.refresh

"Refresh acme but only for Gemini and Claude."


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 list and add the keys you intend to use. Engines without keys are silently skipped, which can leave visibility.check with no data.

  • no engines available error in logs — no engine API keys are set at all. Set at least one of OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, PERPLEXITY_API_KEY, SERPAPI_API_KEY.

  • D1 migration fails — make sure you've run npx wrangler d1 migrations apply mcp-geo-db --remote (and also --local for wrangler dev). For ad-hoc fixes, npx wrangler d1 execute mcp-geo-db --remote --file=migrations/0001_initial.sql.

  • 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 set CONNECT_SECRET, the browser step shows a one-field form — enter the secret you set during deploy. If it loops, clear the connector and re-add it. Double-check the Worker is publicly reachable (curl https://YOUR-WORKER-NAME.YOUR-SUBDOMAIN.workers.dev/healthz should return ok).

  • 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, run npx wrangler deploy again — the trigger is registered on deploy. The handler also only dispatches engines for brands whose refresh_frequency cadence has elapsed, so a freshly-seeded brand might not fire on the next 6h boundary.

  • 401 unauthorized from /admin/*X-Seed-Secret header is missing or doesn't match the deployed SEED_SECRET. Re-run npx wrangler secret put SEED_SECRET and update your .env.test.

  • Worker returns 404 on self-fetch / error code 1042 — the services binding in wrangler.jsonc is missing or the service name doesn't match the worker's name field. /admin/run-live self-fetches /admin/run-engine via env.SELF (a Cloudflare service binding) precisely because a public-URL fetch back to your own workers.dev hostname is blocked by Cloudflare's "Worker called itself" guard. Confirm the wrangler.jsonc you deployed contains "services": [{ "binding": "SELF", "service": "<your-worker-name>" }] with the same name you set in the top-level "name" field. After fixing, npx wrangler deploy and re-run.

  • Gemini rate limit (HTTP 429) on every prompt — the Gemini free tier caps gemini-2.5-flash-lite at single-digit requests per minute and a low daily total. For brands with more than ~5 prompts you'll see status='failed' rows with 429 error messages, which excludes Gemini from scoring. Workarounds: upgrade to paid Gemini, switch the MODEL constant in src/core/gemini.ts to a different model with a higher quota, or invoke /admin/run-engine for one engine at a time so the per-minute window has time to refill between batches.

  • FOREIGN KEY constraint failed in wrangler tail during /admin/run-engine — the handler defensively INSERT OR IGNOREs the runs row before persisting prompt responses. This is an idempotency/FK guard for independently dispatched engine work, so you should not see this on the 0.2.0+ build; if you do, confirm you've deployed the latest src/index.ts (grep -n "INSERT OR IGNORE INTO runs" src/index.ts should match).


Contributing

Issues and PRs welcome. See CONTRIBUTING.md for the short version.


Privacy Policy

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 to whichever AI providers you configured with your own API keys (OpenAI, Anthropic, Google, Perplexity, and/or SerpAPI), and only to those; 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.


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-geo with synchronized Worker, MCP Registry, and MCPB metadata.

  • Hosted visibility.* tool namespaces with typed input/output schemas; local stdio names remain flat.

  • Dedicated mcp-geo-db D1 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 Db adapters.

  • MCP Registry server.json, MCPB desktop extension, Dockerfile, llms-install.md.

[0.2.1] — June 2026

  • Optional CONNECT_SECRET gate on the OAuth connect flow.

  • Word-boundary brand/competitor matching; exact-domain-or-subdomain linked-citation checks.

  • Per-brand aliases and exclude_terms (migration 0005) for homograph brands like Monday/Notion.

  • visibility.history includes 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.SELF service binding (one worker invocation per engine, dodges Cloudflare's 1042 self-call guard).

  • status + error_message columns on prompt_responses — failed engine calls are now explicit rows, no more ERROR: strings in raw_response.

  • INSERT OR IGNORE on the runs row inside /admin/run-engine (handles D1 cross-region replication lag without dropping prompt_responses to FK violations).

  • 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).

  • getLatestCompletedRun anchored on EXISTS(ok rows); partially-finished runs still show their data.

  • New POST /admin/cleanup-failed-runs admin 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

9 tools
check_visibilityA
Read-only
Inspect

Get the latest AI visibility data for a tracked brand: which AI assistants (ChatGPT, Claude, Perplexity, Gemini, Google AI Overviews) cite this brand, for which prompts, and how it compares to competitors. Use when the user asks 'how visible am I on AI?', 'who's citing my brand?', or 'show me my AI visibility score'. Returns stored data — for fresh data, call refresh_brand.

ParametersJSON Schema
NameRequiredDescriptionDefault
enginesNoOptional engine filter. If omitted, return results for every engine with stored data.
brand_idYesStable identifier of the tracked brand to inspect.

Output Schema

ParametersJSON Schema
NameRequiredDescription
brandYes
per_engineYes
refreshed_atYes
overall_scoreYes
top_losing_promptsYes
top_winning_promptsYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, establishing this as a safe read operation, so the bar for behavioral disclosure is lower. The description adds meaningful context by explicitly stating 'Returns stored data' and pointing to refresh_brand for freshness — a key behavioral trait that prevents agents from expecting live data. This is valuable context beyond 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, and every clause earns its place. The example queries and the refresh_brand note are high-value additions with zero waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema (so return format need not be explained), full schema coverage of both parameters, complete usage examples, and a clear alternative-path note. The description covers what the tool does, when to use it, what it returns (stored data), and when not to use it — complete for this complexity level.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: brand_id is 'Stable identifier of the tracked brand to inspect' and engines is fully documented with its enum options and default behavior. Since the schema handles all parameter semantics completely, the description isn't required to add param info, landing at the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Get'), the resource (AI visibility data for a tracked brand), and scope (which AI assistants cite the brand, for which prompts, and competitor comparison). It distinctly separates this from siblings like get_visibility_history and compare_competitors by focusing on the current snapshot of citation data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit example user queries ('how visible am I on AI?', 'who's citing my brand?', 'show me my AI visibility score') as triggers. Critically, it names a sibling alternative (refresh_brand) and explicitly directs when that should be used instead ('for fresh data, call refresh_brand'), satisfying the when/when-not requirements.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_competitorsA
Read-only
Inspect

Compare a brand's AI visibility against competitors for the same category. Returns share-of-voice percentages, prompts the user wins, and prompts where competitors win. Use when the user asks 'who beats me in AI search?', 'compare me to my competitors', or 'why does [competitor] get cited more?'.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoNumber of previous days to include in the comparison.
brand_idYesStable identifier of the tracked brand to compare.
competitor_domainsNoOptional competitor domains to compare; otherwise use the brand's configured competitors.

Output Schema

ParametersJSON Schema
NameRequiredDescription
daysYes
brand_idYes
competitorsYes
prompts_you_winYes
your_share_of_voice_pctYes
requested_competitor_domainsYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds the category-scoping context and the exact outputs (SoV percentages, winning prompts). However, it doesn't disclose behaviors like how competitors are determined by default, the granularity of prompt-level detail, or availability of the data for different categories.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, all dense with useful information: purpose, return values, and trigger examples. Zero filler or redundancy. The description front-loads the core function and enumerates concrete outputs before giving usage examples.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema (which covers return format), good annotations (readOnlyHint), and 100% schema parameter coverage. The description provides trigger examples, expected outputs, and scoping context. Given this richness, the description is complete—nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with all three parameters described in the schema. The description's main value-add is explaining that competitor_domains defaults to the brand's configured competitors when not provided, which supplements the schema's phrasing. The core parameter semantics are handled by the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb+resource combo ('Compare a brand's AI visibility against competitors') and lists exact return values (share-of-voice percentages, prompts the user wins/loses). It clearly distinguishes from siblings by focusing on competitive comparison vs single-brand visibility (check_visibility, get_visibility_history).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly provides example user queries ('who beats me in AI search?', 'compare me to my competitors', 'why does [competitor] get cited more?') making trigger conditions crystal clear. Sibling tools like check_visibility and get_content_gaps handle single-brand or gap analysis, whereas this tool is specifically for competitive comparison, which the examples reinforce.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generate_promptsAInspect

Regenerate the buyer-intent prompt set for a tracked brand using Claude Haiku (requires ANTHROPIC_API_KEY). Replaces the brand's active prompts; historical run data is preserved. Use when the user wants better or more prompts, or to upgrade from the generic starter prompts after adding an Anthropic key.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNoNumber of buyer-intent prompts to generate.
brand_idYesStable identifier of the tracked brand to update.

Output Schema

ParametersJSON Schema
NameRequiredDescription
promptsYes
brand_idYes
next_stepsYes
prompt_sourceYes
prompts_insertedYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Description discloses that this generates prompts using Claude Haiku, requires an API key, and replaces active prompts while preserving historical run data. Annotations note readOnlyHint=false (mutation) which the description aligns with by stating prompts are replaced. Adds the API-key requirement and data-preservation behavior beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, efficient and front-loaded with the core action. Each clause earns its place, though it could arguably be trimmed slightly. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists (return values don't need explanation), 100% schema coverage, and clear annotations (mutation confirmed), the description fully covers prerequisites, effects, data safety, and usage context. Complete for a moderately complex mutation tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for both parameters. The description reinforces brand_id as the target and the count's default/range appears in schema. The description doesn't add heavy param detail but schema fully covers it, so baseline 3-4 is appropriate given high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('Regenerate the buyer-intent prompt set for a tracked brand') with clear scope and the model used. Distinguishes from siblings: siblings cover visibility, gaps, competitors, and brand tracking, while this uniquely handles prompt generation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use (user wants better/more prompts, upgrade from starter prompts after adding Anthropic key) and what prerequisites exist (requires ANTHROPIC_API_KEY). Clearly contrasts with generic starter prompts as the alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_citationsA
Read-only
Inspect

Get the actual citation events where AI assistants mentioned or linked to the brand. Each citation includes the prompt that triggered it, the LLM's response excerpt, and whether it was a linked citation, a mention without a link, or a paraphrase. Use when the user asks 'show me where I'm cited', 'what are ChatGPT/Claude/Perplexity actually saying about my brand?', or 'give me proof of AI citations'.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoNumber of previous days from which to return citations.
engineNoOptional engine filter for the citation events.
brand_idYesStable identifier of the tracked brand to inspect.

Output Schema

ParametersJSON Schema
NameRequiredDescription
daysYes
engineYes
brand_idYes
citationsYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, so safety is covered. The description adds value by explaining the structure of each citation (prompt, response excerpt, and whether it is a linked citation, mention, or paraphrase), which goes beyond the schema. No contradictions 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with purpose, and includes usage examples without redundancy. Every sentence earns its place; no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With read-only annotations, a full output schema, and clear usage guidance, the description is sufficient for an agent to select and invoke the tool. It does not mention ordering or pagination, but those are not critical for this straightforward read operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and all parameters have descriptive comments. The description does not add parameter-specific syntax or semantics beyond what the schema provides, so it stays at the baseline of 3 for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') with a clear resource ('actual citation events') and details the content (prompt, response excerpt, citation type). It distinguishes itself from siblings like check_visibility and get_visibility_history by focusing on citation events rather than aggregate visibility, and it provides example user queries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use: 'Use when the user asks...' followed by three concrete example queries. This gives clear context for invocation, but it does not mention when NOT to use or mention alternatives, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_content_gapsA
Read-only
Inspect

Get actionable content recommendations based on AI visibility gaps. Returns prioritized topics and content formats that would close the gap between this brand and competitors winning the same prompts. Use when the user asks 'what should I write to improve AI visibility?', 'what content gaps do I have?', or 'how do I get cited more by AI?'.

ParametersJSON Schema
NameRequiredDescriptionDefault
brand_idYesStable identifier of the tracked brand to analyze.
max_recommendationsNoMaximum number of content recommendations to return.

Output Schema

ParametersJSON Schema
NameRequiredDescription
reasonNo
brand_idYes
prompt_sourceYes
recommendationsYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the agent knows this is a safe read operation. The description adds context about what the tool produces (prioritized topics and formats, gap analysis vs competitors winning same prompts) but doesn't disclose things like whether recommendations require a tracked/refreshed brand or how current the data is. With readOnly annotation covering the safety profile, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is fairly compact at three sentences and front-loads the core purpose. The example user phrases add practical value but could be tightened; still, it's efficient with no wasted sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has a full input schema (100% coverage), an output schema, and clear readOnly annotations. The description explains what the output represents (prioritized topics/content formats to close gaps) and when to use it, which is sufficient given the rich structured data already present. It doesn't need to explain return values since an output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters (brand_id, max_recommendations) are fully documented in the input schema. The description doesn't add parameter-specific details beyond what the schema provides, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns content recommendations based on AI visibility gaps, specifically prioritized topics and formats to close gaps versus competitors. It uses a specific verb (get) with a clear resource (content gaps) and distinguishes itself well from siblings like check_visibility or generate_prompts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit example queries that should trigger this tool ('what should I write to improve AI visibility?', 'what content gaps do I have?', 'how do I get cited more by AI?'). While it doesn't name alternative tools to use instead, the clear trigger phrases effectively guide appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_visibility_historyA
Read-only
Inspect

Get the time-series history of a brand's AI visibility score, broken down per engine. Use when the user asks 'how has my AI visibility changed over time?', 'is my visibility growing or shrinking?', or 'show me the trend for the last month'.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoNumber of previous calendar days to include.
brand_idYesStable identifier of the tracked brand to inspect.
granularityNoTime bucket for the returned visibility series.weekly

Output Schema

ParametersJSON Schema
NameRequiredDescription
daysYes
seriesYes
brand_idYes
granularityYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds useful scoping detail (per-engine breakdown, time-series nature) beyond the schema. However, it doesn't describe pagination or the time-series return structure, though the output schema exists to handle that, keeping the bar lower. A 3 is appropriate given annotations carry the safety burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core description is efficient—a single purpose sentence followed by usage examples. The example queries earn their place by providing concrete trigger patterns. Slightly padded with three near-synonymous example questions, but all serve the same differentiation purpose, so minor deduction only.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool complexity is moderate (3 params, 1 enum, output schema present). The description covers the purpose, per-engine breakdown, and temporal use cases. The output schema handles return-value documentation, so the description doesn't need to. Could add a note about data freshness or range limits, but days min/max are already in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters (days, brand_id, granularity) are documented in the schema. The description adds the temporal framing ('growing or shrinking', 'trend') but doesn't add syntax or format details beyond what the schema already provides. Baseline 3 is correct when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource+scope: 'get' the time-series history of a brand's AI visibility score, broken down per engine. It clearly distinguishes from siblings like check_visibility (single-point check) and compare_competitors, and explicitly states the per-engine breakdown which adds specificity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit example queries that map to this tool ('how has my AI visibility changed over time?', 'is my visibility growing or shrinking?', 'show me the trend for the last month'). This gives agents concrete trigger patterns and clearly implies when to use it versus the sibling check_visibility tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_brandsA
Read-only
Inspect

List every brand tracked in the local database, with domain, category, competitors, refresh frequency, and how many prompts are active. Use when the user asks 'which brands am I tracking?' or to look up the brand_id the other tools need.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
hintNo
brandsYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false. The description adds useful context beyond annotations by explaining it's a local-database lookup and that its primary purpose is supporting other tools by providing brand_id values. It discloses the return content comprehensively without repeating what the output schema already likely conveys.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste. The first sentence delivers the core purpose and field list; the second gives concrete usage triggers. Everything earns its place with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 0 parameters, an output schema present, and readOnly annotations in place, this description is complete. It names the result fields, ties into the tool ecosystem via brand_id lookup, and gives concrete usage triggers. Nothing is left unaddressed for a list-style tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and schema coverage is 100%, so there are no parameter semantics to document. Per rubric, a 0-param tool gets baseline 4. The description appropriately doesn't waste space on parameters that don't exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('List every brand tracked in the local database') and enumerates exactly what fields are returned (domain, category, competitors, refresh frequency, active prompt count). It explains how to use this to look up brand_id for other tools, which distinguishes it from the sibling tools that operate on specific brands.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage context: use when the user asks 'which brands am I tracking?' or to look up the brand_id other tools need. This gives clear when-to-use guidance and implies how it fits within the broader tool family, though it doesn't explicitly name alternative tools or state when NOT to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

refresh_brandAInspect

Manually trigger a fresh AI visibility scan for a tracked brand. Runs every engine that has its API key configured (ChatGPT, Claude, Perplexity, Gemini, Google AI Overviews) against the brand's current prompt set. Use when the user asks 'refresh my data', 'rerun the scan', or 'I want fresh data right now'. Returns immediately with run IDs; results populate in 30-60 seconds.

ParametersJSON Schema
NameRequiredDescriptionDefault
enginesNoOptional engine filter. If omitted, refresh every configured engine.
brand_idYesStable identifier of the tracked brand to refresh.

Output Schema

ParametersJSON Schema
NameRequiredDescription
messageYes
run_idsYes
brand_idYes
estimated_completion_secondsYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide readOnlyHint=false and openWorldHint=true but the description adds substantial behavioral detail: it returns immediately with run IDs rather than results, results arrive asynchronously in 30-60 seconds, and it only executes engines with configured API keys. This is meaningful context beyond what the annotations convey, explaining the async nature and dependency requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences that each earn their place: the first states the primary function and scope, the second provides usage triggers when to invoke, the third explains the async return behavior. No fluff, no repetition of schema content, and the most important information (what it does) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is relatively simple with only 2 parameters and full schema coverage. An output schema exists so return-value documentation is not needed. The description covers the action, the engines involved, when to use it, the immediate return behavior, and the async timing of results. For a trigger-style tool, this is complete and well-suited to its complexity level.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters well (brand_id as stable identifier, engines with its enum values and omission semantics). The description reinforces engine behavior by naming the concrete engines and noting the 'optional engine filter' default behavior of refreshing all configured engines. The description adds minimal value beyond the schema since coverage is complete, justifying the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states what the tool does: 'Manually trigger a fresh AI visibility scan for a tracked brand.' It names the specific action (refresh/scan), the resource (brand), and enumerates the engines covered (ChatGPT, Claude, Perplexity, Gemini, Google AI Overviews). It also distinguishes its context from sibling tools like get_visibility_history (which reads history) and check_visibility (which checks current state) by focusing on the on-demand refresh action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage triggers: 'Use when the user asks refresh my data, rerun the scan, or I want fresh data right now.' It explains behavioral constraints (only runs engines with API keys configured, runs against current prompt set) and clarifies what happens upon invocation (returns run IDs immediately, results in 30-60 seconds). This gives strong when-to-use guidance with clear context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

track_brandAInspect

Start tracking a brand's AI visibility. Creates the brand in the local database and generates buyer-intent prompts for it — via Claude Haiku when ANTHROPIC_API_KEY is configured, otherwise three generic starter prompts (upgrade later with generate_prompts). Use when the user says 'track my brand', 'add my site', 'start monitoring acme.com', or when another tool reported the brand doesn't exist. After tracking, call refresh_brand to run the first scan.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesDisplay name of the brand to track.
domainYesPrimary domain of the brand, such as acme.com.
aliasesNoExtra terms that always count as a brand mention (product names, abbreviations).
brand_idYesStable identifier to assign to the new tracked brand.
categoryNoOptional product or market category for prompt generation.
competitorsNoOptional competitor domains to include in visibility analysis.
prompt_countNoNumber of buyer-intent prompts to generate for the brand.
exclude_termsNoTerms suppressed from bare-word matching — for brand names that are everyday words ("Monday", "Notion"). The full domain still matches.

Output Schema

ParametersJSON Schema
NameRequiredDescription
domainNo
reasonNo
seededYes
brand_idYes
next_stepsYes
competitorsNo
prompt_sourceNo
prompts_insertedNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=false and openWorldHint=true, which cover mutation and side effects. The description adds significant behavioral detail beyond this: the dual-mode prompt generation (Claude Haiku when ANTHROPIC_API_KEY is set, otherwise three generic starter prompts), explaining the conditional behavior based on env configuration. This is genuinely valuable context an agent wouldn't infer from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-front-loaded with the core purpose in the first sentence, followed by operational details. It's dense with useful info (trigger phrases, env-dependent behavior, follow-up action) but each sentence earns its place. Slightly longer than minimal, but every clause adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with openWorldHint=true, the description covers the key behavioral facets: side effects (DB creation), conditional prompt generation, and the required refresh_brand follow-up. It doesn't detail return values, but an output schema exists which flags this context signal, so that's acceptable. The main gap is not clarifying how competitors/aliases/exclude_terms fully affect behavior, but the schema already documents their semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all 8 parameters are documented in the schema itself. The description doesn't add parameter-specific details beyond what's already there, but it does clarify the prompt_count behavior in context (generation of buyer-intent prompts). Baseline 3 is appropriate given full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb+resource ('Start tracking a brand's AI visibility') and clearly explains what the tool does: creates the brand in the local DB and generates buyer-intent prompts. It distinguishes itself from siblings by noting the upgrade path to generate_prompts and the follow-up refresh_brand call.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit trigger phrases ('track my brand', 'add my site', 'start monitoring acme.com') and a clear when-to-use scenario (when another tool reports the brand doesn't exist). Also names the alternative tool generate_prompts and the required follow-up refresh_brand, giving strong usage context.

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. Dates show when Glama detected each change.

  1. 9 tool updatesv0.3.2
    • First observedcheck_visibility
    • First observedcompare_competitors
    • First observedgenerate_prompts
    • First observedget_citations
    • First observedget_content_gaps
    • First observedget_visibility_history
    • First observedlist_brands
    • First observedrefresh_brand
    • First observedtrack_brand

TDQS

A4.2/5.0
Disambiguation5/5

Each tool targets a distinct operation: get content gaps, check visibility, get history, compare competitors, refresh, track, list, and generate prompts. The purposes are clearly separated and each has explicit usage triggers.

Naming Consistency4/5

Most tools follow a clear verb_noun pattern: get_content_gaps, check_visibility, get_visibility_history, compare_competitors, refresh_brand, track_brand, list_brands, generate_prompts. The pattern is consistent, though 'check_visibility' and 'get_visibility_history' could be seen as minor style variation.

Tool Count5/5

8 tools is well-scoped for an AI visibility monitoring server. Each tool serves a clear purpose in the lifecycle: tracking, monitoring, refreshing, comparing, and generating content recommendations.

Completeness4/5

The tool surface covers the full workflow: track a brand, list brands, check visibility, view history, compare competitors, refresh data, generate prompts, and get content gaps. A minor gap is the lack of an untrack/remove brand tool, but this is a workable omission.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    A production-ready MCP server for AI agents, providing deep web research and RAG capabilities via Cloudflare Workers.
    -
  • A
    license
    B
    quality
    B
    maintenance
    SEO + 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.
    38
    1
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AKzar1el/mcp-geo'

If you have feedback or need assistance with the MCP directory API, please join our Discord server