SEOmatic
您自己網站的SEO代理:在Claude、ChatGPT或Cursor中取得真實的Search Console、關鍵字、反向連結和AI能見度數據,加上需核准的修正功能。
文件
NEWCheck out our FREE templates →
SEOmatic's SEO MCP server is a hosted Model Context Protocol server that exposes SEOmatic's SEO tools to any MCP client: your Search Console data, site audits, AI visibility and approval-gated fixes. Connect over OAuth 2.1, or with a workspace API key as a Bearer token. Tools are annotated read-only or acting, and in hosts that support MCP Apps (ChatGPT, Claude) key tools render interactive UI right in the conversation: file upload, live scan progress, one-click connects, approval cards, and charts.
What makes this one different
It acts, with your approval
Most SEO MCP servers only read. Here, agents stage real fixes, you approve them (approval cards render right in the chat), and approved work executes on your live site within seconds, with the full pre-edit state stored so any edit to an existing page can be rolled back. By default every change waits for your approval; autonomy settings can let small reversible fixes go ahead on their own.
Honest about cost, before you call
Every tool description says whether it is free or bills AI credits. Reading your own data - tasks, evidence, Search Console, audits, AI visibility - is free and never triggers paid re-analysis, and get_credit_usage shows exactly where credits went.
Keeps working after the chat ends
An MCP chat stops when you close the window. SEOmatic's agents don't: diagnosis, planning, visibility scans and approved fixes run on schedule server-side. The chat is a window onto a team that is already working, and changes follow the approval rules you set.
Real UI inside the conversation
In ChatGPT and Claude, key tools render interactive widgets (MCP Apps): upload a CSV where the protocol has no file transport, watch a scan progress live, connect Search Console with one click, approve work with a button, read a trend as a chart. Where the host cannot render them, everything degrades to plain text.
MCP for SEO: what to ask
You do not call tools by hand. You ask your assistant a question in plain language, and it picks the tool. Some questions and the tool that answers each one:
| Ask your assistant | Tool it calls | Plan |
|---|---|---|
| How did my site do on Google this month? | gsc_performance (compare_periods) | Free |
| Which pages get impressions but few clicks? | gsc_insights (ctr_outliers) | Free |
| Are two of my pages competing for the same keyword? | gsc_insights (cannibalization) | Free |
| Is this page indexed, and if not, why? | gsc_indexing (inspect) | Free |
| Audit my site and rank the fixes by impact. | site_audit | Free |
| Do ChatGPT and Claude mention my brand? | get_ai_visibility | Free |
| What is the search volume and difficulty for these keywords? | keyword_research (metrics) | Paid |
| Stage new titles for my pages with the worst CTR. | task_manage (create) | Paid |
Guides per assistant, with prompts to paste: Claude SEO, ChatGPT SEO, Claude Code and Cursor.
Connection
| Field | Value |
|---|---|
| Endpoint | https://app.seomatic.ai/api/mcp |
| Transport | Streamable HTTP (stateless, POST JSON-RPC 2.0) |
| Protocol | 2026-07-28 (per-request _meta, server/discover) and 2024-11-05 through 2025-11-25 (initialize) |
| Extensions | MCP Apps (widgets), Tasks (long jobs), Events (draft: webhook delivery and events/poll) |
| Fewer tools | ?tools=essentials or ?toolsets=gsc,act,events on the endpoint URL |
| Server | seomatic v1.0.0 |
| Auth | OAuth 2.1 (interactive clients) or Authorization: Bearer smk_live_... |
| OAuth token lifetime | 30 days, with a refresh token for assistant connectors |
Install in your assistant (about a minute)
Fastest way: let your agent do it. Copy the prompt below, paste it into whichever AI you want connected, and send it. Agents that can edit config or run commands (Claude Code, Cursor, Cline, Devin) will install the server themselves. Chat assistants (Claude, ChatGPT, Gemini) cannot edit their own settings, so they hand you the exact clicks for their app instead.
copy this into your AI agent
Install the SEOmatic MCP server for me.
Server: https://app.seomatic.ai/api/mcp
Transport: Streamable HTTP (stateless JSON-RPC 2.0)
Auth: OAuth 2.1 - the client discovers it automatically, no API key needed.
(Headless setups can instead send: Authorization: Bearer smk_live_...)
What to do:
1. If you can edit MCP config or run commands in this client, install it
yourself now. Reference configs:
- Claude Code: claude mcp add --transport http seomatic https://app.seomatic.ai/api/mcp
- Cursor / Cline (mcp.json or settings JSON):
{ "mcpServers": { "seomatic": { "url": "https://app.seomatic.ai/api/mcp", "type": "streamableHttp" } } }
- Devin (uses serverUrl, not url):
{ "mcpServers": { "seomatic": { "type": "http", "serverUrl": "https://app.seomatic.ai/api/mcp" } } }
2. If you cannot, give me the exact clicks for THIS client instead
(for Claude: Settings, then Connectors, then Add custom connector with
the URL above; for ChatGPT Plus or higher: Plugins, then +, then Add
custom MCP server with the URL above, OAuth, Create as a plugin;
for the Gemini app: Settings, then Connected Apps, then Custom apps,
then Add a custom app with the URL above. Gemini custom apps need a
personal Google account in the US; elsewhere use Gemini CLI or
Antigravity, see the docs link below).
3. Tell me to finish the OAuth login when the SEOmatic screen appears, and
to pick the site I want connected.
4. In a NEW chat, check the tools menu and confirm SEOmatic is enabled for
that conversation (in the Gemini app, type @ and pick SEOmatic). This
step is the one people miss.
5. Then prove it works by calling tools/list and running one read-only tool,
and show me what came back.
Docs if you need them: https://seomatic.ai/developers/mcp
Prefer to do it by hand? Three steps, same everywhere: open your assistant's connector settings, paste the SEOmatic URL, then log in and pick your site when the SEOmatic screen appears. No API key to copy. After installing, one step people miss: in a NEW chat, open the tools menu in the message box and make sure SEOmatic is enabled for that conversation.
Two things that look like problems but are not: the consent screen asks you to log in or create a SEOmatic account (free works), and the connector is separate from any SEOmatic skill you may have installed. The skill needs the connector to reach your data.
Find your client:
Claude (web and desktop)
Requires: A Claude plan that allows custom connectors.
Settings -> Connectors -> Add custom connector
Name: SEOmatic
URL: https://app.seomatic.ai/api/mcp
Then click Connect and approve in the SEOmatic consent screen.
Full guide for Claude (web and desktop)
Claude Code
Requires: Nothing extra.
claude mcp add --transport http seomatic https://app.seomatic.ai/api/mcp
# then inside a session: /mcp -> seomatic -> Authenticate
ChatGPT
Requires: ChatGPT Plus or higher. Custom MCP plugins are not on the free plan.
Plugins -> + -> Add custom MCP server
Name: SEOmatic
URL: https://app.seomatic.ai/api/mcp
Auth: OAuth -> Create as a plugin, then approve in the SEOmatic consent screen.
(No "Add custom MCP server"? Settings -> Apps -> Advanced settings -> Developer mode)
On Business and Enterprise, an admin must allow custom MCP connectors first.
Meta Muse
Requires: A free SEOmatic account (you can create it during sign-in). Muse is available in the US.
Tell Muse:
"Add my SEOmatic connector: https://app.seomatic.ai/api/mcp,
MCP over HTTP with OAuth. Send me the sign-in link, save a
skill so SEO questions use SEOmatic first, then list my
workspaces."
Open the link, approve in the SEOmatic consent screen, done.
Prefer an API key? Store it in Muse's credential vault when Muse asks for it, never as a chat message. Muse renders results as text (it is not an MCP Apps host): every tool works, the interactive widgets simply do not apply. Muse asks you before anything that changes or spends.
Cursor
Requires: Nothing extra. Use OAuth, not an API key.
// ~/.cursor/mcp.json (or .cursor/mcp.json in one repo)
{
"mcpServers": {
"seomatic": { "url": "https://app.seomatic.ai/api/mcp" }
}
}
# or, from the Cursor Marketplace: /add-plugin seomatic
Cursor starts the OAuth flow and does not send a configured Authorization header, so pasting an API key here silently does nothing. Approve the browser prompt instead.
Cline
Requires: Nothing extra.
// settings JSON
{
"mcpServers": {
"seomatic": {
"url": "https://app.seomatic.ai/api/mcp",
"type": "streamableHttp",
"headers": { "Authorization": "Bearer smk_live_..." }
}
}
}
Agent-guided setup: point the agent at github.com/Minh42/seomatic-mcp.
Grok Bot (x.ai/bot)
Requires: An x.ai bot. Bearer fallback: create an API key in Settings, AI Agents, API Keys.
Ask the Bot (or open Plugins) to add a custom MCP server:
URL: https://app.seomatic.ai/api/mcp (Streamable HTTP, OAuth)
Token-only? Store an SEOmatic API key as a Bot secret,
sent as: Authorization: Bearer smk_live_...
# or: Connect apps -> search SEOmatic -> add -> Authorize
Full always-on template (instructions plus weekly routines): github.com/Minh42/seomatic-mcp/tree/main/grok-bot
Full guide for Grok Bot (x.ai/bot)
VS Code / GitHub Copilot
Requires: Copilot enabled in VS Code. Agent mode for tool calls.
// .vscode/mcp.json
{
"servers": {
"seomatic": {
"type": "http",
"url": "https://app.seomatic.ai/api/mcp"
}
}
}
Then open the Chat view in Agent mode and pick the SEOmatic tools. Sign in when prompted.
Full guide for VS Code / GitHub Copilot
Gemini app (gemini.google.com and mobile)
Requires: A personal Google account, 18 or over, in the US, with Gemini in English and Keep Activity on. Work or school accounts, and accounts outside the US, do not see the Custom apps section yet.
Settings -> Connected Apps -> Custom apps -> Add a custom app
URL: https://app.seomatic.ai/api/mcp
Next -> sign in to SEOmatic and pick your site
In a chat, type @ and pick SEOmatic so Gemini uses it.
The Gemini chat cannot add a server itself: pasting the setup prompt into Gemini only returns these clicks. Set it up on the web; the app then appears in the Gemini mobile app too. Outside the US or on a Workspace account, use Gemini CLI below or Antigravity (/ai-assistants/antigravity).
Full guide for Gemini app (gemini.google.com and mobile)
Gemini CLI
Requires: A Google Workspace account or a Gemini API key. Personal Google accounts moved to Antigravity.
gemini mcp add --transport http seomatic https://app.seomatic.ai/api/mcp
# or as an extension (server plus SEO context in one install):
gemini extensions install https://github.com/Minh42/seomatic-mcp
# headless or container? use a key instead of the browser flow:
gemini mcp add --transport http seomatic https://app.seomatic.ai/api/mcp \
--header "Authorization: Bearer smk_live_..."
Google retired Gemini CLI for personal (free, Pro and Ultra) accounts on June 18, 2026; Workspace and API-key users keep it, and personal accounts use Antigravity (/ai-assistants/antigravity). The OAuth flow needs a local browser and a localhost redirect, so it will not complete over SSH or inside a container. Use the Bearer form there.
Devin (Desktop and CLI)
Requires: A Devin plan. This is where Windsurf went.
// Devin uses serverUrl, NOT url
{
"mcpServers": {
"seomatic": {
"type": "http",
"serverUrl": "https://app.seomatic.ai/api/mcp"
}
}
}
Devin marks a server connected the moment the transport is up and only authenticates on the first tool call, so a connected badge is not proof of sign-in: that happens on the first call.
Full guide for Devin (Desktop and CLI)
Zed
Requires: Nothing extra.
// settings.json -> context_servers
{
"seomatic": {
"source": "custom",
"url": "https://app.seomatic.ai/api/mcp"
}
}
Setting an Authorization header here makes Zed skip the OAuth flow entirely. Use one or the other, never both.
Discovery follows the MCP spec: the endpoint returns 401 with a WWW-Authenticate pointing at /.well-known/oauth-protected-resource (RFC 9728), whose authorization server metadata lives at /.well-known/oauth-authorization-server (RFC 8414). PKCE (S256) is required; tokens are bound to this resource. Dynamic client registration and client-id metadata documents are both supported. Access tokens last 30 days, and assistant connectors also get a refresh token, so clients that support refresh renew without a new sign-in. After you upgrade and want the acting tools, reconnect the connector so the new token carries them. The metadata also lists the RFC 8628 device grant, which is reserved for the SEOmatic CLI.
Starter workflows (no typing required)
Once connected, the server ships three ready workflows. In Claude they appear in the prompt picker (the / menu or the plus button); other clients surface them wherever they list MCP prompts. Picking one is the fastest way to get a real answer out of your own data on day one.
| Prompt | What it does |
|---|---|
seo-audit | Run a complete, data-grounded SEO audit of the connected site and rank the fixes by impact. |
striking-distance | Find the keywords the connected site is one push away from ranking on page 1 for. |
traffic-drop | Work out why organic traffic dropped, who took the clicks, and what to fix first. |
Listing and expanding a prompt costs nothing: no credits, no free questions. Only the tool calls it then makes are metered. The server also exposes two static reference documents over resources/list that an agent can attach for context: seomatic://guides/connect (how to connect Search Console, Analytics, Ads, Business Profile and a CMS) and seomatic://guides/audit-method (the audit sequence the tools are built around). Neither contains workspace data.
Connect with an API key (headless)
For headless agents and clients that take a static token, mint a workspace API key and send it as a Bearer token. This is also how the Claude Messages API connector authenticates, via its authorization_token field.
Mint it under Settings → AI Agents → API Keys. The section needs the admin role on that workspace, so if you do not see it, check which workspace is selected and whether you are an admin on it rather than a member.
{
"mcpServers": {
"seomatic": {
"url": "https://app.seomatic.ai/api/mcp",
"headers": { "Authorization": "Bearer smk_live_..." }
}
}
}
Try it in 30 seconds (curl)
Two requests prove the whole surface: list the tools your key can call, then call one. The example reads your top Search Console queries, which costs no credits (on a free workspace it uses one question). Failures come back as isError results with a plain-language reason, never opaque transport errors.
curl -s https://app.seomatic.ai/api/mcp \
-H "Authorization: Bearer smk_live_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
call one (top Search Console queries)
curl -s https://app.seomatic.ai/api/mcp \
-H "Authorization: Bearer smk_live_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{
"name":"gsc_performance",
"arguments":{"action":"top_queries","days":28,"limit":10}}}'
Every successful call returns the payload twice: content (text, for every client) and structuredContent (a JSON object conforming to the declared outputSchema, for clients that want typed data).
Methods
| Method | What it does |
|---|---|
server/discover | 2026-07-28 clients: supported versions, capabilities (incl. the Apps, Tasks and Events extensions) and serverInfo. Answers without auth; with auth it also returns instructions for this key. |
initialize | Negotiate the protocol version and get serverInfo. Answers 200 without auth (version, capabilities, serverInfo only); with auth it also returns instructions for this key. |
tools/list | The scope-filtered tool roster this key can call. |
tools/call | Invoke a tool. Failures return as an isError result, not a transport error, so the agent can react. |
prompts/list | The starter workflows below. Free: no quota, no credits. |
prompts/get | Expand one prompt into the user message that triggers its tool flow. |
resources/list | The static guides plus the ui:// widget templates that MCP Apps hosts render. |
resources/read | Fetch one by URI. Same content for every caller: no workspace data. |
ping | Liveness check. Returns an empty result. |
notifications/initialized | Accepted and acknowledged with 202. No body, per the spec. |
events/list | Every event SEOmatic emits, with its filters (inputSchema) and data (payloadSchema). |
events/subscribe | Webhook subscription to one event: callback URL plus your whsec_ secret. The callback must echo a signed challenge first; returns id and refreshBefore. Refresh with the same arguments; send your last cursor to replay what you missed. |
events/unsubscribe | Stop a subscription, matched by event name, arguments and callback URL. Idempotent. |
events/poll | Events after a cursor (or within maxAgeMs), filtered by the event's arguments. |
tasks/get | Poll a task handle: working, completed (with the tool result), failed or cancelled. |
tasks/cancel | Ask a task to stop. Cooperative: a scan or article already running may still finish. |
What each key can call
The tools/list roster follows the key's scopes, with two deliberate exceptions so an agent can discover what is available. A free key also sees the acting tools, described as needing a paid plan: calling one returns the upgrade path instead of running. And while the workspace has no Search Console connection, the Search Console tools are listed as needing it: calling one returns the one-click connect link.
| Scope | Lane | Tools it unlocks |
|---|---|---|
read:gsc | Free | Direct Search Console reads. |
chat:ask | Free | All insight tools: GSC, keywords, backlinks, SERP, analytics, ads, Business Profile, datasets, templates. |
agents:act | Paid | The acting tools: SEO tasks, campaigns, bulk edits, blog authoring, skills. Works on any paid plan over MCP. |
Acting over MCP works on any paid plan; the same acting tools over the REST API require Infrastructure.
Interactive widgets (MCP Apps)
In hosts that support MCP Apps (ChatGPT and Claude), 9 tools render interactive UI directly in the conversation instead of describing what to do. Each widget exists because the protocol alone cannot do the job: MCP has no file transport, no navigation, and no way to show progress on async work. Hosts without MCP Apps support get the same tools with plain text results; nothing requires the widgets.
| Tool | What renders |
|---|---|
get_started | The site verdict and top 3 actions with their numbers, plus a one-click Search Console connect when it is missing. |
upload_csv | File picker that reads a CSV in your browser and stages it as a dataset - the file transport MCP itself lacks. |
run_ai_visibility_scan | Live scan progress that polls until results land, then renders per-engine visibility. |
generate_article | Article progress card that polls until the article is ready, with a buy button when prepaid units run out. |
show_connect_card | One-click connect buttons that open Search Console, Analytics, or CMS OAuth in your browser. |
show_approval_cards | Approve/Dismiss cards for proposed tasks and campaigns - the button click is the human decision. |
show_trust_facts_card | One-tap Confirm buttons for the business facts found on your own pages - confirmed facts are the only credentials the agents may claim. |
task_manage | A confirm card before any destructive execution, showing the exact target and consequence. |
gsc_performance | An inline clicks-and-impressions trend chart when a date breakdown is returned. |
Events: your agent hears when something changes
SEOmatic keeps a 30-day log of what happens in your workspace: a ranking that slipped, a fix waiting for your approval, a fix seen live on your page, AI answers gained or lost. Your agent can read that log, or SEOmatic can start your agent the moment it happens. The events tool lists the events, polls them and manages where they go; MCP Events clients use events/subscribe directly.
| Event | When it fires | Filters |
|---|---|---|
ranking.dropped | A query the site earns clicks on slipped in Google (Search Console average position, last 2 complete weeks against the 4 before), with the page, how much of the site's clicks it carries, who passed it when known, and the defense fix staged for approval. Checked daily for workspaces with the SEO agents on. | min_positions_lost, min_click_share |
site_audit.completed | A deep site audit finished: health score, pages crawled, issues by severity, and how many issues are new or fixed since the previous audit. | only_with_new_issues |
task.awaiting_approval | An agent staged a fix that runs once a person approves it. | type |
task.completed | An approved fix finished: whether it changed the site, and whether the change was already seen live. | type |
task.live | A change SEOmatic made was seen on the live page; its effect is now measured against its own baseline. | type |
ai_visibility.scan_completed | Per-engine visibility, plus the AI answers gained and lost since the previous scan and who is cited where you were lost. | only_with_changes |
campaign.completed | Every task in a page set, content sweep or bulk edit has finished. | none |
page.published | A generated page was published to your site. | project_id |
page.publish_failed | Publishing a generated page failed, with the reason. | project_id |
| Your agent | How events reach it |
|---|---|
| ChatGPT (Work chats and dots) | Native MCP Events: ChatGPT subscribes with events/subscribe and SEOmatic posts each event to it, signed (Standard Webhooks). Ask ChatGPT to watch for an event and say what to do when it arrives. |
| Claude Code routines | Add an API trigger to a routine, then ask your agent: "send fixes waiting for approval to my Claude routine" with the routine URL and token. Each event starts a run; write the routine prompt to act on the routine-fire-payload. |
| Grok Bot routines and Cursor Automations | Give the routine a webhook trigger, then ask your agent to send events to it with the webhook URL and its crsr_ key. The event arrives as the run's JSON input. |
| Any agent on a schedule (Claude Cowork, ChatGPT Tasks, Gemini CLI, Grok) | Start the scheduled prompt with "check SEOmatic events since my last run". The events tool returns what happened since that connection last asked, so nothing is missed between runs. |
| Zapier, n8n, Make, your own code | The same events as REST webhooks, signed with X-Seomatic-Signature (register them with the REST API, or with the events tool and kind webhook). |
MCP Events is a draft extension of the protocol (the MCP Triggers and Events working group); ChatGPT is the first client to support it. Event data carries facts and ids, never instructions: your prompt decides what happens next, and fixes still wait for your approval.
Long jobs as tasks
An AI visibility scan and an article take a few minutes. Clients that support the MCP Tasks extension get a task handle back and poll tasks/get until it completes; the completed task carries the same result the read tool returns. Other clients get the scan or article id and poll get_ai_visibility or get_article, as before.
Load fewer tools
Every tool definition takes room in your assistant's context before you ask anything. Add a query to the endpoint URL to load only what you use; calling a tool by name still works.
| Endpoint URL | Loads |
|---|---|
https://app.seomatic.ai/api/mcp | Every tool (the default). |
https://app.seomatic.ai/api/mcp?tools=essentials | Search Console, page checks and audits, the approval loop, cost estimates and events. |
https://app.seomatic.ai/api/mcp?toolsets=gsc,research,act | Any mix of: gsc, research, ai, site, act, analytics, strategy, data, trust, events, account. |
Tool reference (43 tools)
The server serves 43 tools: 19 consolidated outcome tools documented in this section, plus 24 single-purpose tools listed in the next one. Each consolidated tool takes an action that selects the operation. Every tool carries MCP annotations, so a client knows at a glance whether it only reads (readOnlyHint) or can stage a change. Nothing is destructive by default: acting tools stage proposals that follow your approval settings in SEOmatic. This reference is generated from the server's real catalog, so it is exactly what tools/list serves. Every tool is already scoped to the connected workspace and its site; the few tools that accept a domain default to your own site when it is omitted, and analyze a competitor when you pass one.
gsc_performanceRead-onlyFreeInteractive
Read Google Search Console performance (clicks, impressions, CTR, position) by query, page, dimension, or period comparison. Your own connected property; data is Google-finalized with a ~2-3 day lag. days/dates bound every action, and compare_periods contrasts the window with the one immediately before it. Queries for ONE page: dimension_breakdown with dimension=query and filterPage (that page's own numbers per query). Pages for ONE query: dimension_breakdown with dimension=page and filterQuery, or query_pages. The whole site's query-to-page map: query_page_matrix. Anything the preset cuts cannot express (2-3 dimensions together, regex or exclusion filters, a search type, fresh data, exact dates, paging past 1,000 rows): custom_query. For diagnosis (cannibalization, CTR outliers) use gsc_insights rather than recomputing here; for week-by-week position history use rank_tracking.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
top_queries | top search queries | days, limit |
top_pages | top pages | days, limit |
dimension_breakdown | by device/country/date, or one page's queries (query + filterPage) / one query's pages (page + filterQuery) | dimension*, days, filterQuery, filterPage, limit |
query_page_matrix | cannibalization / query-to-page map | days, maxRows |
query_pages | which pages rank for given queries, with each page's own numbers | queries*, page, days |
compare_periods | decay/growth vs the prior period | dimension, days, limit |
trend | daily clicks/impressions over time | days |
discover_news | Discover / News / Image / Video surfaces | surface, days |
folder_rollup | performance by URL folder / site section | days, depth |
fresh | provisional today/yesterday numbers (hours-old data) | none |
custom_query | flexible query: 1-3 dimensions, regex/exclusion filters, search type, fresh data, dates, paging to 25,000 rows | dimensions, filters, searchType, dataState, startDate, endDate, days, rowLimit, startRow, aggregationType |
Parameter details
days(number) Look-back window in days (defaults ~28). 1-90 for most actions; 7-90 for trend; custom_query up to 486 (about 16 months).limit(number) Row cap. top_queries/top_pages/dimension_breakdown default 50; compare_periods rows per period default 500. Ignored by query_page_matrix (use maxRows), trend and custom_query (use rowLimit).dimension(string) REQUIRED for dimension_breakdown: device|country|date|query|page (query + filterPage = the queries one page ranks for, with that page's own numbers; page + filterQuery = the pages ranking for one query). For compare_periods: query|page (default page). Ignored otherwise. One of: device, country, date, query, page.filterQuery(string) dimension_breakdown only: restrict to one exact query (pair with dimension=page to see which pages rank for it).filterPage(string) dimension_breakdown only: restrict to one exact page URL, as Search Console records it (pair with dimension=query to see the queries that page ranks for).maxRows(number) query_page_matrix only: max query-page pairs (100-1000, default 200).queries(array) REQUIRED for query_pages: 1-5 exact search queries. Page rows are that page's own numbers; queryTotal is site-wide and never a page's number.page(string) query_pages only: a full page URL to check - returns its own row for each query, or null when it does not rank.surface(string) discover_news only: which surface (default discover). One of: discover, news, image, video.depth(number) folder_rollup only: path depth to group by (1-3, default 1).dimensions(array) custom_query only: 1-3 dimensions to group by (default query).filters(array) custom_query only: filters applied together (AND). Regex is RE2 (no lookarounds). Country is a 3-letter code (usa); device is DESKTOP, MOBILE or TABLET.searchType(string) custom_query only: which search results (default web). Discover and googleNews report no queries. One of: web, image, video, news, discover, googleNews.dataState(string) custom_query only: final (default) or all (adds fresh data from the last 2-3 days, which can still change). One of: final, all.startDate(string) custom_query only: YYYY-MM-DD, with endDate (overrides days).endDate(string) custom_query only: YYYY-MM-DD, with startDate.rowLimit(integer) custom_query only: rows per page (1-25,000, default 1,000).startRow(integer) custom_query only: zero-based row offset; pass the nextStartRow a previous answer gave.aggregationType(string) custom_query only: auto (default), byPage or byProperty (not with the page dimension or a page filter). One of: auto, byPage, byProperty.
gsc_indexingRead-onlyFree
Check Google index status and coverage diagnostics for one URL or a batch of URLs (coverage state, crawl status, robots/canonical issues). Batch inspection caps at 50 URLs per call (Google allows ~2,000/day per property) and reports each URL independently - one failed URL never fails the batch. When Google answers slowly, the result is partial: it carries the finished URLs plus notChecked, the URLs to send in the next call.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
inspect | one URL, full diagnostics | url* |
batch_inspect | many URLs, summary each | urls* |
Parameter details
url(string) inspect only: the fully-qualified URL to inspect.urls(array) batch_inspect only: the URLs to inspect.
gsc_insightsRead-onlyFree
Derived analyses over your Search Console data: keyword cannibalization, brand vs non-brand split, CTR outliers (pages under-earning their position), rich-result appearance performance, 16-month seasonality verdicts, and sitemap health. Analyses read your captured Search Console history (finalized weekly), so verdicts lag live Google by a few days. Use gsc_performance for raw metrics; use this for the diagnosis layer.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
cannibalization | queries split across competing pages | days, minImpressions |
brand_split | brand vs non-brand performance | days, brandTerms |
ctr_outliers | pages under-earning their position (title/meta candidates) | days, minImpressions |
search_appearance | rich results / enhanced appearance breakdown | days |
seasonality | 16-month YoY verdict: real change vs seasonal dip | none |
sitemaps | sitemap errors, warnings, pending, staleness | none |
Parameter details
days(number) Look-back window in days (7-90, default 28).minImpressions(number) cannibalization/ctr_outliers: minimum impression volume to judge (defaults 100/200).brandTerms(array) brand_split only: brand words/variants, lowercase. Defaults to the domain name.
rank_trackingRead-onlyFree
Week-by-week ranking history from data SEOmatic already stores: Search Console position, clicks and impressions per week for chosen queries (default the target terms), the biggest weekly position gains and losses, and the true top-10 results page over time for one of the site's own queries, with competitor title changes. Search Console position is Google's impression-weighted weekly average, not one results-page rank; weeks run Monday to Sunday and every answer states them. Only the top 500 queries and pages are stored per week. For live numbers over any date range use gsc_performance.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
history | weekly position per query (target terms by default), up to 52 weeks | queries, weeks |
movers | biggest position gains and losses between two weeks | dimension, fromWeek, toWeek, minImpressions, limit |
serp_history | who held the top 10 each week for one of the site's own queries, and competitor title changes | query*, weeks |
Parameter details
queries(array) history only: up to 20 exact queries. Omit for the target terms (or the top 10 queries by impressions when none are set).weeks(integer) history/serp_history: complete weeks back (2-52, default 12).dimension(string) movers only: compare queries (default) or pages. One of: query, page.fromWeek(string) movers only: earlier week, any date in it (YYYY-MM-DD). Default: the week before toWeek.toWeek(string) movers only: later week, any date in it (YYYY-MM-DD). Default: the latest complete stored week.minImpressions(integer) movers only: minimum impressions in BOTH weeks for a move to count (default 20).limit(integer) movers only: rows per list (1-50, default 15).query(string) serp_history only (required): a target term or a query from the site's Search Console history.
keyword_researchRead-onlyBills AI credits
Research keyword demand: search volume, difficulty, CPC, and intent, plus keyword ideas, Google Trends interest and related queries, and Google Ads keyword performance. Volume and difficulty come from a live keyword vendor: a workspace without vendor credits gets an explanatory error with the path forward, never fabricated numbers. Use for what to target and how much demand exists; for who ranks today use serp_competitors.
Cost: metrics and suggestions bill AI credits (live vendor data at actual cost); trends, related_queries, compare and performance are FREE (Google Trends / your connected Google Ads).
| Action | What it does | Parameters |
|---|---|---|
metrics | volume/difficulty/CPC/intent | keywords* |
suggestions | keyword ideas from seeds | keywords*, limit |
compare_trends | Trends interest, keywords side by side | keywords* |
trend | Trends interest over time for one keyword | keyword* |
related | Trends related queries | keyword* |
ads_performance | Google Ads keyword performance | days, limit |
Parameter details
keywords(array) metrics/suggestions/compare_trends: the seed or target keywords.keyword(string) trend/related: the single keyword to analyze.days(number) ads_performance: look-back window in days.limit(number) suggestions/ads_performance: max results.
keyword_clustersRead-onlyFree
The agent's cached keyword-cluster map built from the workspace's GSC query universe (pillar, cannibalization, gap, and covered clusters). A stored lookup, not a recomputation: it reflects the last refresh and is empty until GSC history exists. For live demand numbers use keyword_research.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
list | none |
backlink_profileRead-onlyBills AI credits
Read the backlink profile of your own site or any competitor: referring domains, anchor-text distribution, link velocity, the individual links gained or lost since a date, and link-prospect intersects. Read from the link index at call time; a domain with no indexed links returns an empty profile, not an error. Use for authority and link questions; for rankings use serp_competitors.
Cost: bills AI credits per call (live vendor data at actual cost); reads of your own stored data elsewhere are free.
| Action | What it does | Parameters |
|---|---|---|
summary | totals, referring domains, rank/spam | domain |
anchors | anchor-text distribution | domain, limit |
velocity | monthly new vs lost referring domains | domain, months |
referring_domains | top linking domains | domain, limit |
new_lost_links | the individual links gained or lost since a date | domain, status, since, perDomain, limit |
link_prospects | link intersect: linking to competitors but not to us | competitors*, limit |
Parameter details
domain(string) The domain to analyze, e.g. "example.com". Omit it to analyze the connected workspace's own site (the server fills it in); pass it only to analyze a competitor.limit(number) anchors (default 25), referring_domains (default 50), new_lost_links (1-500, default 100).months(number) velocity only: months back (default 6).status(string) new_lost_links only: new (default) or lost links. One of: new, lost.since(string) new_lost_links only: YYYY-MM-DD, default 30 days ago.perDomain(boolean) new_lost_links only: true = one link per referring domain.competitors(array) link_prospects only: 1-3 competitor domains to intersect against.
serp_competitorsRead-onlyBills AI credits
Inspect the live search landscape: which SERP features (AI Overview, snippet, PAA, local pack, video) appear for a keyword, plus domain-level top rankings, visibility distribution, competitor domains, and a domain's top pages by estimated traffic. Results are fetched from the live SERP at call time, capped by limit per action. Use for who ranks and why; for keyword demand use keyword_research.
Cost: bills AI credits per call (live vendor data at actual cost); reads of your own stored data elsewhere are free.
| Action | What it does | Parameters |
|---|---|---|
features | which SERP features appear for a keyword | keywords* |
domain_rankings | top keywords a domain ranks for | domain, limit |
domain_overview | organic visibility distribution | domain |
domain_competitors | domains ranking for similar keywords | domain, limit |
top_pages | a domain's top pages by estimated organic traffic | domain, limit |
Parameter details
keywords(array) features only: the keyword(s) to inspect.domain(string) domain_rankings/domain_overview/domain_competitors/top_pages: the domain. Omit for the connected workspace's own site (the server fills it in); pass only for a competitor.limit(number) max results where applicable (top_pages 1-500, default 50).
ai_citationsRead-onlyFree
This site's OWN first-party AI-citation data, the part no scan can see. observed_citations: citations recorded in REAL logged-in AI answers (ChatGPT, Perplexity, Gemini, Copilot, Claude, AI Overviews) by the user's browser extension, with per-engine counts and best rank - engines personalize and gate their APIs, so a server-side scan sees a de-personalized view while this sees what a real human was shown. brand_facts: the canonical business facts this site publishes for AI engines, plus internal-link health; use them to spot an AI answer contradicting the owner's own declaration. Counts only, never prompt or answer text. scan_results reads the latest server-side SCAN instead: per-engine brand visibility, the prompts where the brand was MISSED and who won them, competitors, and the sources engines cite. Observed vs scanned is the key distinction - observed is what a real logged-in human saw, scanned is a clean de-personalized baseline comparable over time. For AI traffic per page use traffic_analytics.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
observed_citations | real logged-in AI answers that cited this site | days |
brand_facts | declared canonical facts + internal-link health | none |
scan_results | latest scan: per-engine visibility, missed prompts, competitors, cited sources | scanId |
Parameter details
days(number) look-back window in days (1-90, default 28).scanId(string) scan_results only: a specific scan id from recentScans. Omit for the latest completed scan.
traffic_analyticsRead-onlyFree
Google Analytics (GA4) traffic and Google Ads account, campaign, and search-term performance. overview/sources/landing_pages/top_pages read GA4 presets; ga4_report runs any GA4 report by API names (dimensions, metrics, date ranges, filters), realtime reads the last 30 minutes, and key_events gives key events (conversions) by landing page, source or channel; the ads_* actions read Google Ads - each names its missing connection instead of returning empty data. GA4 sessions and Search Console clicks measure different things: for search clicks use gsc_performance. ai_pages is first-party AI engagement (answer-crawler fetches and AI-referred visits per page) that GA4 cannot attribute - it files that traffic as "Direct".
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
overview | GA4 sessions/users/pageviews/bounce | days |
sources | GA4 sessions by channel | days |
landing_pages | GA4 top entry pages | days, limit |
top_pages | GA4 most-viewed pages | days, limit |
ads_account | Google Ads account totals | days |
ad_campaigns | Google Ads campaign performance | days, limit |
ads_search_terms | actual search terms that triggered Ads | days, limit |
ai_pages | first-party AI engagement per page: crawler fetches + AI-referred visits | days, limit |
ga4_report | custom GA4 report: up to 9 dimensions and 10 metrics by API name, date ranges, filters, ordering | dimensions, metrics*, dateRanges, days, filters, orderBys, limit, offset |
realtime | GA4 activity in the last 30 minutes | dimensions, metrics, filters, limit |
key_events | GA4 key events (conversions) by landing page, source or channel | by, eventName, days, limit |
Parameter details
days(number) look-back window in days.limit(number) max rows where applicable (ga4_report up to 10,000).dimensions(array) ga4_report (0-9) / realtime (0-4): GA4 dimension API names, e.g. sessionDefaultChannelGroup, landingPage, pagePath, deviceCategory, country, customEvent:<parameter>. Realtime default unifiedScreenName.metrics(array) ga4_report (required, 1-10) / realtime: GA4 metric API names, e.g. sessions, totalUsers, engagementRate, keyEvents, totalRevenue. Realtime default activeUsers.dateRanges(array) ga4_report only: up to 4 ranges; dates are YYYY-MM-DD, today, yesterday or NdaysAgo. Overrides days.filters(array) ga4_report/realtime: dimension filters applied together: field + value (matchType default exact) or values (in-list); not:true excludes matches.orderBys(array) ga4_report only: sort by requested metrics or dimensions (default first metric, descending).offset(integer) ga4_report only: row offset for paging (use nextOffset).by(string) key_events only: group by landing page (default), source / medium, or channel. One of: landing_page, source, channel.eventName(string) key_events only: one key event name (e.g. purchase, generate_lead); omit for all.
local_presenceRead-onlyBills AI credits
Read the local search presence of the connected business: Business Profile locations, local ranking for money keywords, and review ratings. Available actions depend on what is connected for this workspace. Use for local and map-pack questions; for national rankings use serp_competitors.
Cost: list_locations and reviews read your connected Business Profile and are FREE; visibility bills AI credits (live local SERP data at actual cost).
| Action | What it does | Parameters |
|---|---|---|
list_locations | GBP locations on the account | none |
visibility | local organic position for keywords | keywords* |
reviews | average rating + review count | location* |
Parameter details
keywords(array) visibility only: the money keywords to measure.location(string) reviews only: the Business Profile location id.
visibility_manageCan stage changesBills AI credits
Manage the workspace's AI-visibility monitor: list the tracked prompts scans ask every engine, add/edit/remove prompts, set the scan cadence, and choose which AI engines are tracked. Reads of scan RESULTS live in ai_citations action scan_results. Running a FRESH scan is not available over MCP; point the user at the dashboard. Config changes apply directly (no staging) but are plan-capped, and cadence and engines are spend levers - 'daily' multiplies recurring scan cost ~7x, each added engine adds its per-question cost; both need the user's explicit ask.
Cost: all actions are FREE config changes; each ACTIVE prompt raises the recurring scan cost when scans run, cadence 'daily' is ~7x weekly spend, and each tracked engine adds its per-question cost - disclose before setting.
| Action | What it does | Parameters |
|---|---|---|
list | tracked prompts + plan allowance + cadence | locationCode, languageCode |
add stages | track a new buyer question (plan-capped) | prompt*, locationCode, languageCode |
update stages | rename / pin / (de)activate a prompt | promptId*, text, pinned, active |
remove stages | delete a prompt permanently (confirm with the user) | promptId* |
set_cadence stages | weekly / daily / manual - daily is ~7x spend, explicit user ask only | cadence*, locationCode, languageCode |
set_engines stages | choose tracked AI engines (full list) or reset to defaults - each engine adds scan cost, quote it first | engines, reset, locationCode, languageCode |
Parameter details
prompt(string) add: the buyer question to track, in the customer voice.promptId(string) update/remove: the prompt id from list.text(string) update: new prompt wording.pinned(boolean) update: pin the prompt.active(boolean) update: false pauses scanning (keeps history), true re-activates (re-checks the plan cap).cadence(string) set_cadence: how often scans run. 'daily' ~7x weekly spend. One of: weekly, daily, manual.engines(array) set_engines: the FULL list of engine ids to track (see list for ids and per-engine cost).reset(boolean) set_engines: true tracks the default engines.locationCode(integer) Locale location code (default: primary monitor).languageCode(string) Locale language code, e.g. "en".
site_pagesRead-onlyFree
Analyze pages: on-page SEO score and critical issues for a URL, raw crawl metadata (title, meta, headings, links), Google PageSpeed lab and real-user field data, structured-data validation against Google rich-result rules, and the page inventory of the site. analyze, crawl, pagespeed and validate_schema fetch the LIVE page at call time (an unreachable URL returns the fetch error; pagespeed can take up to 45 seconds and has a daily allowance per workspace); inventory reads the stored index, synced daily, so brand-new pages can lag a day. Use for page-level diagnosis; for search performance of those pages use gsc_performance.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
score_draft | score a pasted DRAFT pre-publish (deterministic, free) | content*, contentType |
analyze | SEO score + critical issues | url* |
crawl | title/meta/headings/links | url* |
inventory | the user's real synced pages | limit |
pagespeed | Google PageSpeed now: lab metrics (score, LCP, CLS, TBT) and real-user field data (LCP, INP, CLS) | url*, strategy |
validate_schema | structured data vs Google rich-result rules: parse errors, missing required/recommended, wrong types (URL or pasted JSON-LD) | url, jsonld |
Parameter details
content(string) score_draft: the draft HTML or plain text/markdown.contentType(string) score_draft: guide|tutorial|listicle|review|roundup|comparison|case_study|research|opinion (default guide).url(string) analyze/crawl/pagespeed: the URL to inspect. validate_schema: the page to fetch (or pass jsonld instead).strategy(string) pagespeed only: mobile (default) or desktop. One of: mobile, desktop.jsonld(string) validate_schema only: raw JSON-LD (a JSON document or <script type="application/ld+json"> blocks) to validate instead of a URL.limit(integer) inventory only: max pages to return.
dataset_libraryRead-onlyFree
The dataset library and page templates that power programmatic pages: list datasets, sample rows, list templates, and read one template. Reads stored data as-is: sample rows are capped, and an empty library returns empty lists, not an error.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
find_page_set_patterns | keyword research for a page set: the repeated query templates with a varying slot, entities ranked by demand (a seed term adds the keyword provider and costs credits) | seed, minEntities |
list_datasets | available datasets | none |
list_page_projects | the site own page projects (own {{Column}} templates) | none |
dataset_rows | sample rows from one dataset | datasetId*, limit |
list_templates | built-in page templates | none |
get_template | one template in full | templateId* |
Parameter details
seed(string) find_page_set_patterns: a head term to research with the keyword provider ('signage'); omit for Search Console only.minEntities(integer) find_page_set_patterns: smallest set worth showing (default 5).datasetId(string) dataset_rows only: the dataset to sample.templateId(string) get_template only: the template to read.limit(integer) dataset_rows only: how many rows to sample.
strategy_insightsRead-onlyFree
The agent's cached diagnosis for this workspace: a compact snapshot, the current strategy, one raw signal in full, and AI-search content scores. Signals refresh nightly; the strategy itself updates on the agent's weekly cycle. A workspace the agent has never diagnosed says so rather than inventing one.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
snapshot | compact brief of cached signals | none |
strategy | themes + ranked big plays | none |
signal | one cached signal in full | signal* |
content_scores | AI-search scores for generated articles | none |
Parameter details
signal(string) signal only: which cached signal to read (e.g. index_coverage, backlink_profile).
task_manageCan stage changesBills AI creditsInteractive
The agent's full task lifecycle: read the plan board, stage proposals (create accepts up to 5 per call), approve/dismiss (decide), run approved tasks (execute), undo applied changes (rollback), and confirm a hand-pasted change (paste_done: SEOmatic looks for it on the live page before measuring). Staging never runs anything; every mutation is human-approval-gated - decide records the human's decision (auto-executable standalone tasks then dispatch within seconds; the response says whether they did), execute force-runs a task the instant path declined or releases held work with a staged-content reviewToken, rollback is drift-guarded.
Cost: list/get/create/decide are FREE (create only STAGES proposals, nothing runs). rollback is FREE but UNDOES a live change - it is an action, not a read. paste_done is FREE. execute runs the agent and bills AI credits when the work runs (a title/meta/H1 fix is typically a few hundred credits); approving auto-dispatches that run. Inspecting tasks, evidence and statuses never triggers re-analysis.
| Action | What it does | Parameters |
|---|---|---|
list | the plan board (filterable) | status, type |
get | one task in full detail | taskId* |
create stages | stage up to 5 task proposals | tasks* |
decide stages | approve or dismiss a staged proposal (the approval loop) | taskId*, decision*, confirmDestructive |
execute stages | run an approved task now; a reviewToken releases staged holds; refresh_pull_request updates an open GitHub pull request, or opens a new one if someone else changed its branch | taskId*, reviewToken, confirmDestructive, refresh_pull_request |
rollback stages | undo an executed task's live change (drift-guarded) | taskId*, force |
paste_done stages | the user pasted a handed-over change; SEOmatic looks for it on the live page before measuring | taskId* |
Parameter details
status(string) list only: filter by task status (proposed, approved,...).type(string) list only: filter by task type.taskId(string) get/decide/execute/rollback/paste_done: the task to act on.decision(string) decide only: approve releases the task to the gated pipeline; dismiss archives it. Approving an indexation-destructive type (noindex, redirect) also requires confirmDestructive: true. One of: approve, dismiss.confirmDestructive(boolean) decide/execute: required true for indexation-destructive types (noindex, redirect). Attestation that the human explicitly signed off on this specific task after seeing its URL and consequence - never set it on your own judgment.reviewToken(string) execute only: from get's stagedReview block. Releases a staged hold (first rewrite / money page); pass it ONLY after the human explicitly approved the staged content itself.refresh_pull_request(boolean) execute only, GitHub: rewrite the task's OPEN pull request against the site's latest version (the dashboard's Refresh): updates the pull request, or opens a new one if someone else changed its branch. Runs the task again, so it uses AI credits like the first run - set it ONLY when the user asked for the refresh.force(boolean) rollback only: undo even though the live page drifted from what the agent wrote. Set ONLY after the user explicitly confirmed overwriting their newer edit.tasks(array) create only: up to 5 task objects to stage as proposals (see the SEOmatic docs for the task shape).
eventsCan stage changesFree
What happened in this workspace and who hears about it. list: every event SEOmatic emits (fixes waiting for approval, fixes seen live, pages published, AI visibility scans with the answers gained and lost) with filters and fields. poll: events after a cursor, since a time, or since this connection last polled (start a scheduled run with it). wait: block up to 45 seconds for the next matching event. targets: register a Claude routine, a Grok Bot or Cursor routine, or a webhook that receives events so work starts when something happens; list, test or delete them. ChatGPT can also subscribe natively through MCP Events.
Cost: FREE - reads your connected/stored data, no AI credits.
| Action | What it does | Parameters |
|---|---|---|
list | the event catalog with filters and fields | none |
poll | events since a cursor, a time, or the last poll | cursor, since, names, limit |
wait | wait up to 45 s for the next matching event | names, filters, cursor, timeout_seconds |
targets stages | list / create / test / delete where events go (Claude routine, Grok Bot or Cursor routine, webhook) | targetAction*, kind, url, token, events, filters, id |
Parameter details
cursor(string) poll/wait: continue after this cursor (from a previous call or an event delivery).since(string) poll: ISO 8601 time; events at or after it.names(array) poll/wait: only these event names (see list).limit(integer) poll: max events (default 50, max 100).filters(object) wait (one event name) / targets create (one event): that event's filters, see list.timeout_seconds(integer) wait: seconds to wait (default 30, max 45).targetAction(string) targets: what to do with event targets. One of: list, create, test, delete.kind(string) targets create: where events go. One of: claude_routine, grok_routine, cursor_automation, webhook.url(string) targets create: the Claude routine /fire URL, the routine webhook URL, or an https URL.token(string) targets create, routine kinds: the routine API token or crsr_ key (stored encrypted, never shown again).events(array) targets create: which events to send.id(string) targets test/delete: the target id from targets list.
campaign_manageCan stage changesBills AI credits
Read campaigns and stage page-scale, content-sweep, or bulk-edit campaigns and blog articles. All staging is proposal-based and approval-gated; nothing publishes without the user.
Cost: list/get reads are FREE. Creating/approving a campaign bills AI credits per page only as the staged work actually executes; nothing is spent at staging time.
| Action | What it does | Parameters |
|---|---|---|
list | campaigns with status + task counts | status |
manage stages | approve/pause/resume/abandon/update a campaign | campaignId*, manageAction*, confirm, brief |
propose_page_scale stages | a set of pages on the site own page or own template | title*, kind*, brief*, exemplarUrl, projectId, rowSourceKind, rows, libraryDatasetId, rowTarget, allowGenText, publishAsDraft |
propose_location_pages stages | location pages on the site own layout (drafts), or existing ones improved | locationMode*, exemplarUrl, exemplarPlace, title, rows* |
propose_content_sweep stages | N distinct blog articles as a campaign | title*, topics*, brief |
propose_bulk_edit stages | one instruction across many pages | taskType*, instruction, title, selectorKind, urls, pathPrefix, segments, maxPages |
write_articles stages | direct N-article staging | topics*, autoPublish |
save_article stages | save a full article draft (pass title/content/slug) for one-click publish | title*, content*, slug*, excerpt*, metaTitle, metaDescription |
Parameter details
status(string) list only: filter campaigns by status. One of: proposed, approved, active, paused, done, abandoned.campaignId(string) manage only: the campaign to act on.manageAction(string) manage only: what to do to the campaign. approve releases the campaign to execution (the USER must have explicitly said yes first). One of: approve, pause, resume, abandon, update_brief.confirm(boolean) manage only, approve + abandon: must be true - attests the user explicitly asked for this (approve releases work + spend; abandon is irreversible).brief(string) manage+update_brief: replacement brief. Also propose_page_scale (template brief) and propose_content_sweep (shared direction).title(string) propose_page_scale (required), propose_content_sweep (required), propose_bulk_edit and propose_location_pages (optional).locationMode(string) propose_location_pages only (required): create = new draft pages modelled on exemplarUrl; enrich = rewrite existing location pages (rows carry pageUrl). One of: create, enrich.exemplarUrl(string) propose_location_pages (create) and propose_page_scale: the customer's own page the new pages copy (layout, embeds, page type). propose_page_scale needs exemplarUrl or projectId.projectId(string) propose_page_scale: the customer's own project whose fields hold their {{Column}} template. Needs projectId or exemplarUrl.exemplarPlace(string) propose_location_pages, create: the place the model page is about, when its title does not say.kind(string) propose_page_scale only (required): page kind, e.g. "location pages".rowSourceKind(string) propose_page_scale only: where page rows come from (required with exemplarUrl; with projectId defaults to the project dataset). No AI source: an invented row list is refused. One of: user, library, gbp_locations.rows(array) propose_page_scale, rowSourceKind=user: one object per page. propose_location_pages (required): one object per location (name + the facts the user gave; enrich: pageUrl).libraryDatasetId(string) propose_page_scale, rowSourceKind=library: dataset id to attach.rowTarget(integer) propose_page_scale only: target number of rows/pages.allowGenText(boolean) propose_page_scale only: allow per-row AI text (costs credits).publishAsDraft(boolean) propose_page_scale only: publish pages as drafts.topics(array) propose_content_sweep (required, up to 50) and write_articles (required, 2-50). One distinct article per topic.taskType(string) propose_bulk_edit only (required): the sweep type, e.g. ctr_fix, schema, content_refresh.instruction(string) propose_bulk_edit only: shared per-page brief.selectorKind(string) propose_bulk_edit only: how to select pages. One of: urls, path_prefix, all_pages.urls(array) propose_bulk_edit, selectorKind=urls: the pages.pathPrefix(string) propose_bulk_edit, selectorKind=path_prefix: the prefix.segments(array) propose_bulk_edit: advanced mixed-template selectors (overrides selectorKind/instruction).maxPages(integer) propose_bulk_edit only: cap the sweep size.autoPublish(boolean) write_articles only: default true (articles that pass our checks publish on their own, with undo); false keeps them as drafts.content(string) save_article only (required): full Markdown body.slug(string) save_article only (required): the URL slug.excerpt(string) save_article only (required): the excerpt.metaTitle(string) save_article only: meta title.metaDescription(string) save_article only: meta description.
site_audit_deepCan stage changesFree
Whole-site technical SEO audit that runs in the background: start crawls the workspace's own site from the homepage, sitemap and page inventory (default 500 pages, max 2000), obeying robots.txt, and returns a runId at once; status reads progress while it runs and, when done, the health score and every issue type found (status codes, redirect chains and loops, broken internal links, canonicals, noindex pages in the sitemap, duplicate or missing titles, metas and H1s, near-empty pages, slow server response, images without alt, hreflang return links, mixed content, robots-blocked sitemap URLs, orphan pages, click depth), with drill-down into one type, paged; compare lists new, fixed and persisting issues against the previous run; list shows the history (last 10 runs, 90 days). For a quick answer inside one call use site_audit (30 pages).
Cost: FREE - crawls with SEOmatic's own crawler in the background, no AI credits. start creates an audit run; nothing on the site changes.
| Action | What it does | Parameters |
|---|---|---|
start stages | start a background crawl (or get the one already running); returns runId | maxPages, urls |
status | progress while running; score + issues when done; issueType drills in (paged) | runId, issueType, page, pageSize |
compare | new / fixed / persisting issues vs the previous completed run | runId, baseRunId |
list | recent runs with score and issue counts | limit |
cancel stages | stop a queued or running audit (keeps partial results) | runId* |
Parameter details
maxPages(integer) start: most pages to crawl (default 500, max 2000).urls(array) start: list mode, audit exactly these pages of the workspace's own site and follow no links.runId(string) status/compare: the run (default newest; compare: newest completed). cancel (required): the run to stop.issueType(string) status only: drill into one issue type, as named in the results (e.g. broken_internal_link, duplicate_title).page(integer) status with issueType: page number (default 1).pageSize(integer) status with issueType: page size (default 25, max 100).baseRunId(string) compare only: the older run (default: the completed run before runId).limit(integer) list only: how many runs (default 10).
* = required for that action. The complete fine-grained tool list behind these, with each input schema, is in the REST reference.
Single-purpose tools (24)
Alongside the consolidated set, the server serves these single-purpose tools. They take direct parameters instead of an action, and the same annotations apply: read-only tools never change anything, and cost is stated per tool.
get_startedRead-onlyFreeInteractive
The first answer about your own site: whether Google can index it, Search Console clicks and the near-page-one queries worth pushing (when connected), market data in the site's own country, a one-line verdict, the top 3 actions ranked by impact with the numbers behind them, what could not be checked, and one next step. The same answer on free and paid plans.
Cost: FREE for the reads; the one market-data lookup uses the free monthly allowance or AI credits, like any keyword question.
get_ai_visibilityRead-onlyFree
Read the latest completed AI-search visibility scan: per-engine brand visibility (ChatGPT, Claude and Google AI Overviews by default, plus any engine the monitor tracks: Perplexity, Google AI Mode, Copilot, Gemini, Grok), the prompts where the brand was missed and who won them, top competitors, and the sources engines cite.
Cost: FREE - reads your connected/stored data, no AI credits.
run_ai_visibility_scanActs or spendsPaidInteractive
Start a fresh AI-search visibility scan: queries the live AI engines with buyer-intent prompts and measures whether the brand appears. Scans your own site by default, or any competitor domain via the domain parameter. Returns a scanId immediately; results arrive in a few minutes via get_ai_visibility. Limited to one assistant-triggered scan per hour.
Cost: bills AI credits from the workspace pool (comparable to generating a few articles). Reading an existing scan with get_ai_visibility is free.
site_auditRead-onlyFree
Site-wide technical SEO audit: crawls up to 30 pages and aggregates cross-page issues a single-page check cannot see - duplicate titles and metas, thin content, noindex leaks, canonical mismatches, slow pages, and broken internal links. For the whole site (up to 2000 pages, in the background, with history and comparison) use site_audit_deep.
Cost: FREE - crawls with SEOmatic’s own crawler at call time, no AI credits.
get_credit_usageRead-onlyFree
Where the workspace’s AI credits went in the current billing period: customer-language groups plus the raw per-feature ledger with event counts. Totals reconcile with the plan meter; refunds show as negative credits.
Cost: FREE - reads your connected/stored data, no AI credits.
estimate_costRead-onlyFree
What a tool call will cost before you make it: free, credits at the actual vendor cost (with the ceiling the product reserves), credits, or one prepaid unit, plus the remaining balance and, on the free plan, the free questions left. Pass the tool and action you plan to call.
Cost: FREE - reads your connected/stored data, no AI credits.
get_referral_linkRead-onlyFree
Your personal SEOmatic Refer and earn link and earnings: the share URL, how many people you referred and how many became paying, and your money rewards per currency (pending, ready, paid). Earn 25% of what they pay for 12 months, up to $500 per referral. They get 25% off their first 3 months. Nothing is earned at signup.
Cost: FREE - reads your connected/stored data, no AI credits.
generate_articleActs or spendsPaidInteractive
Write one in-depth SEO article on a topic, research-grounded against live rankings, quality-gated, delivered as markdown and HTML. Generation is async: returns an article_id to poll with get_article. With no prepaid units it returns the price and a buy link instead of failing.
Cost: consumes 1 prepaid pay-as-you-go article unit ($9 each, never expires); no subscription required.
get_articleRead-onlyFree
Fetch a pay-as-you-go article by id (poll after generate_article), or omit the id to list recent articles and the prepaid balance. A ready article carries both markdown and HTML.
Cost: FREE - reads your connected/stored data, no AI credits.
pay_for_articlesActs or spendsPaid
Pay for prepaid units with a Stripe Shared Payment Token, for agent platforms whose users approve spends in a Link wallet (Meta Muse, ChatGPT agentic checkout). Products: articles ($9, default), question packs ($5 for 50 assistant questions), AI-visibility scans of your own site ($19), and competitor scans ($19). The token is single-use and amount-capped by Stripe; prices are fixed server-side. Hosts that cannot mint SPTs use the buy links from the payment_required payloads instead.
Cost: charges the approved payment method (product-priced); consumes no AI credits.
upload_csvActs or spendsFreeInteractive
Stage CSV text so it can be imported as a dataset. Exists because MCP has no file transport: in MCP Apps hosts a file-picker widget reads the file in the browser and passes its text here, minting the same attachmentId a chat upload would. Pass that id to import_attachment_as_dataset.
Cost: FREE - stages the file text, no AI credits.
show_connect_cardRead-onlyFreeInteractive
Render inline one-click connect buttons for data sources the workspace has not linked yet (Search Console, Analytics, Ads, Business Profile, CMS). Already-connected integrations are filtered out server-side.
Cost: FREE - reads your connected/stored data, no AI credits.
show_trust_facts_cardRead-onlyFreeInteractive
Render the Trust Profile card: harvested-but-unconfirmed business facts with one-tap Confirm buttons (MCP Apps hosts), or an Open-settings link when the profile is empty. Confirmed facts are the only credentials/experience/review claims the agent's writers may make - an empty profile means humbler content, never invented authority.
Cost: FREE - reads your connected/stored data, no AI credits.
confirm_trust_factActs or spendsFree
Record the USER'S confirmation of one harvested trust fact, allowing writers to claim it. The click is the consent: call ONLY when the user explicitly confirmed that exact fact (the widget's Confirm button is the intended caller). Never confirm on your own judgment.
Cost: FREE - reads your connected/stored data, no AI credits.
get_trust_factsRead-onlyFree
The workspace's Trust Profile: the provenance-tracked, verifiable business facts (credentials, experience, awards, review counts, guarantees) the agent's writers are allowed to claim in E-E-A-T work, each with its source URL and confirmation status. An empty profile means the agent writes around trust claims rather than inventing them.
Cost: FREE - reads your connected/stored data, no AI credits.
import_attachment_as_datasetActs or spendsFree
Promote a spreadsheet uploaded in the conversation (CSV/Excel) into a private dataset in the workspace library, ready to drive a pages-at-scale campaign.
Cost: FREE - writes the dataset, no AI credits.
get_ai_crawler_activityRead-onlyFree
Which AI bots (GPTBot, ChatGPT-User, PerplexityBot, ClaudeBot and more) visited the site, classified by purpose (answer-time retrieval, AI-search indexing, model training), with per-bot trends, top crawled pages, and the crawl-to-citation funnel.
Cost: FREE - reads your connected/stored data, no AI credits.
get_trust_entitiesRead-onlyFree
The trust entities AI engines consult when answering questions about the market, mined from the actual fan-out queries scans capture. Every entity carries the cross of queried vs cited, surfacing the outreach list of sources engines check but never cite the brand from.
Cost: FREE - reads your connected/stored data, no AI credits.
get_ai_funnelRead-onlyFree
The full AI-search funnel per page, joined across three measurements: cited (engines named the page as a source), crawled (AI bots actually fetched it), and referred (GA4-measured assistant-referred visitors), with unmeasured columns flagged honestly rather than shown as zero.
Cost: FREE - reads your connected/stored data, no AI credits.
show_approval_cardsActs or spendsFreeInteractive
Render inline Approve/Dismiss cards for existing proposed tasks and campaigns, bringing the approval decision into the conversation instead of sending the user to the dashboard.
Cost: FREE - reads your connected/stored data, no AI credits.
get_task_rollbackRead-onlyFree
What the pipeline can restore for an executed task: every live edit stores the page’s full pre-edit state before writing. Returns which fields are recoverable, original embed code verbatim, and how to trigger the one-click restore.
Cost: FREE - reads your connected/stored data, no AI credits.
resume_page_publishingActs or spendsPaid
Resume a page campaign paused by the scale governor (the drip stops itself when the first published pages earn essentially no search appearances). Requires the resumeToken from the hold, so resuming is always an explicit, informed decision.
Cost: resuming is free; each released page bills AI credits as it generates and publishes, same as campaign execution.
Free tier limits
A free workspace gets 5 questions a month, one meter shared across SEOmatic chat, MCP, the REST tool bridge and the CLI. Only market-data lookups (keywords, search results, backlinks) and get_started are metered, and metered calls within 90 seconds of each other count as one question, up to 5 lookups. Search Console and site reads are free, and initialize, tools/list, prompts, resources and get_credit_usage never use a question. The first OAuth connect of a free workspace adds 10 bonus questions, and connecting Search Console adds 10 more, enough for a full first audit. When the questions run out, the call returns an isError result with the next step to relay: connecting Search Console when that bonus is still unclaimed, otherwise the ways to get more questions or upgrade. Paid workspaces are not question-metered.
Independent of plan, each key is rate-limited to 60 tool calls per minute and 1,000 per hour, enough for any real session and a backstop against runaway loops. To revoke access: remove the connector in your assistant, or revoke the key or OAuth grant in SEOmatic Settings. Either kills the connection immediately.
Troubleshooting
- The model asks for your domain. It never needs one: every tool is scoped to the connected workspace. Tell it to call the tool directly. Tools that accept a
domaindefault to your own site when it is omitted. - Acting tools marked as paid. Expected on a free workspace or a key without
agents:act: the acting tools are listed so the agent knows they exist, and calling one returns the upgrade path. They run on any paid plan. - Upgraded but tools still locked. An OAuth connection keeps the permissions it was granted, for its 30-day lifetime. Remove the connector and reconnect: the new consent grants
agents:act. With an API key, create a new key that includesagents:act. - Search Console tools say they need a connection. The workspace has no Search Console property linked. Calling any of them returns the one-click connect link.
- Acting tools missing on a paid plan. The SEO agent may be turned off for the workspace, or the connection an action needs (for example your CMS) is not set up. Check Settings in SEOmatic, then reconnect.
- Wrong workspace connected. The OAuth grant is scoped to the one workspace you picked at consent. Remove the connector and reconnect, choosing the right workspace.
- Want a guided audit? Install the free SEO audit skill alongside the connector: it walks your assistant through a full, methodical audit of your site instead of ad-hoc questions. All 20 skills, from traffic drops to client reports: SEO agent skills.
- Tool failures. Failures come back as
isErrorresults with a plain-language reason the model can act on, never as opaque transport errors.
FAQ
What is an SEO MCP server?
An MCP server gives AI assistants tools they can call over the Model Context Protocol. An SEO MCP server gives them SEO tools. SEOmatic's reads your own Search Console data, audits your pages and checks your AI visibility, and on paid plans stages fixes on your site for you to approve.
Which MCP clients does it work with?
Any client that supports remote MCP servers over Streamable HTTP. This page has setup steps for Claude, ChatGPT, the Gemini app, Claude Code, Cursor, GitHub Copilot, Gemini CLI, Devin, Cline, Zed and others. Clients that sign in with OAuth need no API key; headless clients send a workspace key as a Bearer token.
Is the SEO MCP server free?
Connecting is free, and a free workspace gets 5 questions a month, where one message to your assistant uses at most one (only keyword, search result and backlink lookups count; your own Search Console and site data are free), plus bonus questions for the first connect and for connecting Search Console. Paid plans remove the limit and unlock the tools that stage changes. Each tool says whether it is free or bills AI credits.
Can the MCP server change my website?
Only on a paid plan, and only by staging proposals. Each staged change follows the approval rules you set in SEOmatic: by default it waits for your approval, the page's previous state is stored, and an applied edit can be rolled back.
How is it different from other SEO MCP servers?
Most SEO MCP servers only read data. This one also acts, with your approval: agents stage real fixes, you approve them in the chat, and approved work goes live on your site through your connected CMS. It also keeps working after the chat ends, because diagnosis, planning and scans run on schedule in SEOmatic.

Each local area page used to take us half a day to create and optimize.
With SEOmatic, we can create hundreds of pages in the same time, which helps our clients make the best use of their budget.
It's transformed how we deliver scalable SEO solutions.
Will Hawkins
Marketing Director, Digi-Business UK
Give Your Site an SEO Team
Agents read your Search Console data, do the work, and prove what actually moved. You decide what ships.
14-Day Free Trial. $1 today, credited to your first payment.