OpenRush MCP
Vendor MCP20 toolsOAuth 2.1/DCRMarketingAnalyticsConnect to OpenRush MCP to access marketing and competitive intelligence data — competitor discovery, keyword research, SERP snapshots, backlink analysis...
OpenRush MCP connector
-
Install the SDK
Section titled “Install the SDK”Terminal window npm install @scalekit-sdk/nodeTerminal window pip install scalekit -
Set your credentials
Section titled “Set your credentials”Add your Scalekit credentials to your
.envfile. 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> -
Authorize and make your first call
Section titled “Authorize and make your first call”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.actionsconst connector = 'openrushmcp'const identifier = 'user_123'// Generate an authorization link for the userconst { 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 callconst result = await actions.executeTool({connector,identifier,toolName: 'openrushmcp_get_ad_performance',toolInput: {},})console.log(result)quickstart.py import osfrom scalekit.client import ScalekitClientfrom dotenv import load_dotenvload_dotenv()scalekit_client = ScalekitClient(env_url=os.getenv("SCALEKIT_ENV_URL"),client_id=os.getenv("SCALEKIT_CLIENT_ID"),client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),)actions = scalekit_client.actionsconnection_name = "openrushmcp"identifier = "user_123"# Generate an authorization link for the userlink_response = actions.get_authorization_link(connection_name=connection_name,identifier=identifier,)print("Authorize OpenRush MCP:", link_response.link)input("Press Enter after authorizing...")# Make your first callresult = actions.execute_tool(tool_input={},tool_name="openrushmcp_get_ad_performance",connection_name=connection_name,identifier=identifier,)print(result)
What you can do
Section titled “What you can do”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
domainranks 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
Tool list
Section titled “Tool list”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.
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_backlink_gap#THE backlink gap / link intersect, done server-side in ONE call:
referring domains that link to several of a client's competitors,
ranked by how many competitors link them, spam- and authority-filtered,
with the ones the client already earned flagged.
This replaces the hand-run recipe (pull each competitor's referring
domains, union thousands of rows, dedupe against the client, enrich for
true authority, filter, sort) — all of which used to run in the agent's
context. Here it is one call and a compact, report-ready result.
How it works: ranks the competitors by true authority, fans out
referring-domain pulls to the strongest of them (the top-N recover
essentially the full intersect), unions and counts the overlap, attaches
TRUE domain authority + spam via the bulk endpoint (the row-level rank on
a referring row is page-level and must not be trusted), drops spam ≥
`max_spam` and authority < `min_authority`, flags each row `earned`
(client already links from it) or a fresh gap, and sorts by
(competitor_count desc, authority desc). Fan-out and per-competitor depth
are handled for you — there are no knobs for them.
Read `data.summary` for the funnel (union → candidates → after-filter →
gap/earned) and per-competitor coverage, and `coverage.scope_note` for
what was and wasn't covered. `data.gap` holds the top `limit` rows;
`resources` holds the FULL ranked list — fetch it with export_dataset,
don't re-run per-competitor pulls. A short list is a good result: if the
client already owns the strong domains, that shows up as earned=true, not
as junk padding.
First get a real competitor set from discover_competitors (seed_keywords
mode for a specific vertical); passing domain-similarity giants produces
a meaningless gap.7 params
THE backlink gap / link intersect, done server-side in ONE call: referring domains that link to several of a client's competitors, ranked by how many competitors link them, spam- and authority-filtered, with the ones the client already earned flagged. This replaces the hand-run recipe (pull each competitor's referring domains, union thousands of rows, dedupe against the client, enrich for true authority, filter, sort) — all of which used to run in the agent's context. Here it is one call and a compact, report-ready result. How it works: ranks the competitors by true authority, fans out referring-domain pulls to the strongest of them (the top-N recover essentially the full intersect), unions and counts the overlap, attaches TRUE domain authority + spam via the bulk endpoint (the row-level rank on a referring row is page-level and must not be trusted), drops spam ≥ `max_spam` and authority < `min_authority`, flags each row `earned` (client already links from it) or a fresh gap, and sorts by (competitor_count desc, authority desc). Fan-out and per-competitor depth are handled for you — there are no knobs for them. Read `data.summary` for the funnel (union → candidates → after-filter → gap/earned) and per-competitor coverage, and `coverage.scope_note` for what was and wasn't covered. `data.gap` holds the top `limit` rows; `resources` holds the FULL ranked list — fetch it with export_dataset, don't re-run per-competitor pulls. A short list is a good result: if the client already owns the strong domains, that shows up as earned=true, not as junk padding. First get a real competitor set from discover_competitors (seed_keywords mode for a specific vertical); passing domain-similarity giants produces a meaningless gap.
competitorsarrayrequiredThe competitor domains to measure the gap against.domainstringrequiredThe client's domain — the site the gap is measured FOR. Domains it already links from are flagged earned=true rather than re-pitched.include_earnedbooleanoptionalKeep domains the client already links from, flagged earned=true (so a report can say 'already earned' instead of re-pitching them). Set false for the pure 'what's left to earn' list.limitintegeroptionalHow many top rows to return inline as facts / data.gap. The FULL ranked set is always in resources (export_dataset).max_spamintegeroptionalDrop referring domains at/above this spam score (0-100).min_authorityintegeroptionalDrop referring domains below this TRUE domain authority (0-1000 scale). Set 0 to keep every domain regardless of strength.min_competitorsintegeroptionalA referring domain must link to at least this many competitors to be in the gap. 2 = the classic 'links to several rivals' intersect.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`.
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.
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`.
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.
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.
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.
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.
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).
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_backlinks#One domain's link profile, deep. Lean per `view`: ask for only the
slices you need. `view` is any subset of (default is just `authority`):
- "authority": the headline summary — domain_rank (0-1000, higher =
stronger), referring-domain count, total backlinks, dofollow ratio,
spam score. The cheap call for judging how established a site is.
- "referring_domains": a deep, paginated list of the domains that link
to the target. Its row-level rank is PAGE-level, not true domain
authority, so don't rank or filter on it directly. Use `limit` (up to
1000) and `offset` to page. For a competitor link-gap, don't page and
union these lists yourself — call compare_backlink_gap, which does the
union/rank/filter server-side.
- "anchors": the anchor-text distribution.
- "backlinks": individual links (from-url, anchor, dofollow, first_seen,
lost_date). Use `status="lost"` to find lost links to reclaim, and the
full list for disavow review. Set `domain_from` to a single source
domain to see exactly where and how it links to the target (source-page
URL + anchor) — the drill-down after a compare_backlink_gap row.
`status` ("live" default | "lost" | "new") and `since` (ISO date; only
links new/lost on/after it) apply to the referring_domains and backlinks
views for velocity and reclaim work. Backed by the cross-engine backlinks
index, so this works even when the organic search-index tools are thin.
For a competitor link-gap, `next_actions` point at compare_backlink_gap
(server-side join), not a hand-run union.7 params
One domain's link profile, deep. Lean per `view`: ask for only the slices you need. `view` is any subset of (default is just `authority`): - "authority": the headline summary — domain_rank (0-1000, higher = stronger), referring-domain count, total backlinks, dofollow ratio, spam score. The cheap call for judging how established a site is. - "referring_domains": a deep, paginated list of the domains that link to the target. Its row-level rank is PAGE-level, not true domain authority, so don't rank or filter on it directly. Use `limit` (up to 1000) and `offset` to page. For a competitor link-gap, don't page and union these lists yourself — call compare_backlink_gap, which does the union/rank/filter server-side. - "anchors": the anchor-text distribution. - "backlinks": individual links (from-url, anchor, dofollow, first_seen, lost_date). Use `status="lost"` to find lost links to reclaim, and the full list for disavow review. Set `domain_from` to a single source domain to see exactly where and how it links to the target (source-page URL + anchor) — the drill-down after a compare_backlink_gap row. `status` ("live" default | "lost" | "new") and `since` (ISO date; only links new/lost on/after it) apply to the referring_domains and backlinks views for velocity and reclaim work. Backed by the cross-engine backlinks index, so this works even when the organic search-index tools are thin. For a competitor link-gap, `next_actions` point at compare_backlink_gap (server-side join), not a hand-run union.
domainstringrequiredThe domain whose backlink profile to inspect.domain_fromstringoptionalbacklinks view only: return just the links coming FROM this source domain (e.g. the referring domain from a compare_backlink_gap row), so one call yields their exact source-page URLs and anchor text instead of paging the target's full inbound set. Ignored by the other views.limitintegeroptionalRows per list view (referring_domains / anchors / backlinks). Max 1000; the vendor prices per call not per row, so pull deep.offsetintegeroptionalRow offset for paging a deep list view.sincestringoptionalISO date (e.g. '2025-01-01'). Limits the referring_domains and backlinks views to links new or lost on/after it.statusstringoptionalLink state for the referring_domains and backlinks views: live (default) | lost (for reclaim) | new.viewarrayoptionalWhich slices to return; each is one vendor call. Any subset of authority | referring_domains | anchors | backlinks. Defaults to ['authority'].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.
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.
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.
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.
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.
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.
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.