Skip to content
Scalekit Docs

OpenRush MCP

Vendor MCP20 toolsOAuth 2.1/DCRMarketingAnalytics

Connect to OpenRush MCP to access marketing and competitive intelligence data — competitor discovery, keyword research, SERP snapshots, backlink analysis...

OpenRush MCP connector

  1. Terminal window
    npm install @scalekit-sdk/node

    Full SDK reference: Node.js | Python

  2. Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. quickstart.ts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENV_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'openrushmcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize OpenRush MCP:', link)
    process.stdout.write('Press Enter after authorizing...')
    await new Promise(r => process.stdin.once('data', r))
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'openrushmcp_get_ad_performance',
    toolInput: {},
    })
    console.log(result)

Connect this agent connector to let your agent:

  • Keywords research — Expand a seed term into a ranked demand list (volume, CPC, competition, intent per keyword)
  • List websites, connections — List the owned-data this account has connected
  • Serp inspect — Live SERP snapshot for one query: ranked organic results plus which SERP features are present (AI overview, featured snippet, local pack, paid, people-also-ask, related searches)
  • Search inspect — Where domain ranks across a specific keyword set (1-100 keywords), with a position summary
  • Page inspect — Full detail on a single page (exact URL): how many organic keywords it ranks for, estimated monthly traffic, and the top terms driving that traffic
  • Keyword inspect — Full detail on a single keyword: monthly volume, CPC, competition level, intent, 12-month trend, the current top SERP, and which SERP features it triggers

Use the exact tool names from the Tool list below when you call execute_tool. If you’re not sure which name to use, list the tools available for the current user first.

openrushmcp_audit_site#Fast, opinionated technical / content health audit across a sampled set of a domain's pages, tuned for organic-search signal over noise. Discovers URLs from the sitemap/robots (or a homepage link-crawl fallback), then samples one representative per URL template BY VALUE: money/content pages first, while enumerated low-value sections (e.g. a jobs board or event listings) get a single spot-check rather than eating the budget. Fetches the sample concurrently, then GATES OUT non-indexable pages — anything intentionally `noindex` (on a low-value page) or canonicalized to another URL is excluded from scoring instead of being reported as a problem (a noindexed job listing is working as intended). Returns: grouped `issue_clusters` (issue + severity + affected page count + which page roles + a fix), a ranked `recommendations` list weighted by the *value* of the pages affected, an `onpage_score`, and cross-page duplicate-title/description checks. Full per-page rows — including excluded pages and why — are linked via `resources` (fetch with export_dataset). Runs in seconds. - `max_pages` (default 10, max 20): how many sampled pages to audit. Key fields: `page_class_summary` (sampled pages by role: core/content/ utility/ephemeral), `pages_excluded` + `excluded_summary` (non-indexable pages skipped, by reason), and `worst_page` (the highest-value page with the most issues — the best drill-down target). Each cluster/recommendation carries `page_classes` so you can tell whether a finding hits money pages or just utility ones. Scope: this reads each page's raw HTML — it does NOT execute JavaScript or measure Core Web Vitals. `render_warning: true` means ≥1 audited page looks client-rendered (its raw HTML is near-empty), so its content checks are low-confidence. Also read `coverage` (audited vs discovered), `discovery_source` (a `homepage_fallback` means no sitemap was found), and `fetch_failures` (pages that didn't respond in time). To confirm which findings hit pages that actually earn search traffic, follow the `inspect_domain` / `inspect_page` next_actions.2 params

Fast, opinionated technical / content health audit across a sampled set of a domain's pages, tuned for organic-search signal over noise. Discovers URLs from the sitemap/robots (or a homepage link-crawl fallback), then samples one representative per URL template BY VALUE: money/content pages first, while enumerated low-value sections (e.g. a jobs board or event listings) get a single spot-check rather than eating the budget. Fetches the sample concurrently, then GATES OUT non-indexable pages — anything intentionally `noindex` (on a low-value page) or canonicalized to another URL is excluded from scoring instead of being reported as a problem (a noindexed job listing is working as intended). Returns: grouped `issue_clusters` (issue + severity + affected page count + which page roles + a fix), a ranked `recommendations` list weighted by the *value* of the pages affected, an `onpage_score`, and cross-page duplicate-title/description checks. Full per-page rows — including excluded pages and why — are linked via `resources` (fetch with export_dataset). Runs in seconds. - `max_pages` (default 10, max 20): how many sampled pages to audit. Key fields: `page_class_summary` (sampled pages by role: core/content/ utility/ephemeral), `pages_excluded` + `excluded_summary` (non-indexable pages skipped, by reason), and `worst_page` (the highest-value page with the most issues — the best drill-down target). Each cluster/recommendation carries `page_classes` so you can tell whether a finding hits money pages or just utility ones. Scope: this reads each page's raw HTML — it does NOT execute JavaScript or measure Core Web Vitals. `render_warning: true` means ≥1 audited page looks client-rendered (its raw HTML is near-empty), so its content checks are low-confidence. Also read `coverage` (audited vs discovered), `discovery_source` (a `homepage_fallback` means no sitemap was found), and `fetch_failures` (pages that didn't respond in time). To confirm which findings hit pages that actually earn search traffic, follow the `inspect_domain` / `inspect_page` next_actions.

NameTypeRequiredDescription
domainstringrequiredThe site to audit: "example.com", or a subdomain host to audit that property alone. A URL or www. prefix is normalized; must be a public host.
max_pagesintegeroptionalHow many sampled pages to audit (1-20).
openrushmcp_compare_keyword_coverage#Keyword gap analysis: terms one or more competitors (1-10 domains) rank for that `domain` does not, plus terms where the target is losing ground. Use after discover_competitors to turn a competitor set into a concrete content/keyword target list. Results group into intent clusters so the agent can prioritize. Both target and competitors must be reasonably indexed for the gap set to be meaningful — see `coverage`.5 params

Keyword gap analysis: terms one or more competitors (1-10 domains) rank for that `domain` does not, plus terms where the target is losing ground. Use after discover_competitors to turn a competitor set into a concrete content/keyword target list. Results group into intent clusters so the agent can prioritize. Both target and competitors must be reasonably indexed for the gap set to be meaningful — see `coverage`.

NameTypeRequiredDescription
competitorsarrayrequired1-10 competitor domains to compare against.
domainstringrequiredThe target site whose keyword gaps you want. A bare domain covers all its subdomains; pass a subdomain to narrow to that property.
languagestringoptionalResult language ("English", "Spanish").
limitintegeroptionalHow many gap keywords to return.
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
openrushmcp_describe_capabilities#START HERE. List the live OpenRush surface: enabled data domains, the tools in each, the fact types every tool can emit, which sources back them (live SERP, search index, backlinks, owned Search Console/Analytics/Ads), and which tools need an owned-data connection. Use this to discover what's available before assuming a tool exists. Returns the standard OFE envelope; the tool list is in `data.tools`.0 params

START HERE. List the live OpenRush surface: enabled data domains, the tools in each, the fact types every tool can emit, which sources back them (live SERP, search index, backlinks, owned Search Console/Analytics/Ads), and which tools need an owned-data connection. Use this to discover what's available before assuming a tool exists. Returns the standard OFE envelope; the tool list is in `data.tools`.

openrushmcp_discover_ai_citations#Which domains AI cites on a category — the map of where to earn a mention, and who AI cites instead of you. Provide `topic` (a real category keyword) or `domain`, and if both are given `topic` wins. Prefer `topic` whenever you know the brand's real category: pass the category as `topic` (and the brand as `domain` if you also want its standing). Fall back to `domain` alone only when the category is unknown — the tool then derives it from the domain's top ranking keywords, which is reliable for an established site but can pick a tangential term for a thin or new site that barely ranks (e.g. a website-migration brand whose top keyword is "migrate ai", an AI/cloud term). When that happens the result is labeled `data.category_confidence: "derived_weak"` and carries a next-action asking you to supply the real category as `topic`; re-run with an explicit `topic` for an accurate map. Coverage is Google AI Overview only (the deep, independently validated surface); this does NOT cover ChatGPT, Claude, Gemini, Perplexity, or CoPilot. The metric is "this domain cited as a source", not "brand discussed". Results are domain-anchored, never brand-name matched. A scattered or tagline-like input returns a low-signal `data_freshness` note instead of junk rows, and "AI search volume" is never surfaced. Use this even when a brand has zero AI presence: it shows where its category is cited so it knows where to earn placement. `next_actions` point to inspect_ai_visibility to see where a domain stands among these sources.5 params

Which domains AI cites on a category — the map of where to earn a mention, and who AI cites instead of you. Provide `topic` (a real category keyword) or `domain`, and if both are given `topic` wins. Prefer `topic` whenever you know the brand's real category: pass the category as `topic` (and the brand as `domain` if you also want its standing). Fall back to `domain` alone only when the category is unknown — the tool then derives it from the domain's top ranking keywords, which is reliable for an established site but can pick a tangential term for a thin or new site that barely ranks (e.g. a website-migration brand whose top keyword is "migrate ai", an AI/cloud term). When that happens the result is labeled `data.category_confidence: "derived_weak"` and carries a next-action asking you to supply the real category as `topic`; re-run with an explicit `topic` for an accurate map. Coverage is Google AI Overview only (the deep, independently validated surface); this does NOT cover ChatGPT, Claude, Gemini, Perplexity, or CoPilot. The metric is "this domain cited as a source", not "brand discussed". Results are domain-anchored, never brand-name matched. A scattered or tagline-like input returns a low-signal `data_freshness` note instead of junk rows, and "AI search volume" is never surfaced. Use this even when a brand has zero AI presence: it shows where its category is cited so it knows where to earn placement. `next_actions` point to inspect_ai_visibility to see where a domain stands among these sources.

NameTypeRequiredDescription
domainstringoptionalThe brand's domain, used alone to derive the category from its top ranking keywords. One of `topic` / `domain` is required.
languagestringoptionalResult language ("English", "Spanish").
limitintegeroptionalHow many citing domains to return.
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
topicstringoptionalThe category to map, as a real category keyword ("website migration services") — not a tagline or brand name. Preferred input, and wins if `domain` is also given. One of `topic` / `domain` is required.
openrushmcp_discover_competitors#Find organic competitors. Provide exactly one of `domain` or `seed_keywords`. - domain mode: competitors by keyword overlap with the target's indexed set. Broad, but unreliable for new/small sites because the search index lags the live SERP — the response flags this with a `data_freshness` fact. - seed_keywords mode (1-20 queries): aggregates who consistently ranks across those queries by hitting the live SERP database directly. Needs the SEEDS indexed in that market, not the target — returns empty, with a reason, when they are not. Prefer it when domain mode came back thin; read `coverage`.5 params

Find organic competitors. Provide exactly one of `domain` or `seed_keywords`. - domain mode: competitors by keyword overlap with the target's indexed set. Broad, but unreliable for new/small sites because the search index lags the live SERP — the response flags this with a `data_freshness` fact. - seed_keywords mode (1-20 queries): aggregates who consistently ranks across those queries by hitting the live SERP database directly. Needs the SEEDS indexed in that market, not the target — returns empty, with a reason, when they are not. Prefer it when domain mode came back thin; read `coverage`.

NameTypeRequiredDescription
domainstringoptionaldomain mode: the site to find competitors for. Pass this or `seed_keywords`; if both are given `seed_keywords` wins and this is ignored.
languagestringoptionalResult language ("English", "Spanish").
limitintegeroptionalHow many competitor domains to return.
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
seed_keywordsarrayoptionalseed_keywords mode: 1-20 real search queries to find who consistently ranks across them (e.g. ["crm software", "sales pipeline tool"]). A list of strings, not a JSON-encoded string. Takes precedence over `domain`.
openrushmcp_export_dataset#Fetch the full rows behind a dataset `uri` that another tool returned in its `resources` block (results too large to inline). Pass the uri verbatim; do not construct one yourself. Datasets are retained for a limited window and may be dropped sooner under load, so a valid uri can come back empty. That is not an error: when it happens the response has `data.available = false` with a `note`, and `next_actions` contains the tool to re-run to regenerate the dataset. Follow that action, then export the fresh uri from the new `resources` block.1 param

Fetch the full rows behind a dataset `uri` that another tool returned in its `resources` block (results too large to inline). Pass the uri verbatim; do not construct one yourself. Datasets are retained for a limited window and may be dropped sooner under load, so a valid uri can come back empty. That is not an error: when it happens the response has `data.available = false` with a `note`, and `next_actions` contains the tool to re-run to regenerate the dataset. Follow that action, then export the fresh uri from the new `resources` block.

NameTypeRequiredDescription
uristringrequiredA dataset uri from another tool's `resources` block.
openrushmcp_get_ad_performance#Measured, normalized ad performance (spend, impressions, clicks, CTR, CPC, CPM, conversions, conversion value, cost/conversion, conversion rate, ROAS) for one of the user's OWN connected ad accounts — Google Ads today, more ad platforms later — straight from the platform, not a modeled estimate. THE single tool for every ad platform: ask once, and OpenRush handles which platforms are connected. `platform` and `ad_account` are optional: omit both and the single connected platform + activated account are auto-selected. Several connected platforms return `platform_required`; several activated accounts return `account_required`; nothing connected/activated returns `connection_required` (set up in the dashboard). One platform per call — `next_actions` point to any other connected platform and to deeper slices. - `report`: overview (default: account totals + top campaigns + daily trend + Google network split) | campaign | ad_group | asset_group | ad | date | device | network | keyword | search_term (the last three Google-only). Use asset_group for Performance Max campaigns — they have no ad_group/ad rows; their creative unit is the asset group. Every other type (Search, Shopping, Demand Gen, Video, Display) has ad groups and ads. next_actions route to the right drilldown per campaign type, and to both on a mixed account. - `group_by`: the lower-level equivalent of `report` (one dimension) - `period`: last_7_days | last_28_days (default) | last_3_months | last_6_months | last_12_months - `compare_to`: previous_period (default) | previous_year | none Every monetary value carries its currency and is NEVER converted; every conversion/ROAS number carries its attribution basis. Windows are in the account's own time zone; the most recent ~1-2 days are preliminary. Ad clicks are PAID clicks — not GA4 sessions and not Search Console clicks. Read-only: no campaign, budget, or bid changes.8 params

Measured, normalized ad performance (spend, impressions, clicks, CTR, CPC, CPM, conversions, conversion value, cost/conversion, conversion rate, ROAS) for one of the user's OWN connected ad accounts — Google Ads today, more ad platforms later — straight from the platform, not a modeled estimate. THE single tool for every ad platform: ask once, and OpenRush handles which platforms are connected. `platform` and `ad_account` are optional: omit both and the single connected platform + activated account are auto-selected. Several connected platforms return `platform_required`; several activated accounts return `account_required`; nothing connected/activated returns `connection_required` (set up in the dashboard). One platform per call — `next_actions` point to any other connected platform and to deeper slices. - `report`: overview (default: account totals + top campaigns + daily trend + Google network split) | campaign | ad_group | asset_group | ad | date | device | network | keyword | search_term (the last three Google-only). Use asset_group for Performance Max campaigns — they have no ad_group/ad rows; their creative unit is the asset group. Every other type (Search, Shopping, Demand Gen, Video, Display) has ad groups and ads. next_actions route to the right drilldown per campaign type, and to both on a mixed account. - `group_by`: the lower-level equivalent of `report` (one dimension) - `period`: last_7_days | last_28_days (default) | last_3_months | last_6_months | last_12_months - `compare_to`: previous_period (default) | previous_year | none Every monetary value carries its currency and is NEVER converted; every conversion/ROAS number carries its attribution basis. Windows are in the account's own time zone; the most recent ~1-2 days are preliminary. Ad clicks are PAID clicks — not GA4 sessions and not Search Console clicks. Read-only: no campaign, budget, or bid changes.

NameTypeRequiredDescription
ad_accountstringoptionalAn OpenRush ad-account id, from list_connections (`data.ad_accounts[].ad_account`) or an `account_required` error's `data.options`. NOT a raw Google customer id. Omit it to auto-select the single activated account; never invent one.
compare_tostringoptionalComparison baseline: previous_period | previous_year | none.
filtersarrayoptionalUp to 10 filters, each {dimension, operator, expression}. dimension: campaign | device | network. operator: equals | contains for campaign (matched on the campaign name); equals only for device and network. device values: mobile | desktop | tablet | connected_tv | other. network values: search | search_partners | display | youtube | youtube_search | mixed.
group_byarrayoptionalOne dimension, any `report` token except overview. Overrides `report` when given — use `report` unless you are mapping a raw dimension name.
limitintegeroptionalMaximum rows for a single-slice report (1-1000). Defaults to 100.
periodstringoptionalReporting window in the account's own time zone: last_7_days | last_28_days | last_3_months | last_6_months | last_12_months.
platformstringoptionalAd platform: google_ads. Omit it to auto-select when one platform is connected; a `platform_required` error lists the choices in `data.options`.
reportstringoptionalPrebuilt slice: overview (default: account totals + top campaigns + daily trend + Google network split) | campaign | ad_group | asset_group | ad | date | device | network | keyword | search_term (the last three are Google-only). Use asset_group for Performance Max campaigns, which have asset groups instead of ad groups and ads; every other campaign type (Search, Shopping, Demand Gen, Video, Display) drills into ad_group and ad.
openrushmcp_get_search_performance#Measured Google Search performance (clicks, impressions, CTR, impression-weighted position) for one of the user's OWN websites, straight from their connected Search Console — not a modeled estimate. `website_id` and `domain` are optional, interchangeable selectors: omit both and the single connected website is auto-selected. If the account has several connected websites the call returns a `website_required` error listing safe options in `data.options` — retry with one `website_id`. If nothing is connected yet it returns `connection_required`/`binding_required` (set up in the dashboard). - `period`: last_7_days | last_28_days (default) | last_3_months | last_6_months | last_12_months | last_16_months - `compare_to`: previous_period (default) | previous_year | none - `group_by`: any of page | query | date | device | country (omit for the site total; page + query is allowed but bounded) - `search_type`: web (default) | image | video | news | discover The most recent ~3 days are labeled preliminary; GSC reports search performance, which is not the same as total website traffic.8 params

Measured Google Search performance (clicks, impressions, CTR, impression-weighted position) for one of the user's OWN websites, straight from their connected Search Console — not a modeled estimate. `website_id` and `domain` are optional, interchangeable selectors: omit both and the single connected website is auto-selected. If the account has several connected websites the call returns a `website_required` error listing safe options in `data.options` — retry with one `website_id`. If nothing is connected yet it returns `connection_required`/`binding_required` (set up in the dashboard). - `period`: last_7_days | last_28_days (default) | last_3_months | last_6_months | last_12_months | last_16_months - `compare_to`: previous_period (default) | previous_year | none - `group_by`: any of page | query | date | device | country (omit for the site total; page + query is allowed but bounded) - `search_type`: web (default) | image | video | news | discover The most recent ~3 days are labeled preliminary; GSC reports search performance, which is not the same as total website traffic.

NameTypeRequiredDescription
compare_tostringoptionalComparison baseline: previous_period | previous_year | none.
domainstringoptionalAlternative to `website_id`: the domain of one of the user's OWN connected websites. Not a way to query a site they have not connected.
filtersarrayoptionalUp to 10 filters, each {dimension, operator, expression}. dimension: query | page | country | device | searchAppearance. operator: equals | notEquals | contains | notContains | includingRegex | excludingRegex (note these differ from the analytics operators).
group_byarrayoptionalBreakdown dimensions: page | query | date | device | country. Two are accepted only as page + query. Omit for the site total.
limitintegeroptionalMaximum number of rows to return (1-1000). Defaults to 100.
periodstringoptionalReporting window: last_7_days | last_28_days | last_3_months | last_6_months | last_12_months | last_16_months.
search_typestringoptionalSearch surface: web | image | video | news | discover | googleNews.
website_idstringoptionalAn OpenRush website id, from list_connections or a `website_required` error's `data.options`. Omit it and `domain` to auto-select the single connected website; never invent one.
openrushmcp_get_website_analytics#Measured website analytics (sessions, users, engaged sessions, engagement rate, average engagement time, page views, bounce rate) for one of the user's OWN websites, straight from their connected Google Analytics (GA4) property — not a modeled estimate. `website_id` and `domain` are optional, interchangeable selectors: omit both and the single connected website is auto-selected. If the account has several connected websites the call returns a `website_required` error listing safe options in `data.options` — retry with one `website_id`. If nothing is connected yet it returns `connection_required`/`binding_required` (set up in the dashboard). - `report`: overview (default, a rich summary: site totals + top channels + top landing pages + a daily trend) | channel | source_medium | campaign | landing_page | country | device | date - `group_by`: the lower-level equivalent of `report` (one dimension) - `period`: last_7_days | last_28_days (default) | last_3_months | last_6_months | last_12_months - `compare_to`: previous_period (default) | previous_year | none Windows are computed in the property's own reporting timezone. The most recent ~1-2 days are labeled preliminary. Sessions are visits, not users, and are not the same as Search Console clicks. This is the universal traffic/attribution/engagement tool: it deliberately reports NO conversions, revenue, or custom events.8 params

Measured website analytics (sessions, users, engaged sessions, engagement rate, average engagement time, page views, bounce rate) for one of the user's OWN websites, straight from their connected Google Analytics (GA4) property — not a modeled estimate. `website_id` and `domain` are optional, interchangeable selectors: omit both and the single connected website is auto-selected. If the account has several connected websites the call returns a `website_required` error listing safe options in `data.options` — retry with one `website_id`. If nothing is connected yet it returns `connection_required`/`binding_required` (set up in the dashboard). - `report`: overview (default, a rich summary: site totals + top channels + top landing pages + a daily trend) | channel | source_medium | campaign | landing_page | country | device | date - `group_by`: the lower-level equivalent of `report` (one dimension) - `period`: last_7_days | last_28_days (default) | last_3_months | last_6_months | last_12_months - `compare_to`: previous_period (default) | previous_year | none Windows are computed in the property's own reporting timezone. The most recent ~1-2 days are labeled preliminary. Sessions are visits, not users, and are not the same as Search Console clicks. This is the universal traffic/attribution/engagement tool: it deliberately reports NO conversions, revenue, or custom events.

NameTypeRequiredDescription
compare_tostringoptionalComparison baseline: previous_period | previous_year | none.
domainstringoptionalAlternative to `website_id`: the domain of one of the user's OWN connected websites. Not a way to query a site they have not connected.
filtersarrayoptionalUp to 10 filters, each {dimension, operator, expression}. dimension: any `report` token except overview and date, plus content | term. operator: exact | contains | begins_with | ends_with | full_regexp (note these differ from the Search Console operators).
group_byarrayoptionalOne dimension, any `report` token except overview. Overrides `report` when given — use `report` unless you are mapping a raw dimension name.
limitintegeroptionalMaximum number of rows to return (1-1000). Defaults to 100.
periodstringoptionalReporting window: last_7_days | last_28_days | last_3_months | last_6_months | last_12_months.
reportstringoptionalPrebuilt slice: overview (default: site totals + top channels + top landing pages + a daily trend) | channel | source | medium | source_medium | campaign | landing_page | country | city | device | browser | operating_system | date.
website_idstringoptionalAn OpenRush website id, from list_connections or a `website_required` error's `data.options`. Omit it and `domain` to auto-select the single connected website; never invent one.
openrushmcp_inspect_ai_visibility#How a domain shows up in AI answers — its citation count, alone or against named competitor DOMAINS (up to 9), with the gap. Always domain-anchored: pass domains, never brand names (a brand name matches thousands of unrelated answers; a domain is an exact entity). Coverage is Google AI Overview only; this does NOT cover ChatGPT, Claude, Gemini, Perplexity, or CoPilot. The number is "your domain cited as a source", not "how often AI talks about you", and it is a sampled corpus observation, not what any one user sees. AI answers are non-deterministic, so treat movement as directional. A zero is a first-class answer, not an error: a domain AI has not cited yet returns a `brand_mentions` fact with `mentions: 0` plus a `next_actions` pointer to discover_ai_citations (where to earn a mention). Comparing more competitors costs no more — they are batched into one call. Call it solo (no competitors) to also get `data.sample_answers` — real questions where the domain is cited, with the sources cited alongside it. With competitors you get the ranked comparison and share-of-citations gap instead (no sample answers).4 params

How a domain shows up in AI answers — its citation count, alone or against named competitor DOMAINS (up to 9), with the gap. Always domain-anchored: pass domains, never brand names (a brand name matches thousands of unrelated answers; a domain is an exact entity). Coverage is Google AI Overview only; this does NOT cover ChatGPT, Claude, Gemini, Perplexity, or CoPilot. The number is "your domain cited as a source", not "how often AI talks about you", and it is a sampled corpus observation, not what any one user sees. AI answers are non-deterministic, so treat movement as directional. A zero is a first-class answer, not an error: a domain AI has not cited yet returns a `brand_mentions` fact with `mentions: 0` plus a `next_actions` pointer to discover_ai_citations (where to earn a mention). Comparing more competitors costs no more — they are batched into one call. Call it solo (no competitors) to also get `data.sample_answers` — real questions where the domain is cited, with the sources cited alongside it. With competitors you get the ranked comparison and share-of-citations gap instead (no sample answers).

NameTypeRequiredDescription
domainstringrequiredThe domain to check AI-citation visibility for.
competitorsarrayoptionalUp to 9 competitor DOMAINS. Omit for a solo read, which also returns `data.sample_answers`.
languagestringoptionalResult language ("English", "Spanish").
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
openrushmcp_inspect_domain#Starting map for any domain: top organic keywords, top pages, estimated traffic, dominant search intents, and likely competitors in one call. Use this first when handed a bare domain. The `next_actions` typically point to inspect_page (for a winning URL), research_keywords (around a theme), or discover_competitors. Backed by the search index, so a brand-new or barely-indexed domain may return thin `data` — check `coverage` before concluding a site ranks for nothing. If `data.result_status` is `partial`, check `data.section_status`: unavailable sections are unknown, not empty.3 params

Starting map for any domain: top organic keywords, top pages, estimated traffic, dominant search intents, and likely competitors in one call. Use this first when handed a bare domain. The `next_actions` typically point to inspect_page (for a winning URL), research_keywords (around a theme), or discover_competitors. Backed by the search index, so a brand-new or barely-indexed domain may return thin `data` — check `coverage` before concluding a site ranks for nothing. If `data.result_status` is `partial`, check `data.section_status`: unavailable sections are unknown, not empty.

NameTypeRequiredDescription
domainstringrequiredThe site to map: "example.com", or a named subdomain ("news.example.com") to scope to that property alone. A URL or www. prefix is normalized.
languagestringoptionalResult language ("English", "Spanish").
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
openrushmcp_inspect_keyword#Full detail on a single keyword: monthly volume, CPC, competition level, intent, 12-month trend, the current top SERP, and which SERP features it triggers. Use to validate or deep-dive one term surfaced by research_keywords or a gap analysis before committing to it.3 params

Full detail on a single keyword: monthly volume, CPC, competition level, intent, 12-month trend, the current top SERP, and which SERP features it triggers. Use to validate or deep-dive one term surfaced by research_keywords or a gap analysis before committing to it.

NameTypeRequiredDescription
keywordstringrequiredThe keyword to look up full detail for (1-200 characters).
languagestringoptionalResult language ("English", "Spanish").
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
openrushmcp_inspect_page#Full detail on a single page (exact URL): how many organic keywords it ranks for, estimated monthly traffic, and the top terms driving that traffic. Use to understand why a specific competitor URL wins, or to profile one of your own pages surfaced by inspect_domain's top_pages.3 params

Full detail on a single page (exact URL): how many organic keywords it ranks for, estimated monthly traffic, and the top terms driving that traffic. Use to understand why a specific competitor URL wins, or to profile one of your own pages surfaced by inspect_domain's top_pages.

NameTypeRequiredDescription
urlstringrequiredThe page URL INCLUDING scheme ("https://example.com/pricing"). Matched exactly against ranking data, so the scheme and path must be the real ones.
languagestringoptionalResult language ("English", "Spanish").
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
openrushmcp_inspect_search_visibility#Where `domain` ranks across a specific keyword set (1-100 keywords), with a position summary. mode controls the data backend: - "auto" (default): search-index lookup, auto-falling back to live SERPs when the target is underindexed. Best signal-to-noise for any-size domain. - "index": search index only. Fastest; reports unranked for new domains. - "live": one live SERP fetch per keyword — slowest and most expensive (one billed query per keyword, capped at 10 per call); always reflects today's Google. Use when "auto"/"index" look stale for a new site. Prefer "auto", which already falls back to live when the target is underindexed. This is a point-in-time read of current positions.5 params

Where `domain` ranks across a specific keyword set (1-100 keywords), with a position summary. mode controls the data backend: - "auto" (default): search-index lookup, auto-falling back to live SERPs when the target is underindexed. Best signal-to-noise for any-size domain. - "index": search index only. Fastest; reports unranked for new domains. - "live": one live SERP fetch per keyword — slowest and most expensive (one billed query per keyword, capped at 10 per call); always reflects today's Google. Use when "auto"/"index" look stale for a new site. Prefer "auto", which already falls back to live when the target is underindexed. This is a point-in-time read of current positions.

NameTypeRequiredDescription
domainstringrequiredThe site whose positions you want. A named subdomain is scoped as its own property.
keywordsarrayrequired1-100 keywords to check positions for. Note the live path resolves at most 10 per call; the rest are reported as unchecked in `coverage`.
languagestringoptionalResult language ("English", "Spanish").
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
modestringoptionalData backend. Prefer "auto"; "live" is billed per keyword and capped at 10.
openrushmcp_inspect_serp#Live SERP snapshot for one query: ranked organic results plus which SERP features are present (AI overview, featured snippet, local pack, paid, people-also-ask, related searches). Use to see who actually ranks right now and what the result page looks like before targeting a query. `depth` (10-100) is how many organic results to pull; raise it only when you need the long tail. Reflects Google today, not the index.4 params

Live SERP snapshot for one query: ranked organic results plus which SERP features are present (AI overview, featured snippet, local pack, paid, people-also-ask, related searches). Use to see who actually ranks right now and what the result page looks like before targeting a query. `depth` (10-100) is how many organic results to pull; raise it only when you need the long tail. Reflects Google today, not the index.

NameTypeRequiredDescription
querystringrequiredThe search query to fetch a live SERP snapshot for (1-200 characters).
depthintegeroptionalHow many SERP results to pull (10-100). Raise it only when you need the long tail.
languagestringoptionalResult language ("English", "Spanish").
locationstringoptionalTarget market: a country ("United States") or a full sub-country location ending in its country ("London,England,United Kingdom"). A bare city is rejected. Defaults to the United States when omitted.
openrushmcp_list_connections#List the owned-data this account has connected. Two sibling sections, because the products are addressed differently: `data.websites` — the website-addressed products (Search Console, GA4). Each website reports its per-product state under `connections`: - `search_console`: connected | reconnect_required | not_connected - `website_analytics`: connected | reconnect_required | not_connected `search_console` connected means get_search_performance can return data for that website; `website_analytics` connected means get_website_analytics can. `data.ad_accounts` — the account-addressed ad platforms (Google Ads now, more later). Ads are NOT website-addressed: the ad account is the unit, so this is a flat list independent of `websites`, each row carrying `platform`, the opaque `ad_account` id (pass it back to get_ad_performance), `name`, `currency`, `customer_id_display`, and `connection_status`. Only ACTIVATED accounts appear — the ones get_ad_performance can actually query. (A website may separately show an `ad_platform` key under its `connections` only when the user made the OPTIONAL website↔account association; that key is NOT the way to tell whether ads are connected — use `data.ad_accounts` for that.) An account that has connected nothing at all returns EMPTY `websites` and `ad_accounts` with `data.connection_required: true`. Do not invent a website or ad account in that case; tell the user a connection is required. You usually do NOT need to call this first: get_search_performance, get_website_analytics, and get_ad_performance auto-select when the account has exactly one eligible target. Call this when the user asks what's connected, wants to switch target, or an owned-data tool returned a `website_required` / `account_required` error — then retry that tool with a `website_id` from `data.websites` or an `ad_account` from `data.ad_accounts`.0 params

List the owned-data this account has connected. Two sibling sections, because the products are addressed differently: `data.websites` — the website-addressed products (Search Console, GA4). Each website reports its per-product state under `connections`: - `search_console`: connected | reconnect_required | not_connected - `website_analytics`: connected | reconnect_required | not_connected `search_console` connected means get_search_performance can return data for that website; `website_analytics` connected means get_website_analytics can. `data.ad_accounts` — the account-addressed ad platforms (Google Ads now, more later). Ads are NOT website-addressed: the ad account is the unit, so this is a flat list independent of `websites`, each row carrying `platform`, the opaque `ad_account` id (pass it back to get_ad_performance), `name`, `currency`, `customer_id_display`, and `connection_status`. Only ACTIVATED accounts appear — the ones get_ad_performance can actually query. (A website may separately show an `ad_platform` key under its `connections` only when the user made the OPTIONAL website↔account association; that key is NOT the way to tell whether ads are connected — use `data.ad_accounts` for that.) An account that has connected nothing at all returns EMPTY `websites` and `ad_accounts` with `data.connection_required: true`. Do not invent a website or ad account in that case; tell the user a connection is required. You usually do NOT need to call this first: get_search_performance, get_website_analytics, and get_ad_performance auto-select when the account has exactly one eligible target. Call this when the user asks what's connected, wants to switch target, or an owned-data tool returned a `website_required` / `account_required` error — then retry that tool with a `website_id` from `data.websites` or an `ad_account` from `data.ad_accounts`.

openrushmcp_list_websites#List the owned-data this account has connected. Two sibling sections, because the products are addressed differently: `data.websites` — the website-addressed products (Search Console, GA4). Each website reports its per-product state under `connections`: - `search_console`: connected | reconnect_required | not_connected - `website_analytics`: connected | reconnect_required | not_connected `search_console` connected means get_search_performance can return data for that website; `website_analytics` connected means get_website_analytics can. `data.ad_accounts` — the account-addressed ad platforms (Google Ads now, more later). Ads are NOT website-addressed: the ad account is the unit, so this is a flat list independent of `websites`, each row carrying `platform`, the opaque `ad_account` id (pass it back to get_ad_performance), `name`, `currency`, `customer_id_display`, and `connection_status`. Only ACTIVATED accounts appear — the ones get_ad_performance can actually query. (A website may separately show an `ad_platform` key under its `connections` only when the user made the OPTIONAL website↔account association; that key is NOT the way to tell whether ads are connected — use `data.ad_accounts` for that.) An account that has connected nothing at all returns EMPTY `websites` and `ad_accounts` with `data.connection_required: true`. Do not invent a website or ad account in that case; tell the user a connection is required. You usually do NOT need to call this first: get_search_performance, get_website_analytics, and get_ad_performance auto-select when the account has exactly one eligible target. Call this when the user asks what's connected, wants to switch target, or an owned-data tool returned a `website_required` / `account_required` error — then retry that tool with a `website_id` from `data.websites` or an `ad_account` from `data.ad_accounts`.0 params

List the owned-data this account has connected. Two sibling sections, because the products are addressed differently: `data.websites` — the website-addressed products (Search Console, GA4). Each website reports its per-product state under `connections`: - `search_console`: connected | reconnect_required | not_connected - `website_analytics`: connected | reconnect_required | not_connected `search_console` connected means get_search_performance can return data for that website; `website_analytics` connected means get_website_analytics can. `data.ad_accounts` — the account-addressed ad platforms (Google Ads now, more later). Ads are NOT website-addressed: the ad account is the unit, so this is a flat list independent of `websites`, each row carrying `platform`, the opaque `ad_account` id (pass it back to get_ad_performance), `name`, `currency`, `customer_id_display`, and `connection_status`. Only ACTIVATED accounts appear — the ones get_ad_performance can actually query. (A website may separately show an `ad_platform` key under its `connections` only when the user made the OPTIONAL website↔account association; that key is NOT the way to tell whether ads are connected — use `data.ad_accounts` for that.) An account that has connected nothing at all returns EMPTY `websites` and `ad_accounts` with `data.connection_required: true`. Do not invent a website or ad account in that case; tell the user a connection is required. You usually do NOT need to call this first: get_search_performance, get_website_analytics, and get_ad_performance auto-select when the account has exactly one eligible target. Call this when the user asks what's connected, wants to switch target, or an owned-data tool returned a `website_required` / `account_required` error — then retry that tool with a `website_id` from `data.websites` or an `ad_account` from `data.ad_accounts`.

openrushmcp_research_keywords#Expand a seed term into a ranked demand list (volume, CPC, competition, intent per keyword). mode: - "ideas" (default): broad, category-level expansion. Best for mapping a topic. - "suggestions": autocomplete-style long-tail off the exact seed. - "related": semantically adjacent terms. Optional filters: `min_volume` drops low-demand noise; `intent` restricts to one of informational | navigational | commercial | transactional.7 params

Expand a seed term into a ranked demand list (volume, CPC, competition, intent per keyword). mode: - "ideas" (default): broad, category-level expansion. Best for mapping a topic. - "suggestions": autocomplete-style long-tail off the exact seed. - "related": semantically adjacent terms. Optional filters: `min_volume` drops low-demand noise; `intent` restricts to one of informational | navigational | commercial | transactional.

NameTypeRequiredDescription
seedstringrequiredThe ONE seed term to expand — a single search phrase ("seo audit tool"), not a list, not a JSON-encoded array, not a domain. Call once per seed; discover_competitors is the tool that takes a keyword LIST (`seed_keywords`).
intentstringoptionalRestrict results to one search intent.
languagestringoptionalResult language ("English", "Spanish").
limitintegeroptionalHow many keywords to fetch. `min_volume` and `intent` filter afterwards, so the result can be smaller.
locationstringoptionalTarget market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
min_volumeintegeroptionalDrop keywords below this monthly search volume.
modestringoptionalExpansion style: "ideas" = broad category-level expansion (best for mapping a topic), "suggestions" = autocomplete-style long-tail off the exact seed, "related" = semantically adjacent terms.