Skip to main content

What is MCP?

The Model Context Protocol (MCP) is an open standard that lets AI assistants connect to external tools and data sources. Searchable’s MCP server lets you ask AI assistants questions about your AI visibility, site audits, and content — without leaving the assistant. Compatible clients include:
  • Claude.ai (web and mobile) — add as a connector
  • ChatGPT — via developer-mode connectors
  • Grok — via custom MCP connectors
  • Gemini Spark — via custom Connected Apps
  • Microsoft 365 Copilot agents and Microsoft Copilot Studio
  • Claude Desktop and Claude Code
  • Cursor
  • Windsurf, Perplexity Enterprise, Mistral, and other MCP-compatible clients
The assistant controls whether custom MCP servers are available for your account, plan, and region. Gemini custom apps currently require Gemini Spark eligibility, a US personal Google Account, and English. For Microsoft, this compatibility applies to Microsoft 365 Copilot agents and Copilot Studio — not the consumer Microsoft Copilot chat product, which does not currently document a bring-your-own MCP server flow.
Ask questions like “What’s my brand’s visibility score on ChatGPT?” or “What critical AEO issues does my site have?” and the assistant will query Searchable for live data.
Plan requirement: MCP integration requires a paid Searchable plan. Both connection methods — signing in with OAuth and API keys — are unavailable on the Free plan.

How authentication works

The Searchable MCP server uses OAuth 2.1 with PKCE. It supports the current MCP client-metadata discovery flow, plus Dynamic Client Registration for clients that still require it. Public clients use PKCE; compatible enterprise clients can use a dynamically issued client secret. This means a new standards-compatible assistant can connect without Searchable adding a provider-specific OAuth integration first. You do not paste an API key into your MCP client’s config — you sign in and approve access, just like connecting any other app:
  1. You add the server URL to your client (https://app.searchable.com/api/mcp-server/mcp).
  2. On first use, the client opens Searchable in your browser and asks you to log in (or reuses your existing session).
  3. A consent screen shows which application is connecting and lets you choose:
    • Which projects it can access — pick specific ones, or leave all selected (all also covers projects you create later).
    • Read-only (default) or Read & write access.
  4. You click Authorize. Your client receives an OAuth access token scoped to exactly what you approved and uses it for subsequent requests.
The token can never exceed what you granted on the consent screen — a read-only, single-project grant stays read-only and single-project.
Only connect the Searchable MCP from trusted clients. Grant the narrowest access you need — read-only, and only the projects the assistant should see.

Setup

Server URL: https://app.searchable.com/api/mcp-server/mcp — the same address for every client below.

Step 1: Add the server to your client

  1. Open Claude.ai → Settings → Connectors.
  2. Click Add custom connector.
  3. Enter URL: https://app.searchable.com/api/mcp-server/mcp
  4. Claude opens the Searchable sign-in and consent page — continue with Step 2.
For Grok, Gemini Spark, Microsoft 365 Copilot agents, Copilot Studio, Perplexity Enterprise, Mistral, or another hosted assistant, create a custom MCP server or connector in that product and use https://app.searchable.com/api/mcp-server/mcp. Searchable publishes OAuth discovery metadata, so choose OAuth or automatic authentication when the host asks. The exact menu name and availability are controlled by the host product.

Step 2: Log in and authorize

The first time your client connects, Searchable opens in your browser:
  1. Log in to Searchable (or continue with your existing session).
  2. On the consent screen, choose which projects the client may access and whether it gets Read-only (default) or Read & write access.
  3. Click Authorize. Your browser returns to the client, now connected — no API key to copy or paste.
Your login is the identity for this flow. To connect a script or a client that only accepts a static bearer token, use the legacy API-key path below instead.

Step 3: Verify the connection

Once connected, ask:
You should see a list of your projects with their names and domains.

Connect with an API key (legacy)

The OAuth login flow above is the recommended path for interactive MCP clients. For scripts, headless clients, or any client that only accepts a static bearer token, a Searchable API key works as a bearer token directly — the same sea_ key the REST API accepts.
1

Create an API key

In Settings → Workspace → Integrations, click Create API Key, name it, and copy the key (starts with sea_). Store it securely — you won’t see it again. A key can be scoped to a single project and to read or read-and-write, mirroring the consent options above.
2

Send it as a bearer token

Configure your client to send Authorization: Bearer sea_... on every request to https://app.searchable.com/api/mcp-server/mcp. No login or consent screen is involved on this path.

Available tools

The Searchable MCP exposes 30 primary tools — 27 read-only and 3 write (32 with the Associated Sources feature enabled), plus 4 deprecated names kept callable through their sunset window (see Deprecated tool names). Every read tool is annotated readOnlyHint: true. Every tool that operates on a project takes a required projectId (get IDs from list_projects), and most read tools also accept an optional response_format"concise" (default, summary + capped rows) or "detailed" (fuller rows, same shape). Five tools exist purely to make assistants reliable, and are worth calling early in a session:
  • get_current_date — the server’s UTC date plus pre-computed window starts (7/30/90/365 days). Call it before interpreting relative time like “last month” so date math is never guessed.
  • whoami — who this connection is authenticated as, its read/write scopes, and the project roster it can see. Call it when unsure what the connection can access.
  • search_docs / read_doc — full-text search and retrieval over this documentation, so questions like “how is the visibility score calculated?” are answered in-chat, from the source.
  • get_page_metrics — the per-URL rollup: one page’s citations, AI-referral sessions, and AI-crawler hits as daily buckets, in one call.
The server also publishes two resourcessearchable://glossary (compact index) and searchable://glossary/full (complete definitions) — metric and concept definitions with the tools that read each one, for hosts that attach resources as reference context. get_visibility, get_share_of_voice, and get_sentiment additionally accept compare: "previous_period" | "previous_year" — the response gains a comparison block with the previous window’s metrics and current-minus-previous deltas, so period-over-period questions are one tool call.
Absolute date ranges. The core analytics reads accept from and to (inclusive, UTC) as an alternative to the relative daysfrom: "2026-03-01", to: "2026-03-31" answers “how did March go” without arithmetic against today. Both bounds are required together, and they are mutually exclusive with days: sending both is an invalid_argument error rather than a silent precedence rule. Bare YYYY-MM-DD and full ISO timestamps are both accepted (the UTC day is what counts). An over-long days is clamped to the tool’s maximum, but an over-long explicit range is rejected — narrowing a range you spelled out would answer a different question than the one you asked. Supported on get_visibility (every group_by), get_share_of_voice, get_sentiment, get_topic_analysis, and get_ai_traffic (every report), plus the matching REST endpoints. Tools not in that list — get_competitors, get_shopping_visibility, get_ads, get_page_metrics, get_query_fanout, get_prompt_answers, and the source reads — still take days only. (get_gsc_performance has always had its own startDate / endDate.)
Filter echo. Every filterable read echoes an appliedFilters object: the platform / brand / topic / location filters that call actually narrowed by, or {} when it was unfiltered. That covers get_visibility, get_share_of_voice, get_competitors, get_topic_analysis, list_prompts, get_sentiment (every view), get_source_trends, and get_shopping_visibility (summary view). All of them except get_topic_analysis also return availableFilters (the project’s topics and countries) so a client can offer the next filter without a second round-trip — on get_visibility that rides along on the summary and platform views. Use appliedFilters to state what a number covers rather than presenting a filtered figure as the whole picture.
Write actions are MCP tools too: generate_report, trigger_audit, and refresh_sitemap are available to keys/grants with the write scope, and each requires an explicit confirm: true argument — without it the tool returns a dry-run preview and changes nothing. The REST equivalents (e.g. POST /api/mcp/projects/{projectId}/reports) remain available; see Advanced API Usage.

Diagnostics

investigate

Answers a whole diagnostic question in one call, by running its multi-read chain server-side and in parallel. Prefer it over chaining the granular tools yourself for “why did X change” and “where do we stand” questions.question="visibility_drop" (default) returns the score trend with the largest single-day fall, per-platform movement against the previous window, the share-of-voice shift with which competitors gained, and the weakest topics. "competitive_position" returns your standing with ranks and deltas plus the topics where a rival currently leads. "citation_gap" returns your citation trend, the domains AI answers actually cite in your space, and per-engine citation share.Takes the usual narrowing arguments — days or from/to, platform, topicId, unbranded / branded, country / locationId.It reports measurements, never a cause. It will tell you ChatGPT fell 38 points while Gemini held; it will not tell you why, because the reason is usually outside the data — a rebrand, a campaign ending, a competitor launch. Every response carries an interpretation list naming what the numbers cannot settle. A signal whose upstream failed appears in unavailable with a reason rather than as a zero, so missing data is never mistaken for a finding.Each question has a companion recipe explaining how to read the result and when it misleads: visibility drop, competitive position, citation gap. Load one in-chat with read_doc("recipes/visibility-drop").

Projects

list_projects

List all projects this connection can access — names, domains, and IDs. Call this FIRST: every other tool needs a projectId.Parameters: response_format (optional)

Visibility & share of voice

get_visibility

AI visibility for a project. group_by selects the view: summary (overall visibility score), platform (per ChatGPT/Claude/Gemini/Perplexity breakdown), prompt (per-prompt breakdown, paginated), location (per country/city), or date (the per-report time series — trend, uplift, before/after analysis; default 90-day window). The unbranded/branded, topicId, country and locationId filters work on every view except date, which accepts only unbranded/branded; the platform filter is restricted to group_by=prompt|location. An interactive Visibility Snapshot card also renders automatically beside the answer on Apps-capable clients — see below.
group_by="topic" was removed. Per-topic visibility now lives on its own tool, get_topic_analysis (next card), which returns the competitive rank, strengths, and gaps the old view never had. Passing group_by="topic" is now a validation error — switch the call to get_topic_analysis.include attaches optional extra blocks (comma-separated): industry_ranking adds the competitive leaderboard — the top 25 entities by visibility, with your own rank, share of voice, and change — to group_by=summary|platform (hasMore flags a longer field; brandRankStatus distinguishes ranking below the cutoff from being unranked, and totalEntities is null when truncated); annotations adds the dated markers (campaign launches, migrations) overlapping the window to group_by=date, so a spike comes back with its explanation attached. An include a view cannot attach is an invalid_argument error on every view — including group_by=prompt and group_by=location, which attach no blocks at all — never a response that quietly lacks the block.
Parameters: projectId (required), group_by ("summary" | "platform" | "prompt" | "location" | "date", default summary), days (default 30, or 90 for group_by=date; max 365, or 180 for group_by=prompt), unbranded, branded, platform, topicId, limit (group_by=prompt, default 100, max 500), offset (group_by=prompt), country, locationId (all optional except projectId)

get_topic_analysis

Per-topic AI visibility — the brand’s mention rate in each topic, its competitive rank within that topic, how many tracked prompts sit under it, and the AI-identified attribute strengths and gaps behind the number. This is the only per-topic view: use it for any question about topics, subject areas, or categories, including where a brand is winning or losing and what to fix. Replaces the removed get_visibility (group_by:"topic"). An interactive Topic Analysis card also renders automatically beside the answer on Apps-capable clients — see below.view="prompts" drills into ONE topic (topicId required): every prompt assigned to it with your average rank, its visibility, and which competitors outrank you — the “which specific questions are we losing” view behind a weak topic. A prompt you never appeared for reports rank: null, never 0.view="heatmap" returns average brand position per topic x AI platform — where you’re strong on one engine and absent on another. There is deliberately no platform filter on this view: the platform axis is the answer.Parameters: projectId (required), view (topics default, prompts, heatmapplatform is rejected on heatmap, whose axis IS platform), topicId (required for view=prompts; rejected on the default view, which lists every topic), days (default 30, max 365), from/to, limit, platform, unbranded, branded (all optional except projectId)

get_visibility_history

Deprecated — call get_visibility with group_by: "date" instead (same data, same parameters). This name keeps answering with an identical payload until its removal date; see Deprecated tool names.Parameters: projectId (required), days (default 90, max 365), unbranded, branded (all optional except projectId)

get_share_of_voice

Brand vs competitor share of voice — mention-share percentage and rank among all tracked entities, plus each entity’s day-over-day (today vs yesterday) point change. mentions/citations aren’t part of this view (mirrors the in-app Share of Voice sheet) — use get_competitors for those. An interactive Share of Voice card also renders automatically beside the answer on Apps-capable clients — see below.group_by="date" returns the daily share series instead — your share and your top competitors’, one point per day. That is the “is our share growing?” view; include="annotations" adds the dated markers explaining any jump. compare is not supported there (the series already shows the movement), and the interactive card hides itself on it.Parameters: projectId (required), group_by (summary default, or date), days (default 30, max 365), from/to, include, platform, topicId, unbranded, branded, country, locationId, compare (all optional except projectId)

Competitors

get_competitors

The project’s real/tracked competitors, ordered by rank (highest visibility first) — visibility, share of voice, sentiment score, average mention position, and all-time mention count, plus a brand block carrying the same metrics for the project itself so the two sit on one ruler. Pass competitorId for a head-to-head against one competitor instead: headToHead.brand vs headToHead.competitor, each with visibility %, share of voice %, sentiment (0–100) and average position (a rank — lower is better), plus the phrases each is known for; for the competitor it also returns its rank, per-day history, and up to 10 recent prompts it was mentioned in. competitorId accepts either the competitor’s ID or its name exactly as the list shows it (competitorId: "Nike"), so you can drill in straight from the list — response_format: "detailed" adds an id column if you want the exact key. A null metric means unmeasured in that window, not zero. visibility/sov/sentimentScore/avgPosition honor the filters; the list view’s mentions is all-time and ignores them. On the head-to-head, citations (inline citations on responses mentioning the competitor) and history[].domainSources (source URLs — pages used for generation, not inline citations — on the competitor’s own domain) are different metrics. An interactive Competitor Ranking card also renders automatically beside the answer on Apps-capable clients, in whichever shape matches the call — see below.Parameters: projectId (required), competitorId (optional — ID or name; switches to the head-to-head view), days (default 30, max 365), platform, topicId, unbranded, branded, country, locationId, limit (list view, default 20, max 100), offset (list view) (all optional except projectId)

Sources & citations

search_sources

Top cited source domains from AI answers — rank, citation counts, usage %, models, and top content types. Paginated and sortable. Use to find which external sites AI models cite most; drill in with get_source_detail.Parameters: projectId (required), sort (e.g. "-citations"), limit (default 20, max 100), offset, days, platform, topicId, sourceType, unbranded, branded, country, locationId, response_format (all optional except projectId)

get_source_detail

Drill into cited sources. level="domain" (+ domain): domain summary, or include="urls" (cited URLs on it) / include="responses" (AI responses citing it). level="url": with url → single-page citation analytics, or include="content" → cached page markdown + entity mentions (never triggers a live scrape); without url → all cited URLs across the project (optionally filtered by contentType).Parameters: projectId (required), level ("domain" | "url", default domain), include ("urls" | "responses" | "content"), domain (required for level=domain), url (level=url), contentType, limit, offset, cursor, days, platform, topicId, sourceType, unbranded, branded, country, locationId (all optional except projectId)

get_source_trends

How the project’s top source domains trend over time — a per-domain time-series of the external sites most used as sources in AI answers, over the window (default 30 days). An interactive Sources card renders beside the answer on Apps-capable clients: the trend line inline, expanding to the top source URLs.Parameters: projectId (required), days (window; default 30 — pass 7/90/365 for a different one), platform, topicId, sourceType, unbranded, branded, country, locationId (all optional except projectId)

Sentiment

get_sentiment

Brand sentiment across AI platforms. view selects: summary (default) — overall score + positive/neutral/negative split + per-platform breakdown, plus analysis (the weekly brand-perception write-up for the platform that mentions you most, or the one you filter to with platform) and analyses (every platform’s write-up); history — the daily sentiment trend (default 90-day window); competitors — head-to-head vs competitors, the brand flagged by isBrand. topicId is not accepted on competitors, and compare only on summary. The interactive Sentiment Profile card renders on summary answers only.Parameters: projectId (required), view ("summary" | "history" | "competitors", default summary), days (default 30, or 90 for view=history; max 365), platform, topicId, limit (view=competitors, default 10, max 50), unbranded, branded, country, locationId, response_format (all optional except projectId)

get_sentiment_history

Deprecated — call get_sentiment with view: "history" instead (same data, same parameters). Keeps answering identically until its removal date; see Deprecated tool names.Parameters: projectId (required), days (default 90, max 365), platform, topicId, unbranded, branded, country, locationId, response_format (all optional except projectId)

get_sentiment_competitors

Deprecated — call get_sentiment with view: "competitors" instead (same data, same parameters). Keeps answering identically until its removal date; see Deprecated tool names.Parameters: projectId (required), days (default 30, max 365), platform, limit (default 10, max 50), unbranded, branded, country, locationId, response_format (all optional except projectId)

Query fanout

get_query_fanout

The sub-queries AI models generate when answering tracked prompts. Without prompt_id: the project aggregate (most frequent fanout queries, per-prompt counts, per-model stats; paginated). With prompt_id: every deduped sub-query for that one prompt, with per-query frequency and query type. Paid feature — returns plan_upgrade_required if not entitled.Parameters: projectId (required), prompt_id (optional — note the snake_case; omit for the project aggregate), days (default 30, max 180), platform, topicId, unbranded, branded, limit (aggregate, default 50, max 50), offset (aggregate), topQueriesLimit (aggregate, default 50, max 200) (all optional except projectId)

Brand profile & authority

get_brand_profile

The project’s knowledge-base brand profile (name, headline, category, positioning, description, topics, business type, connected entities, competitor geography/context) plus the latest batch of AI-observed brand facts — statements AI platforms actually make about the brand, each with its platform and verification status. Pass include: "domain_authority" to also get the Moz domain-authority block (latest DA/PA/spam/linking-domains snapshot + roughly-monthly 365-day history) in the same call. Call this first for brand context in any analysis. profile is null until onboarding creates one; facts come from the weekly sentiment job.Parameters: projectId (required), platform, verificationStatus ("unverified" | "pass" | "fail"), include ("domain_authority"), response_format (all optional except projectId)

get_domain_authority

Deprecated — call get_brand_profile with include: "domain_authority" instead (same data; the REST endpoint keeps custom days windows). Keeps answering identically until its removal date; see Deprecated tool names.Parameters: projectId (required), days (default 365, max 1095) (all optional except projectId)

Prompts

list_prompts

The project’s prompt catalog as configured — tracked prompts (type, intent, branded flag, topics, tracked locations, keyword volume/difficulty), paused (untracked) prompts, or the AI-suggested review queue (status="suggested" — proposals from research runs and the agent that nobody has accepted or rejected yet, each with the reason it was proposed). Configuration data, not performance — use get_visibility group_by=prompt for per-prompt visibility scores. The summary always reports all three counts, so pending suggestions surface from any call. An interactive Prompts card also renders automatically beside the answer on Apps-capable clients.Parameters: projectId (required), status ("tracked" | "untracked" | "suggested" | "all", default tracked), topicId, limit (default 50, max 200), offset, days (metrics window, default 30, max 365), sortBy (prompt | volume | difficulty | branded | intent | recency, default recency — performance columns like visibility/position/sentiment are computed per page and are not server-sortable), sortDir ("asc" | "desc", default desc), unbranded, branded, response_format (all optional except projectId)

get_prompt_answers

Raw, per-response AI-answer data for one prompt (Profound-parity) — platform, response date, response text, whether the brand was mentioned, competitors mentioned, and the source URLs the engine consulted (sources[] — pages used for generation, not inline citations), one entry per AI response. Not an aggregate — use get_visibility or get_share_of_voice for scores/rankings. Response text is hard-truncated at 2000 characters server-side; the markdown table shows a short snippet (120 characters, 500 in detailed format).Parameters: projectId (required), promptId (required — note the camelCase, unlike get_query_fanout’s prompt_id), days (default 30, max 365), platform, limit (default 10, max 50) (all optional except projectId and promptId)

Site health & audits

get_site_health

Technical + AEO site health. view="pages" (default) = the monitored-page inventory, one server-paginated page at a time (audited pages first) — every page (audited or not) with its latest technical/AEO scores, open-issue count, and last-audited date, plus pagination.total; page with limit/offset, filter server-side with search (URL/slug/title), reorder with sortBy, and omit the header aggregates with includeSummary=false; view="audits" = per-page technical/AEO scores for audited pages + averages; view="issues" = issues grouped by severity (filter status); view="issue_details" = issues grouped by type with fix guidance (filter issueType). An interactive Site Audit card renders beside the answer on Apps-capable clients: pages/audits show the inventory with a search box + Prev/Next paging (both server-side), a per-page Audit button (calls trigger_audit for that page), and a Sync website button (calls refresh_sitemap); issues/issue_details show the findings ranked by severity, each expanding to its fix guidance. Clicking a page row on the inventory drills into that page’s own issues.Parameters: projectId (required), view ("pages" | "audits" | "issues" | "issue_details", default pages), status (view=issues: "open" | "resolved" | "all", default open), pageId (view=issues: scope to one monitored page — the card’s page → issues drill-down), issueType (view=issue_details: "technical" | "content"), includeIssues (view=audits, boolean), search (view=pages: server-side filter by URL / slug / title), sortBy (view=pages: "audited" | "technical" | "aeo" | "issues", default audited-first), includeSummary (view=pages, boolean, default true), limit (view=pages default 12, max 100; view=issues default 1000, max 5000), offset (view=pages / view=issues) (all optional except projectId)

Content & articles

list_articles

List articles / content pieces for a project (merges content-v2 + legacy). Shows title, status, type, word count, and source.Parameters: projectId (required), status ("draft" | "published" | "editing" | "all", default all), limit (default 50, max 100) (all optional except projectId)

get_article

Full article content — HTML/markdown body, outline, FAQs, images, schema markup, internal/external links, and all metadata.Parameters: articleId (required)

Opportunities

get_opportunities

Actionable opportunities Searchable surfaced for the project — prioritized fix / write / audit suggestions derived from visibility, sentiment, sources, traffic, prompts, site health, and articles. Returned in the product’s priority order (status, then impact, then newest). Defaults to active opportunities; blocked for active pitch projects.Parameters: projectId (required), status ("active" | "completed" | "dismissed" | "auto_resolved", default active only), includeResolved, source (e.g. "visibility", "sentiment", "sources", "traffic", "prompts", "site_health", "articles"), impact ("critical" | "high" | "medium" | "low"), limit (default 100, max 500), offset (all optional except projectId)

GA4 / Traffic

This tool requires a linked GA4 property. When the project has none, the backing endpoint returns a 409 error with { code: "ga4_not_connected", message, howToFix } — the howToFix field points at Settings → Integrations in Searchable, where you can connect GA4 and then retry.

get_ga4_traffic

Google Analytics 4 website traffic. report="ai_referrals" (default; per-LLM-host AI Source Visitors from ChatGPT/Copilot/Gemini/Perplexity/DeepSeek and more — use for AI-referral attribution), "trend" (daily users/sessions/pageviews), "top_pages" (top landing pages by sessions), or "sources" (channel-group + source breakdown).Parameters: projectId (required), report ("ai_referrals" | "trend" | "top_pages" | "sources", default ai_referrals), weeks (default 12, max 52), limit (top_pages/sources, default 20, max 100) (all optional except projectId)

Search Console (GSC)

This tool requires a linked Google Search Console site. When the project has none, the backing endpoint returns a 409 error with { code: "gsc_not_connected", message, howToFix } — the howToFix field points at Settings → Integrations in Searchable, where you can connect GSC and then retry.

get_gsc_performance

Live Google Search Console organic performance. report="overview" (default): clicks/impressions/CTR/average position plus a prior-period comparison. "top_queries" / "top_pages" / "countries" / "devices": ranked rows for that dimension. "trend": daily timeseries with window totals. "opportunities": quick-win queries (ranking position 4-15, ≥100 impressions, under 5% CTR). "position_buckets": query-count distribution across top 3 / page 1 / page 2 / beyond 20. Pass period ("7d"|"28d"|"30d"|"90d"|"16m", default "30d") or an explicit startDate+endDate (YYYY-MM-DD) window — GSC data lags ~3 days.Parameters: projectId (required), report (default overview), period, startDate, endDate, limit (top_queries/top_pages/countries/opportunities only; defaults 25/25/100/20) (all optional except projectId)

AI Traffic

First-party AI-traffic measurement from the tracker/CDN pipeline — Searchable’s flagship differentiator, distinct from GA4 above (which reads Google’s own analytics). This tool requires a crawler-log, CDN, or Searchable-tracker source connected. When none is connected, the backing endpoint returns a 409 error with { code: "traffic_not_connected", message, howToFix } — the howToFix field points at AI Traffic → Setup in Searchable, where you can connect a source and then retry.

get_ai_traffic

First-party AI-crawler and AI-referral traffic. report="overview" (default): crawler + AI-referral totals by platform, plus the top crawled pages. "crawlers": per-page AI-crawler activity, capped by limit (no deep pagination at the tool layer — use the REST endpoint’s offset for that). "referrals": daily AI-referral session timeseries by platform. "top_cited_pages": top pages driving AI-referral traffic for one platform — platform is required for this report. platform is validated strictly, and an unrecognized value returns an error rather than a silent empty result: crawlers and referrals accept all eight platform IDs (openai, anthropic, google, perplexity, microsoft, deepseek, xai, meta), while top_cited_pages accepts only the first five. overview ignores platform entirely — it always returns every platform, so filter with crawlers or referrals instead. Long-tail vendors that can appear in output rows (e.g. amazon, you.com) are deliberately not filterable.overview, crawlers, and correlation take groupBy="platform" | "botCategory" | "botName". This extends the same tool rather than adding traffic tools. Omitting it preserves the legacy response; botCategory adds byCategory, botName adds byBot (name, ID, vendor, and category), and platform adds correlation’s per-page byPlatform crawl split. Overview and crawlers keep their existing byPlatform arrays with every grouping.The public bot categories are ai_training, ai_search, ai_assistant, ai_agent, and search_engine. ai_assistant is the distinct user-triggered class for ChatGPT-User, Claude-User, and Perplexity-User. A per-page ai_training → ai_search → ai_assistant view is therefore possible, but ai_search means retrieval/search crawling — actual answer citation remains a separate visibility metric.Five further reports cover the rest of the AI Traffic surface:
  • sitemap_coverage — per bot (named, with vendor and category): how often it fetched your sitemap, how many listed pages it discovered, and the median lag from publish to first crawl. It answers how fast and how completely each crawler is picking your sitemap up; it does not enumerate individual uncrawled URLs.
  • human — real human sessions that arrived FROM an AI assistant, split by platform. The conversion half of the funnel the crawler reports open. Check summarySource: site-wide totals come from the first-party tracker while the AI figures fall back to GA4 when no tracker is installed — in that split state every summary field and percentOfTotal are null (not 0), and a failed GA4 read surfaces as aiReferral.sourceError rather than as zeroes.
  • correlation — per page, crawls and AI-referred sessions over the same window, joined by path. Its optional grouping classifies the crawl side only. This is co-occurrence, not attribution: nothing establishes that a session followed a crawl or came from a named bot. Ranked by sessions, but the ranked population is the upstream union of the top-500 crawled and top-500 human-traffic pages — pagesConsidered is a floor, and populationTruncated tells you when pages are certainly missing.
  • attribution — traffic by UTM tuple, referrer domain, and bot category.
  • logs — the raw request feed, filterable by path, statusCode, botsOnly, and host, cursor-paginated: pass a page’s nextCursor back as both cursorTimestamp and cursorEventId (half a cursor is rejected rather than silently re-serving page one). Row-capped (25 default, 100 max) because it is the one row-level report. ip_address and user_agent are never returned — the IP is personal data with no analytical value once country is present, and the user-agent is superseded by the resolved bot identity.
host narrows any report to specific hostnames (comma-separated) — useful on multi-domain projects where “blog versus docs” is the question.Parameters: projectId (required), report (default overview), days (default 30, max 365), from/to, host, platform (required for top_cited_pages), groupBy (overview/crawlers/correlation only), limit, plus path / statusCode / botsOnly for report=logs (all optional except projectId)

Shopping visibility

Requires a plan with Shopping Analytics (Scale or higher). get_shopping_visibility returns available: false (not an error) when the project simply has no shopping/product data yet — that’s a data-presence state, not a plan or connection problem, and needs no setup step. The plan gate only surfaces once there’s data to fetch.

get_shopping_visibility

AI shopping/product visibility (Peec-parity) — products surfaced in AI shopping/product-carousel responses. view="summary" (default): ranked product list (rank, mentions, dominant platform) plus an activation-rate summary. view="timeseries": daily activation-rate/product-count trend. Pass productId (the id from a summary row — the product’s title) for full detail on one product instead: occurrences, vendor/pricing rows, a real per-platform breakdown, and up to 50 recent responses that surfaced it — productId overrides view. The summary view accepts the brand / topic / location filters and echoes appliedFilters + availableFilters. An interactive Shopping Shelf card also renders automatically beside the answer on the summary view for Apps-capable clients — see below.Parameters: projectId (required), days (default 30, max 365), platform, productId (optional — switches to detail view), view ("summary" | "timeseries", default summary), limit (summary view, default 50, max 100), offset (summary view), topicId, unbranded, branded, country, locationId (all optional except projectId)

AI ads

Ad data appears once tracked prompts surface sponsored ad units. An empty result means either that nothing has been captured yet or that a filter didn’t resolve — topicId, locationId and promptId take IDs, not names. An unrecognized value is dropped from its filter; only when none of a filter’s values resolve does that filter match nothing rather than being ignored — a mixed list silently returns just the recognized subset. Retry without filters before reporting that a project has no ad data, and state that the retried figures are unfiltered. adCount/appearances count ads we scraped in AI answers, not ad-platform impressions, and commercial ad libraries don’t publish spend, so there are no cost or impression figures.

get_ads

Sponsored ads surfaced in AI answers. view="advertisers" (default): who is running ads, ranked by ad volume with share % and a competitor flag, plus your own brand’s ad share-of-voice and rank. view="creatives": the individual ad creatives (advertiser, headline, appearances, prompts) — narrow with advertiserKey, promptId, or search. view="prompts": which tracked prompts surface the most ads, with ad coverage %. view="timeseries": per-advertiser ad-frequency trend.Parameters: projectId (required), view ("advertisers" | "creatives" | "prompts" | "timeseries", default advertisers), days (default 30, max 365), filter ("all" | "competitors", view=advertisers), advertiserKey (view=creatives/timeseries), promptId + search (view=creatives), sortBy (promptText|adUnits|coveragePct|engines|totalResponses, default adUnits) + sortDir (view=prompts), limit (advertisers default 20/max 100, creatives 25/200, prompts 50/500), platform, topicId, locationId, unbranded, branded, response_format (all optional except projectId)

Write actions

All three require a grant/key with the write scope. None of them execute without confirm: true — omit it and the tool returns a dry-run preview (what would happen, current quota state) with no side effect.

generate_report

Generate + publish a shareable report and return its public URL. reportType=sentiment|visibility|combined (default sentiment). Note the Only suffix on the brand filters here — unbrandedOnly/brandedOnly — unlike every read tool’s unbranded/branded.Parameters: projectId (required), reportType, timeRange ("7d"|"30d"|"90d"|"365d", default 30d), platforms, topicIds, locationIds, unbrandedOnly, brandedOnly, title, status ("published"|"draft", default published), whiteLabel (requires a white-label-entitled plan), confirm (all optional except projectId)

trigger_audit

Start a technical + AEO site audit for the project’s pages (all tracked pages by default, or the given pageIds); returns the job id. Results land on get_site_health (view="audits"). Consumes the monthly audit quota and is blocked for pitch projects.Parameters: projectId (required), pageIds (optional — omit to audit every tracked page), confirm (optional)

refresh_sitemap

Re-sync the project’s configured sitemap — re-discovers it and reconciles monitored pages (add/update/remove) in the background; returns the job id. Read the result with get_site_health (view="pages"). Blocked for pitch projects.Parameters: projectId (required), confirm (optional)

Removed tool names

Earlier iterations of this MCP shipped 35 individual tools. When those were consolidated, 26 of the old names stayed callable as deprecated aliases. Those aliases were removed in August 2026 — calling one of the names below now returns an unknown-tool error. Use the replacement. Nine other pre-consolidation names kept their exact original name as a primary tool at the time. Six still do — list_projects, list_articles, get_article, get_opportunities, get_sentiment, and get_query_fanout; the other three (get_visibility_history, get_sentiment_history, get_sentiment_competitors) were folded into selector views in August 2026 and are now deprecated names — see the next section.
The four get_source_* breakdown rows above are the one case where the removed name did something no MCP tool now does: breakdown (and get_source_trend’s group) were arguments only those aliases accepted. get_source_trends returns the top-source-domain trend directly and has no breakdown argument. For the content-type, source-type, or article-type breakdown, use the REST endpoint.

Deprecated tool names

The August 2026 family-grid consolidation folded four reads into selector parameters on their family’s primary tool. Unlike the removed aliases above, these four names still work — same handler, byte-identical payload — so existing scripts and scheduled jobs keep running. They are scheduled for removal after 2026-10-15 (the same ~60-day window the removed aliases got); move to the replacement call before then. The REST endpoints behind these reads (GET /visibility/history, GET /sentiment/history, GET /sentiment/competitors, GET /domain-authority) are not deprecated — the 12-month REST deprecation policy governs those, and nothing REST-side is scheduled for removal.

Interactive cards

Nine tools render an interactive card beside their answer in MCP-Apps-capable hosts (Claude web/desktop, ChatGPT, Goose, VS Code — all implement the same standard):get_visibility hides its card on a platform-filtered call and on group_by=prompt|location, where the card’s numbers would misrepresent the answer. Hosts without MCP Apps support just see the normal text/JSON answer. Cards are dark/light aware and have an Expand button for a fullscreen view. Where a card has a period control you switch window inside the card rather than sending another message — the card queries the tool itself and remembers each window it has already loaded, so returning to one is instant.

Pagination

Tools that return lists are paginated so you can read complete datasets without silent truncation.

Per-prompt visibility

get_visibility with group_by: "prompt" is fully paginated (the deprecated get_visibility_by_prompt alias maps to the same call). Every response includes a pagination object that tells you whether more prompts exist and exactly how to fetch the next page:
Loop until you’ve read every prompt:
  1. Call get_visibility with group_by: "prompt" (defaults: limit 100, offset 0).
  2. While pagination.hasMore is true, call again with offset = pagination.nextOffset.
  3. Stop when pagination.hasMore is false.
limit accepts 1–500 prompts per page. The total number of prompts you can page through is unbounded — paging in fixed-size chunks scales to projects with thousands of prompts.

Other list tools

Other list-returning tools paginate too: get_opportunities, search_sources, get_source_detail (include: "responses"), and get_query_fanout (per-prompt list) use limit + offset, while get_source_detail (include: "urls", or level: "url" for the flat cross-project listing) is cursor-based (pass the cursor from the previous response until none is returned). get_prompt_answers also returns the standard limit/offset/hasMore/nextOffset pagination shape, but the tool layer only exposes limit (max 50) — use the REST endpoint’s offset for deep pagination.

Example prompts

Visibility analysis

Site audit

Content

Use cases

Automated issue fixing

Pair the MCP with a coding assistant to retrieve AEO/SEO issues and apply fixes in your codebase:
The assistant fetches issues from Searchable (missing meta descriptions, alt text, heading structure, etc.), locates the relevant files, and proposes or applies fixes.

For developers

  • Query AEO/SEO issues while debugging frontend code
  • Check if code changes would impact page audit scores
  • Review article content without leaving your IDE

For AEO/SEO teams

  • Pull visibility summaries during standups
  • Extract audit data for reports
  • Track issue resolution progress

For content teams

  • Review article status and metadata
  • Pull full article content for editing
  • Track content coverage across topics

Troubleshooting

  • Confirm the server URL is exactly https://app.searchable.com/api/mcp-server/mcp (browser-sent Origin headers are validated against an allowlist — hosted connectors normally call server-side without one, so they’re unaffected).
  • Check your API key starts with sea_ and is enabled for MCP in Searchable settings.
  • Restart your MCP client after config changes.
  • Confirm the key starts with sea_ and hasn’t been revoked in Settings → Integrations. - Confirm the key’s workspace is on a paid Searchable plan — MCP is unavailable on the Free plan.
  • Confirm you have projects in your Searchable account. - Check that the API key belongs to the correct workspace.
  • The project has no GA4 property linked, so the tool call returns a 409 error with code: "ga4_not_connected". - Connect Google Analytics 4 under Settings → Integrations in your Searchable dashboard (the error’s howToFix field carries the direct link), then retry the tool call.
  • The project has no Google Search Console site linked, so the tool call returns a 409 error with code: "gsc_not_connected". - Connect Google Search Console under Settings → Integrations in your Searchable dashboard (the error’s howToFix field carries the direct link), then retry the tool call.
  • The project has no crawler-log, CDN, or Searchable-tracker source connected, so the tool call returns a 409 error with code: "traffic_not_connected". - Connect a source under AI Traffic → Setup in your Searchable dashboard (the error’s howToFix field carries the direct link), then retry the tool call.
  • The workspace’s plan doesn’t include Shopping Analytics (Scale or higher), and the project has shopping data to fetch, so the tool call returns a 403-equivalent error with code: "plan_upgrade_required". - This is different from available: false — that’s a normal 200 response meaning the project just has no shopping data yet, not a plan restriction. If you’re seeing available: false instead of this error, no upgrade is needed. - Upgrade to a plan with Shopping Analytics in Settings → Billing, then retry.
Both are retryable, and neither means you’ve exhausted a quota. rate_limited means another heavy read for the same project is still running — the limit is per project, not per key, so wait a moment and retry, and avoid firing many project-wide tools in parallel for one project. query_timeout means the aggregation ran past the server-side limit — reduce the days window or add filters (platform, topicId, country), then retry.
  • The connected grant or API key only has read access. Write tools require the write scope. - Re-authorize with Read & write selected on the consent screen, or create/edit an API key with read-and-write access in Settings → Integrations.
  • Restart your MCP client.
  • Verify the server URL and JSON config syntax.
  • Check the client’s MCP logs for errors.

Security

Read-only by default, write tools scope-gated

Every tool except the 3 write tools is annotated readOnlyHint: true: they can only list and read data. The 3 write tools (generate_report, trigger_audit, refresh_sitemap) additionally require a grant or key with the write scope, and each still needs an explicit confirm: true on the individual call before it does anything — a read-only connection can’t invoke them at all (the call fails with missing_scope), and even a read-and-write connection gets a no-op dry-run preview until it passes confirm: true.

Token & key handling

  • The OAuth login flow issues your client an access token scoped to exactly the projects and read/write access you approved on the consent screen — no API key is created or stored for this path.
  • Every request is re-checked against the server-side authorization grant, so a revoked grant stops working immediately — the token in the client’s hands can’t outlive the consent it came from.
  • Tokens refresh silently while the connection is in use; active connections persist, and an idle connection expires about 60 days after its last use, after which you simply re-authorize.
  • On the legacy API-key path, the sea_ key is the bearer token — treat it as a secret, scope it narrowly, and revoke it in Settings → Integrations if it’s exposed.

Origin validation

The server validates browser Origin headers against an allowlist (claude.ai, claude.com, plus dev hosts) to prevent cross-site abuse. Requests without an Origin header are allowed through — that covers native clients (Claude Desktop, Cursor, curl) and hosted connectors like Claude.ai and ChatGPT, which call from their servers rather than a browser. This is defense-in-depth; bearer-token auth is the primary control.

Best practices

  • Rotate keys regularly — generate new keys periodically and revoke old ones.
  • Use per-use-case keys — separate keys for separate clients makes revocation targeted.
  • Revoke unused keys — remove keys you’re no longer using from Searchable settings.

API reference

Server details

Rate limits

Searchable does not enforce a per-key request-rate limit today, but two server-side controls can make a call fail retryably:
  • Per-project concurrency. Heavy aggregation reads take a per-project lock, so a second heavy call for the same project while the first is still running is rejected rather than queued. On the REST API that’s a 429 with a Retry-After header; MCP tools have no header channel, so the tool returns the error code rate_limited with retry guidance in howToFix. Wait a moment and retry — the limit is per project, not per key.
  • Query timeout. Long aggregations are bounded by a server-side timeout, returning query_timeout with a hint to narrow the days window or add filters.
Both are retryable. Normal interactive usage from Claude, Cursor, or similar clients is not expected to hit either; parallel fan-out across many tools for the same project is the usual trigger.

Support

All integrations

Browse the integrations directory

Contact support

Email our team