MCP tools

The SEOAIO MCP server exposes 17 tools over the HTTP transport at https://app.seoaio.ai/api/mcp. Per-customer authentication is required; nothing is exposed without it.

The only writes are propose_competitor, propose_fact, propose_measurement, propose_prompt and propose_remove_competitor, and every one of them queues a change request for a human to approve rather than changing anything. Nothing here sends email, charges a card, edits your site, or spends money on an engine call.

Call order

  1. list_assets to get an assetId. Never invent one.
  2. get_measurement_status: how fresh the data is, whether anything is queued or running, and which proposals already await approval.
  3. The read tools, as needed. Every share arrives with its n and interval.
  4. A propose_* tool only for a change the user asked for, and only after checking nothing identical is pending. A person approves it at https://app.seoaio.ai/dashboard/requests.

Read tools (12)

Every share comes back with its sample size and a 95% Wilson interval, and every value with a provenance of measured, estimated or derived. A pillar that was not measured says so rather than returning zero.

  • get_answer_share

    Get the north-star Answer Share for an asset (share of AI-engine answers citing the brand), aggregate + per engine, each with provenance (measured / estimated / mixed).

  • get_citation_metrics

    Citation headline metrics for an asset over a trailing window: total citations, cited-run counts and owned-citation counts from real engine answers. Raw measured aggregates; absent inputs mean not measured.

  • get_crawler_activity

    Observed AI-crawler hits on an asset over the last 30 days (FI-262): which bots fetched which pages, aggregated per day. Real server-reported hits, never estimated; empty means no collector data, not zero traffic.

  • get_measurement_status

    How fresh an asset's data is and whether anything is in flight: the age of the latest analysis and citation snapshots, the last real answer per engine, jobs queued or running now, and the change requests already waiting for a human. Call it before quoting a number as current, and before proposing anything, so you do not propose the same thing twice. A null snapshot means not measured, never zero.

  • get_visibility_score

    Get the latest Visibility Score for an asset, with its component breakdown and each value's provenance (measured / estimated / derived).

  • list_assets

    List the Visibility Assets in YOUR organization, with their id and hostname. Call this first: every other tool needs an assetId.

  • list_cited_passages

    The passages AI engines actually quoted from the brand's own pages in sampled answers: passage, URL, title, how many times it was quoted, on which engines, best position. Most quoted first. This is what engines quote FROM you; how they describe you in their own words is not stored, so it is not measured here.

  • list_competitors

    The competitors tracked on an asset and, per engine, how many sampled answers cited the rival where the brand was not cited, as a share with its n and Wilson interval. Call it before propose_competitor, so you do not propose one that is already tracked. An empty list is a fact about the tracked set, not a measurement.

  • list_findings

    List the findings from the latest analysis of an asset (what is happening and why).

  • list_prompt_outcomes

    Per tracked question, what the engines did in the current sweep: cited (used one of your pages as a source), named (mentioned you, sourced elsewhere), category-only (answered the category and named a competitor instead of you) or absent. Each question carries n (answers pooled), the counts, the cited share with its Wilson interval, and the split per engine. Worst first, so the questions you lose come first. No sweep means not measured, never zero.

  • list_recommendations

    List the ranked Action Plan for an asset: each recommendation with its Predicted Visibility Gain, confidence, and status.

  • list_sources

    The domains and pages AI answers cite for this asset's questions inside a trailing window, yours and everyone else's: classification (target_owned, competitor_owned, neutral_third_party, unknown), citations, the answers citing the domain as a share of sampled answers with n and a Wilson interval, a URL, a title, best position, engines. Most cited first. Filters: a domain substring, a classification. No sampled answer in the window means not measured, never zero.

Propose tools (5)

5 of them, and none of them changes anything on its own. Each queues a change request for a human to approve.

  • propose_competitor

    Propose adding a competitor domain to this asset's tracked set. QUEUES A REQUEST FOR HUMAN APPROVAL; it does not add the competitor. Returns applied:false and a change-request id.

  • propose_fact

    Propose an owner-declared fact for Answer Accuracy to check AI answers against (e.g. a price, a founding year, a service area). QUEUES A REQUEST FOR HUMAN APPROVAL. A fact nobody with authority confirmed is not a fact.

  • propose_measurement

    Propose running a fresh measurement for this asset. QUEUES A REQUEST FOR HUMAN APPROVAL; it does not start a run. A sweep spends real money with AI vendors, so a person decides.

  • propose_prompt

    Propose adding a prompt to the sampled set for this asset. QUEUES A REQUEST FOR HUMAN APPROVAL. Prompts cost money to run on every sweep, which is part of why a person decides.

  • propose_remove_competitor

    Propose removing a competitor from this asset's tracked set. QUEUES A REQUEST FOR HUMAN APPROVAL; it does not remove anything.

When to use which

ToolUse it whenDo not use it when
get_answer_shareYou need the share of sampled AI answers that cite the brand, with its evidence.You need which questions are lost; that is list_prompt_outcomes.
get_citation_metricsYou need raw citation counts over a trailing window.You need a share with an interval; counts here are aggregates, not proportions.
get_crawler_activityYou need to know which AI crawlers actually fetched the site.The site has no collector installed; the tool will say the activity is not measured.
get_measurement_statusBefore quoting any number as current, and before proposing anything.You need the numbers themselves; they live on the tools that measure them.
get_visibility_scoreYou need the composite, or the reason it is held, with each pillar's provenance.You need what to change; that is list_findings and list_recommendations.
list_assetsYou need an assetId, or you are in a new conversation.You already hold a confirmed assetId from this conversation.
list_cited_passagesYou need the passages engines actually quoted from the brand's own pages.You need how engines describe the brand in their own words; that text is not stored, so it is not measured here.
list_competitorsYou need the tracked rivals, and how often each is cited where the brand is not.You are about to invent a competitor name, or to propose one without checking it is not already tracked.
list_findingsYou need what is happening on the site and why, from the latest analysis.You need a number; findings carry severity and impact, not scores.
list_prompt_outcomesYou need to know which tracked questions the brand loses, and on which engine.You need one headline share; that is get_answer_share.
list_recommendationsYou need what to change next, ranked by predicted gain.You need proof that a change worked; that is a fresh measurement, not a prediction.
list_sourcesYou need which domains and pages AI answers cite for this site's questions, yours and everyone else's.You need a headline share; that is get_answer_share. You need what was quoted from you; that is list_cited_passages.
propose_competitorThe user asked to track a specific competitor domain, and list_competitors shows it is not tracked yet.You are guessing who the competitors might be.
propose_factThe user stated a fact about their business that AI answers should be checked against.You inferred the fact yourself; a fact nobody with authority confirmed is not a fact.
propose_measurementThe user changed something and wants it measured, or asked for a fresh run.A run is already queued or running; check get_measurement_status first.
propose_promptThe user asked to track a specific question.You want more data; every prompt costs money on every sweep, so a person decides.
propose_remove_competitorThe user asked to stop tracking a specific competitor.A competitor merely looks irrelevant to you.

What every result carries

dataStatus, one vocabulary on every tool, beside the specific fields; and on every read, an href to the dashboard page that holds the evidence, for the right site.

dataStatusMeaning
okThere is at least one result, or a measured zero.
not_measuredNo measurement of this kind exists yet for the asset. Not zero, and not a broken connection.
empty_filterData exists, and the filter you passed matched none of it. Retry without the filter.
queuedA propose tool queued a change request for a person; nothing has changed.

Errors that apply to every tool

Quoted from the code that sends them. A request without a valid credential answers 401 with the message below; that first 401 is how an MCP client starts OAuth, not a failure.

Unauthorized. Present a SEOAIO API key or an OAuth access token as a Bearer token. MCP clients: start OAuth from the resource_metadata URL in the WWW-Authenticate header.
WhenMessageOn the wire
The assetId is not one of yours, or does not exist. Both cases read the same, and the message names your own sites.Asset not found. Call list_assets and use one of its ids. Your sites: example.com.tools/call result with isError: true
A tool name the server does not have. The list from tools/list is complete.Unknown tool: get_historyJSON-RPC error -32602
A JSON-RPC method the server does not implement, such as a subscribe.Method not found: resources/subscribeJSON-RPC error -32601
A required argument is missing.Error: assetId (string) is requiredtools/call result with isError: true

Empty results are not errors: a null block is a measurement that does not exist yet. The rest is on the troubleshooting page.