Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the OpenRush MCP server

Vendor MCP
Open markdown

The OpenRush MCP connector routes your AI agent's tool calls to OpenRush's own MCP server through Scalekit. Each user signs in to OpenRush once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 20 tools.

Tools
20
What they doRead · write · destructive
20 · 0 · 020 read0 write0 destructive
Users sign in with
OAuth app
Scalekit's or your own

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    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. Create the OpenRush MCP connection

    In AgentKit > Connections, create an OpenRush MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for OpenRush MCP server, so you don't need to register an OAuth app.

  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_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)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'openrushmcp_describe_capabilities',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • openrushmcp_audit_siteFast, opinionated technical / content health audit across a sampled set of a domain's pages, tuned for organic-search signal over noise.Read-only

    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.

    Inputs

    domainstringrequired
    The 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_pagesinteger
    How many sampled pages to audit (1-20).default 10
  • openrushmcp_compare_keyword_coverageKeyword gap analysis: terms one or more competitors (1-10 domains) rank for that `domain` does not, plus terms where the target is losing ground.Read-only

    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`.

    Inputs

    competitorsarrayrequired
    1-5 competitor domains to compare against.
    domainstringrequired
    The target site whose keyword gaps you want. A bare domain covers all its subdomains; pass a subdomain to narrow to that property.
    languagestring
    Result language ("English", "Spanish").default English
    limitinteger
    Max gap keywords and max losing keywords to return (each).default 50
    locationstring
    Target market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
  • openrushmcp_describe_capabilitiesSTART HERE.Read-only

    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`.

    Inputs

    This tool takes no inputs.

  • openrushmcp_discover_ai_citationsWhich domains AI cites on a category — the map of where to earn a mention, and who AI cites instead of you.Read-only

    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.

    Inputs

    domainstring
    The brand's domain, used alone to derive the category from its top ranking keywords. One of `topic` / `domain` is required.
    languagestring
    Result language ("English", "Spanish").default English
    limitinteger
    No description.default 20
    locationstring
    Target market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
    topicstring
    The 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_competitorsFind organic competitors.Read-only

    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`.

    Inputs

    domainstring
    domain mode: the site to find competitors for. Pass this or `seed_keywords`; if both are given `seed_keywords` wins and this is ignored.
    languagestring
    Result language ("English", "Spanish").default English
    limitinteger
    No description.default 10
    locationstring
    Target market as a COUNTRY name ("United States", "Mexico"); sub-country values are rejected. Defaults to the United States.
    seed_keywordsstring
    seed_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_datasetFetch the full rows behind a dataset `uri` that another tool returned in its `resources` block (results too large to inline).Read-only

    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.

    Inputs

    uristringrequired
    A dataset uri from another tool's `resources` block.
  • openrushmcp_get_ad_performanceMeasured, 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.Read-only

    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.

    Inputs

    ad_accountstring
    An 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_tostring
    Comparison baseline: previous_period | previous_year | none.default previous_period
    filtersstring
    Up 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_bystring
    One dimension, any `report` token except overview. Overrides `report` when given — use `report` unless you are mapping a raw dimension name.
    limitinteger
    Maximum rows for a single-slice report.default 100
    periodstring
    Reporting window in the account's own time zone: last_7_days | last_28_days | last_3_months | last_6_months | last_12_months.default last_28_days
    platformstring
    Ad platform: google_ads. Omit it to auto-select when one platform is connected; a `platform_required` error lists the choices in `data.options`.
    reportstring
    Prebuilt 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.default overview