siteline Start free trial Log in

SiteLine MCP setup for AI coding agents

See your data

SiteLine MCP is included on every paid plan. You are not installing a local Python server. You are pointing an MCP client at two HTTPS endpoints that already hold your imported Search Console and cookieless analytics.

This is the setup page. The public overview is /mcp. What the Google Search Console MCP server returns, tool by tool: Google Search Console MCP server. Call order and prompts: how to query Search Console with MCP. The agent-workflow argument is SEO analytics for AI agents. Client pages: ChatGPT, Claude Desktop.

Client config used to be split across twelve short pages. It lives here now, one section per client: Cursor, Claude Code, Claude, ChatGPT, OpenAI Codex, Grok, Windsurf, GitHub Copilot, Continue, Aider, Gemini CLI, and Cline. The product does not change between those sections. The config filename, the transport key, and OAuth versus a bearer token do. If you bookmarked one of those client pages, use the matching heading on this page.

Before you connect an agent

  1. Register. The trial is 7 days with no card to start. Add a card at checkout before it ends if you want to keep the subscription. Pricing.
  2. Connect Search Console with webmasters.readonly. Wait for the 16-month backfill; get-import-status will say if it is still running.
  3. Enable analytics on the same domain, allowlist hostnames, install the script or React SDK. Confirm Live.
  4. Open Settings → MCP access (/settings/api-tokens). That screen is the source of truth for URLs and tokens.

Without step 2 the Search Console server has nothing to list. Without step 3 the analytics server has empty overviews. You can connect MCP anyway; the tools will be honest about empty sites.

Two servers, not one

Server URL Units
Search Console https://siteline.tools/mcp/search-console clicks, impressions, CTR, position, query, page
Analytics https://siteline.tools/mcp/analytics pageviews, visitor-days, events, goals, realtime

These are two servers and two unit systems. A click is a Google-reported search click, usually about two days late. A pageview is a first-party event from a browser that ran the tracker. A visitor-day is a daily hash of that browser, and it resets the next day. Do not equate visitors with clicks. Do not subtract one from the other and call the gap “leakage,” “bounce,” or “untracked organic.” Mixing the integers in one answer is how a click becomes a session in the write-up.

The settings page currently highlights the Search Console URL because that is the connector most people add first. Add the analytics URL as a second server in the client. One OAuth grant or one bearer token can authorise both. The host, the tool list, and the units stay separate. If you only add Search Console, the agent will invent on-site numbers. If you only add analytics, it will invent queries.

Path A — OAuth (Claude.ai, ChatGPT, Grok connectors)

Use this when the app has a “custom connector” / “MCP” UI and a browser.

  1. Copy the server URL from MCP access (Search Console first).
  2. In the assistant, add a custom connector and paste the URL.
  3. Approve the OAuth screen back on SiteLine. The app appears under Connected apps. Revoke there when you are done.
  4. Repeat for https://siteline.tools/mcp/analytics if you want on-site numbers.

Exact menu names move. Look for Connectors, Custom connector, or Add MCP server. SiteLine registers OAuth clients dynamically; you do not paste a client id by hand. Do not paste a bearer token into the chat transcript. That transcript is the wrong secret store. Bearer tokens are the IDE path below.

Grok’s bring-your-own MCP at grok.com/connectors wants a public HTTPS URL. SiteLine already is one. Do not tunnel localhost.

Path B — Bearer token (Cursor, Claude Code, Codex, Copilot, Windsurf, Continue, Gemini CLI, Cline)

Use this when the client cannot finish an OAuth dance, or when you want a token sitting in a config file.

  1. On MCP access, name the token (Cursor, Claude Code) and pick the team. Create it. Copy it once.
  2. The token is scoped to that team. It does not follow current_team_id in the browser. It cannot see another team’s sites.
  3. Put it in the client’s MCP config as Authorization: Bearer …. Prefer an env var over a committed secret. In the examples on this page the literal placeholder is YOUR_TOKEN.

Claude Code example (replace the token; check claude mcp add --help on your version):

claude mcp add --transport http siteline https://siteline.tools/mcp/search-console \
  --header "Authorization: Bearer YOUR_TOKEN"

Add a second command for https://siteline.tools/mcp/analytics with a different server name (siteline-analytics). The full pair is in the Claude Code section.

Cursor / Claude Desktop JSON shape, which several other IDEs almost copy and then reject:

{
    "mcpServers": {
        "siteline": {
            "type": "http",
            "url": "https://siteline.tools/mcp/search-console",
            "headers": {
                "Authorization": "Bearer YOUR_TOKEN"
            }
        },
        "siteline-analytics": {
            "type": "http",
            "url": "https://siteline.tools/mcp/analytics",
            "headers": {
                "Authorization": "Bearer YOUR_TOKEN"
            }
        }
    }
}

That block is right for Cursor. It is the wrong paste for Windsurf (serverUrl), Continue (YAML streamable-http), Cline (type: streamableHttp), GitHub Copilot (.vscode/mcp.json with a servers key), OpenAI Codex (config.toml and bearer_token_env_var), and Gemini CLI (gemini mcp add or httpUrl). Those dialects are the sections below. Longer wiring notes that are not this page: Cursor, Claude.

Sanity-check with curl if the IDE fails closed. This proves the token and the URL before you debug a client’s JSON:

curl -X POST https://siteline.tools/mcp/search-console \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

You should see list-sites, get-site-overview, and the rest. A 401 is a bad token. A 402 is a lapsed subscription — billing — not a cue to retry. A client that omits Accept: application/json, text/event-stream can get a 406 against streamable HTTP even when this curl succeeds. Repeat the call against https://siteline.tools/mcp/analytics if the analytics tools are the ones missing. A Search Console tools/list will never include get-analytics-overview.

Cursor

Cursor is an editor whose agent can apply the patch. It does not use the Claude.ai OAuth connector. It wants the bearer JSON in the previous section: mcpServers, type: http, url, and Authorization: Bearer YOUR_TOKEN, twice — siteline on https://siteline.tools/mcp/search-console and siteline-analytics on https://siteline.tools/mcp/analytics.

Grok, Claude, and GPT inside Cursor share that file. The model picker changes the weights. It does not change the MCP servers. If the thing you call “Cursor” is actually Grok on grok.com, that is the Grok section: a different credential UI, the same two SiteLine hosts.

Cursor’s win is the diff, not a strategy deck. After get-movers and a page breakdown, it should open the template that owns the path. It must not “request indexing.” There is no Cursor plugin to install. The npm packages are the tracker, not an IDE extension. Field-by-field wiring, including the project-rules prompt, is MCP for Search Console and analytics in Cursor.

Claude Code

Claude Code lives in the terminal and the working tree. It will not pick up a Claude.ai connector. Add both servers with the CLI, and check claude mcp add --help because the flags move:

claude mcp add --transport http siteline https://siteline.tools/mcp/search-console \
  --header "Authorization: Bearer YOUR_TOKEN"
claude mcp add --transport http siteline-analytics https://siteline.tools/mcp/analytics \
  --header "Authorization: Bearer YOUR_TOKEN"

Put the token in an environment variable rather than a committed .claude.json when the build allows it. SiteLine does not replace Claude’s other MCP servers (GitHub, docs, Sentry). It replaces the screenshot you were pasting into the prompt.

A Claude Code loop that matches the tool: get-import-status, then get-site-overview on closed dates, then get-queries-for-page for the URL you are about to touch, then search the repo and edit. get-analytics-realtime only tells you the tracker still fires after deploy. Judge SEO on the next closed Search Console days, not on Live. Put the refusal in CLAUDE.md: totals from overview, never average position or CTR, and do not equate visitors with clicks. Claude.ai, which has no repo and uses OAuth, is the Claude section. Both credential stores are described in Claude connector for Search Console and analytics.

Claude

Claude.ai and Claude Desktop are chat clients with connectors, not IDEs. The path is OAuth, not a personal access token in the transcript.

Copy https://siteline.tools/mcp/search-console from Settings → MCP access. In Claude, add a custom connector, paste the URL, and approve the SiteLine screen. Repeat for https://siteline.tools/mcp/analytics. Revoke under Connected apps. You do not mint a client id; SiteLine uses dynamic client registration. Menu labels move; look for Connectors.

Claude for Work or Team still means a custom connector under that host’s admin rules. SiteLine scopes data to the OAuth user’s team, not to the Claude workspace name you typed. The connector cannot submit sitemaps. The Google scope is webmasters.readonly.

Use this client for the briefing: name the query, the URL, and data_through. Use Claude Code or Cursor for the patch. Do not expect the web connector to appear in the CLI, and do not expect SiteLine to grow a “publish to the CMS” write tool. ChatGPT’s menu is a different OAuth screen for the same two URLs: ChatGPT. Desktop-only click path: Claude Desktop Search Console MCP.

ChatGPT

ChatGPT’s path is an OAuth custom connector, the same family as Claude.ai. It is not a Codex config.toml, and it is not a Sanctum token pasted into the composer.

  1. On SiteLine Settings → MCP access, copy https://siteline.tools/mcp/search-console.
  2. In ChatGPT, add a custom connector. The menu has been called Connectors, Apps, or Developer Mode depending on plan and week.
  3. Paste the URL. Finish the SiteLine OAuth screen. The app is listed under Connected apps.
  4. Add https://siteline.tools/mcp/analytics as a second connector when you want pageviews and goals.

Connector availability depends on the ChatGPT plan. SiteLine cannot change that. If the UI has nowhere to add a remote MCP, a token in the chat is not the workaround. Use Cursor or Claude Code for that credential, or wait until the plan exposes connectors.

ChatGPT is a good place for a monthly narrative from get-movers plus get-site-overview, and for a cannibalisation list from get-pages-for-query. It is a bad place to apply the git patch. Hand the URL list to Cursor or Claude Code. It will also try to invent one organic-traffic number. Refuse that. Two servers, two units. This connector does not rank you inside ChatGPT answers; it lets ChatGPT read your Search Console and your tracker. The CLI on the same OpenAI account is OpenAI Codex. The connector-only write-up is ChatGPT Search Console MCP.

OpenAI Codex

OpenAI Codex — the CLI, the IDE extension, and the coding host inside ChatGPT desktop — is an agent on your files. ChatGPT-the-chat-app is not. Codex wants streamable HTTP in config.toml, with the bearer token in an environment variable, or OAuth via codex mcp login when that path completes.

[mcp_servers.siteline]
url = "https://siteline.tools/mcp/search-console"
bearer_token_env_var = "SITELINE_MCP_TOKEN"

[mcp_servers.siteline_analytics]
url = "https://siteline.tools/mcp/analytics"
bearer_token_env_var = "SITELINE_MCP_TOKEN"

Or, after you confirm codex mcp add --help:

codex mcp add siteline --url https://siteline.tools/mcp/search-console --bearer-token-env-var SITELINE_MCP_TOKEN

Run the same shape again for siteline_analytics and https://siteline.tools/mcp/analytics. codex mcp list, or /mcp inside a session, shows whether the tools loaded. Restart the session after you edit the file.

Do not mix command (stdio) and url in one table. SiteLine is remote HTTP, not an npx child process. OpenAI documents a shared Codex host config across desktop, CLI, and the IDE extension; verify that on your build. A Claude.ai connector still will not appear here. Codex can open the route file after get-queries-for-page. It cannot request indexing. The chat connector for the same company is ChatGPT.

Grok

“Grok” is a model, a grok.com assistant, and often the model picker inside Cursor. Those are not the same client. The two SiteLine URLs do not change. The credential UI does.

Grok on grok.com. xAI’s bring-your-own MCP needs a URL the Grok backend can reach on the public internet. Paste https://siteline.tools/mcp/search-console. Do not ngrok a laptop, and do not run a local MCP just to reach SiteLine. In grok.com/connectors: New Connector, then Custom, paste the URL, and finish whatever auth the host prompts — OAuth when the client can complete SiteLine’s authorization server, otherwise a token if that UI allows headers. Repeat for https://siteline.tools/mcp/analytics.

Grok inside Cursor or another IDE. Grok is only the weights. MCP is the IDE’s. Use the Cursor JSON and a SiteLine bearer token. You do not add a second “Grok MCP” for SiteLine.

If a Grok surface has no custom MCP at all, it cannot query SiteLine. The X app’s search box is not Search Console. SiteLine is not an X analytics product and not Grok’s Google Workspace connectors. Revoke the connector on SiteLine MCP access when you are done. Hosted SiteLine does not need a tunnel.

Windsurf

Windsurf’s Cascade agent edits the repo. Its remote-HTTP key is serverUrl, not Cursor’s type plus url. Some builds also accept url. Copying the Cursor block is the usual reason Cascade never connects.

Token from Settings → MCP access. Prefer ${env:SITELINE_MCP_TOKEN} when the build interpolates headers. The secret is still the bearer you would otherwise write as YOUR_TOKEN, including the literal Bearer prefix.

{
    "mcpServers": {
        "siteline": {
            "serverUrl": "https://siteline.tools/mcp/search-console",
            "headers": {
                "Authorization": "Bearer ${env:SITELINE_MCP_TOKEN}"
            }
        },
        "siteline-analytics": {
            "serverUrl": "https://siteline.tools/mcp/analytics",
            "headers": {
                "Authorization": "Bearer ${env:SITELINE_MCP_TOKEN}"
            }
        }
    }
}

Typical path: ~/.codeium/windsurf/mcp_config.json, or Cascade → Manage MCPs → Add Server. Refresh, then fully restart Windsurf. Closing a window is not always a reload. Devin and Cascade splits have moved this file before; confirm against current Windsurf docs. Add both servers. One token.

Cascade documents OAuth on HTTP transports. If your build completes the SiteLine authorization redirect, use it and skip the token. If it does not, the bearer path above is the IDE fallback. If Cascade caps how many MCP tools it loads, keep these two servers and drop toy ones. Search Console is the query ledger; analytics is the on-site ledger. Curl from the Path B section separates a SiteLine 401 from a Windsurf key typo.

GitHub Copilot

GitHub Copilot in VS Code can call remote MCP in Agent mode (VS Code 1.101 and later). It is not the GitHub MCP server. That server is issues and pull requests. It does not contain your Search Console.

Workspace file: .vscode/mcp.json (or the user MCP config). Copilot’s key is servers, not mcpServers. Do not paste a Claude Desktop file and expect it to load. Use an input so the token is not committed:

{
    "servers": {
        "siteline": {
            "type": "http",
            "url": "https://siteline.tools/mcp/search-console",
            "headers": {
                "Authorization": "Bearer ${input:siteline_token}"
            }
        },
        "siteline-analytics": {
            "type": "http",
            "url": "https://siteline.tools/mcp/analytics",
            "headers": {
                "Authorization": "Bearer ${input:siteline_token}"
            }
        }
    },
    "inputs": [
        {
            "type": "promptString",
            "id": "siteline_token",
            "description": "SiteLine MCP token",
            "password": true
        }
    ]
}

Create the token on Settings → MCP access. The value you type at the prompt is the same secret the other examples call YOUR_TOKEN. Enable Agent mode and confirm list-sites exists. Copilot’s one-click OAuth is for GitHub’s own MCP host. Use this token path unless your VS Code build actually completes SiteLine’s OAuth redirect for a custom HTTP server.

Cline in the same editor is a different JSON key, streamableHttp: Cline. Continue is YAML: Continue. Do not ask Copilot to mix GitHub stars with Search Console clicks. Different servers, different units.

Continue

Continue’s Agent mode is the only mode that receives MCP tools. Chat and edit mode will not see them. The config is YAML, and the transport string is streamable-http with a hyphen. streamableHttp is Cline. type: http inside servers is VS Code Copilot. Copying the wrong dialect is why Continue attempts legacy SSE against a streamable HTTP server and then shows no tools.

mcpServers:
    - name: siteline
      type: streamable-http
      url: https://siteline.tools/mcp/search-console
      apiKey: ${{ secrets.SITELINE_MCP_TOKEN }}
    - name: siteline-analytics
      type: streamable-http
      url: https://siteline.tools/mcp/analytics
      apiKey: ${{ secrets.SITELINE_MCP_TOKEN }}

On builds that support it, apiKey is sent as Authorization: Bearer …. Older Continue wants requestOptions.headers.Authorization with Bearer YOUR_TOKEN. Some versions also ingest a Cursor-shaped JSON file from .continue/mcpServers/. Whichever file you use, add both URLs. The token comes from SiteLine MCP access and is team-scoped. Reload Continue and switch to Agent mode.

Continue is model-agnostic. Claude, GPT, Gemini, or a local model still needs the same refusal in Continue’s rules: totals from get-site-overview, respect data_through, do not equate visitors with clicks. Continue can read get-analytics-goals. It cannot create goals; that stays in the dashboard. If tools are missing, check mode, YAML parse errors, and the hyphen in streamable-http before you blame the token. Curl from Path B if you need to split those cases.

Aider

Aider is a terminal pair programmer: /add, a diff, /commit. It is not a Search Console client, and its MCP story is version-shaped. Many builds speak stdio more readily than remote HTTP. Run aider --help and look for MCP before you assume a type: http key exists the way it does in Cursor.

When your build is an MCP client, use the keys that version documents (.aider.conf.yml, .mcp.json, or --mcp-server). The SiteLine URLs are still:

Auth is Authorization: Bearer YOUR_TOKEN from MCP access. If the client only spawns stdio servers, bridge HTTP with a local stdio adapter (the usual mcp-remote pattern). Aider talks to a child process; the child talks to SiteLine. You are not installing SiteLine on the laptop. Confirm the adapter’s flags on its current README; they move.

If that Aider build has no MCP, keep the split honest. Run Aider for the diff, and query SiteLine from Cursor, Claude Code, or the curl example in another pane. Pasting tools/list JSON into the Aider prompt is ugly and works, and it is better than inventing queries. There is no SiteLine “Aider plugin,” and SiteLine does not wrap Aider as an MCP server. Aider cannot request indexing through these tools. Once tools exist, the order is the same as every other client: get-import-status, get-site-overview, never sum query rows, then /add the template that owns the URL.

Gemini CLI

Gemini CLI is a terminal agent that can call MCP. It is not the Gemini API’s Search grounding, and grounding is not your Search Console property. SiteLine copies GSC with webmasters.readonly. It does not read a GA4 property, and it has no Ads tools, even though Gemini will happily mix those lores unless you stop it. Dedicated walkthrough: Gemini CLI setup.

Token from Settings → MCP access. The documented add command is gemini mcp add --transport http. Confirm gemini mcp add --help on your binary:

gemini mcp add --transport http siteline https://siteline.tools/mcp/search-console \
  --header "Authorization: Bearer YOUR_TOKEN"

gemini mcp add --transport http siteline-analytics https://siteline.tools/mcp/analytics \
  --header "Authorization: Bearer YOUR_TOKEN"

Builds that store servers in settings.json want httpUrl, not a bare url. A bare url can mean legacy SSE, and SiteLine is streamable HTTP:

{
    "mcpServers": {
        "siteline": {
            "httpUrl": "https://siteline.tools/mcp/search-console",
            "headers": {
                "Authorization": "Bearer YOUR_TOKEN"
            }
        }
    }
}

Add the analytics URL the same way, under a second name. If you get HTTP 406, the client is missing Accept: application/json, text/event-stream. Update the CLI. Gemini CLI can do a localhost OAuth redirect for remote MCP, which is fine on a laptop with a browser. Headless CI should use the bearer token. Do not assume this file is shared with Gemini Code Assist in VS Code. Configure MCP where the agent you type into actually reads settings.

Cline

Cline’s MCP settings are not Copilot’s .vscode/mcp.json. The transport value is streamableHttp — camelCase, one word. Omit type and Cline may register legacy SSE. SiteLine is streamable HTTP, so the tools list comes back empty even when the Path B curl succeeds. Continue’s hyphenated streamable-http and Windsurf’s serverUrl will not load here either.

Cline panel → MCP Servers → Configure, or ~/.cline/mcp.json for the CLI. Token from SiteLine MCP access:

{
    "mcpServers": {
        "siteline": {
            "type": "streamableHttp",
            "url": "https://siteline.tools/mcp/search-console",
            "headers": {
                "Authorization": "Bearer YOUR_TOKEN"
            },
            "disabled": false
        },
        "siteline-analytics": {
            "type": "streamableHttp",
            "url": "https://siteline.tools/mcp/analytics",
            "headers": {
                "Authorization": "Bearer YOUR_TOKEN"
            },
            "disabled": false
        }
    }
}

The Remote Servers UI — name, URL, transport Streamable HTTP — is safer than a paste that forgets type. If curl shows tools and Cline shows none, disable and re-enable the server after fixing streamableHttp.

Cline will take a long task and touch many files. That is a bad default when the first tool result was a lag day. Force get-import-status before overview, movers, and a single URL. You can auto-approve SiteLine’s read tools; they cannot write to Google. They can still waste the context window if the model sums query rows, so keep that refusal in Cline’s custom instructions. The same bearer token can sit in GitHub Copilot’s mcp.json as well. Two configs, one secret. Revoke it once on SiteLine to cut off both.

First useful calls

Search Console, in order, on https://siteline.tools/mcp/search-console:

  1. list-sites — copy a site id. Do not guess the domain string.
  2. get-import-status — read data_through before you believe a cliff.
  3. get-site-overview — the only whole-site totals.
  4. Then get-movers or get-striking-distance. Never sum get-top-results and call it the site.

Analytics, on https://siteline.tools/mcp/analytics:

  1. list-analytics-sites
  2. get-analytics-overview for the same calendar dates that have already landed in Search Console
  3. get-analytics-breakdown with dimension=page for the URL you are about to edit

The investigate-traffic-drop prompt on the Search Console server exists because that sequence is easy to reverse. Keep the two result sets in separate sentences. A visitor-day from the second list is not a click from the first.

Rules to put in the agent’s memory

When a plan’s event cap is active, analytics tools note that newer events are hidden until you upgrade. That is a visibility cap, not a stop on ingest.

FAQ

Can the agent write to Search Console?

No. Read-only Google scope, read-only tools. If a client promises it will “SEO itself,” that is not this server.

Why does list-sites return nothing?

The token’s team has no connected Search Console property, or you pointed the analytics URL at the Search Console server (or the reverse). Call the matching list-* tool on the matching host.

Is MCP billed per tool call?

No. MCP is on every tier. You pay for the subscription and for billable analytics events (pageviews and custom events), not for Search Console import rows or MCP round-trips. Billing.

I bookmarked a per-client setup page

Use the heading on this page for that client. Cursor, Claude Code, Claude, ChatGPT, OpenAI Codex, Grok, Windsurf, GitHub Copilot, Continue, Aider, Gemini CLI, and Cline are sections here. The category argument, including what “best” does and does not mean, stays on SEO analytics for AI agents.