GEO MCP by DigestSEO
This server is an AI visibility (GEO/AEO) tracker for measuring and improving how often your brand is cited by AI assistants like ChatGPT, Claude, Perplexity, Gemini, and Google AI Overviews.
Track brands — add a brand/domain, set competitors, aliases, exclude terms, and generate buyer-intent prompts (
track_brand)List tracked brands — view all brands with domains, competitors, and active prompt counts (
list_brands)Regenerate prompts — create a better prompt set for a brand via Claude Haiku (
generate_prompts)Check visibility — get the latest per-engine AI visibility snapshot, overall score, and winning/losing prompts (
check_visibility)View history — see daily or weekly visibility trends over time (
get_visibility_history)Compare competitors — share-of-voice percentages, prompts you win, and prompts competitors win (
compare_competitors)Get citations — see actual AI citation events with response excerpts and citation types (
get_citations)Find content gaps — get prioritized content recommendations to improve AI visibility (
get_content_gaps)Refresh data — manually trigger a fresh scan across all configured engines (
refresh_brand)
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, 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-geoCursor:
Kiro (hosted endpoint):
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:

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-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 — 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-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
Tool | 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 |
|
| List tracked brands with domains, competitors, and active prompt counts. | — |
| 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. ~€0.0004 per prompt with
gpt-4o-mini. Batch path roughly halves that. platform.openai.comAnthropic — 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 deployThe production MCP endpoint is the product-based custom domain:
https://geo-mcp.digestseo.com/mcpUse 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/mcpComplete 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/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. Free tier is rate-limited for brands with more than ~5 prompts (see Troubleshooting); opt-in add-on. |
| opt-in | unset | Enables the Perplexity Sonar engine. Paid only. |
| opt-in | unset | Enables the Google AI Overviews engine (via SerpAPI). |
| 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. |
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 --> DBEach 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,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 every prompt — the Gemini free tier caps
gemini-2.5-flash-liteat single-digit requests per minute and a low daily total. For brands with more than ~5 prompts you'll seestatus='failed'rows with 429 error messages, which excludes Gemini from scoring. Workarounds: upgrade to paid Gemini, switch theMODELconstant insrc/core/gemini.tsto a different model with a higher quota, or invoke/admin/run-enginefor one engine at a time so the per-minute window has time to refill between batches.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
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-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
9 toolscheck_visibilityARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| engines | No | Optional engine filter. If omitted, return results for every engine with stored data. | |
| brand_id | Yes | Stable identifier of the tracked brand 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 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.
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.
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.
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.
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.
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_competitorsARead-onlyInspect
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?'.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Number of previous days to include in the comparison. | |
| brand_id | Yes | Stable identifier of the tracked brand to compare. | |
| competitor_domains | No | Optional competitor domains to compare; otherwise use the brand's configured competitors. |
Output Schema
| Name | Required | Description |
|---|---|---|
| days | Yes | |
| brand_id | Yes | |
| competitors | 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, 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of buyer-intent prompts to generate. | |
| brand_id | Yes | Stable identifier of the tracked brand 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?
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.
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.
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.
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.
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.
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_citationsARead-onlyInspect
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'.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Number of previous days from which to return citations. | |
| engine | No | Optional engine filter for the citation events. | |
| brand_id | Yes | Stable identifier of the tracked brand to inspect. |
Output Schema
| Name | Required | Description |
|---|---|---|
| days | Yes | |
| engine | Yes | |
| brand_id | Yes | |
| citations | Yes |
TDQS
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.
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.
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.
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.
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.
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_gapsARead-onlyInspect
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?'.
| Name | Required | Description | Default |
|---|---|---|---|
| brand_id | Yes | Stable identifier of the tracked brand to analyze. | |
| max_recommendations | No | Maximum number of content 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?
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.
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.
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.
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.
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.
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_historyARead-onlyInspect
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'.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Number of previous calendar days to include. | |
| brand_id | Yes | Stable identifier of the tracked brand to inspect. | |
| granularity | No | Time bucket for the returned visibility 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, 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.
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.
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.
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.
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.
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_brandsARead-onlyInspect
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.
| 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 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| engines | No | Optional engine filter. If omitted, refresh every configured engine. | |
| brand_id | Yes | Stable identifier of the tracked brand 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 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Display name of the brand to track. | |
| domain | Yes | Primary domain of the brand, such as acme.com. | |
| aliases | No | Extra terms that always count as a brand mention (product names, abbreviations). | |
| brand_id | Yes | Stable identifier to assign to the new tracked brand. | |
| category | No | Optional product or market category for prompt generation. | |
| competitors | No | Optional competitor domains to include in visibility analysis. | |
| prompt_count | No | Number of buyer-intent prompts to generate for the brand. | |
| exclude_terms | No | Terms suppressed from bare-word matching — for brand names that are everyday words ("Monday", "Notion"). The full domain still matches. |
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 |
TDQS
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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
Related MCP Connectors
Cloudflare Workers MCP server: ai-rate-limit-tracker
Cloudflare Workers MCP server: ai-provider-status
AI-visibility monitoring for your brand across ChatGPT, Claude, Perplexity & Gemini.
- RampifyOAuthdev.rampify
SEO MCP server: crawl your site, find AI-visibility gaps, and ship the fix from your coding agent.
Related MCP Servers
- -licenseNot 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.462ISC

seocrawl-mcpofficial
AlicenseBqualityBmaintenanceSEO + 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.381MIT- 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.28237MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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