A minimal Model Context Protocol server exposing two read-only Google Search Console tools to Claude (or any MCP client):
list_sites— lists the properties your account can access (wrapssites.list)query_search_analytics— pulls clicks / impressions / CTR / position for a site over a date range, grouped by dimensions you choose (wrapssearchAnalytics.query)
It authenticates as your own Google account via OAuth, using the webmasters.readonly scope. Because it's you, it automatically sees every property you already have access to — no per-property granting needed. It can only read, never write.
- Node.js 18 or later
- A Google account with at least one property in Search Console
- A free Google Cloud project (instructions below — no billing required)
- Go to the Google Cloud Console and create a project (free, no card).
- Under APIs & Services → Library, search for "Search Console API" and enable it.
- Under APIs & Services → OAuth consent screen, choose External and fill in the required app name and your email.
- Add the
.../auth/webmasters.readonlyscope when prompted (optional but tidy). - Add your own Google address under Test users.
- Set publishing status to "In production." This matters: while the app is in Testing status, refresh tokens expire after 7 days and you'd have to re-run login weekly. In production they're long-lived. Since the app is unverified, you'll see a "Google hasn't verified this app" warning during login — click Advanced → Go to (app name) to proceed. That's expected for a personal app.
- Under APIs & Services → Credentials → Create credentials → OAuth client ID.
- Choose application type Desktop app. (Desktop clients automatically allow the
http://localhostredirect this server uses.) - Copy the Client ID and Client secret.
cd gsc-mcp
npm installRun the login helper with your client credentials. It prints a URL, you authorize in the browser, and it saves a token.json next to the script.
GSC_CLIENT_ID="your-id.apps.googleusercontent.com" \
GSC_CLIENT_SECRET="your-secret" \
npm run loginOpen the printed URL, sign in as yourself, click through the unverified-app warning, and approve. When it says "Success," the refresh token is saved. You only do this once.
This is a local (stdio) server — works with Claude Desktop and Claude Code, not the claude.ai web app (which needs a remote server).
You configure it through a JSON file, but don't go looking for that file on disk — it doesn't exist until Claude Desktop creates it for you. Open it from inside the app:
- Open Claude Desktop and go to Settings.
- Find the Developer section and enable Developer mode if there's a toggle. (Without it, the next step's button won't appear.)
- Click Settings → Developer → Edit Config. This creates the config file if it doesn't exist and opens it in your default editor.
- Paste in the block below (merge into
mcpServersif the file already has entries), then save.
The file it opens lives at
~/Library/Application Support/Claude/claude_desktop_config.json on macOS or
%APPDATA%\Claude\claude_desktop_config.json on Windows.
{
"mcpServers": {
"gsc": {
"command": "node",
"args": ["/absolute/path/to/gsc-mcp/index.js"],
"env": {
"GSC_CLIENT_ID": "your-id.apps.googleusercontent.com",
"GSC_CLIENT_SECRET": "your-secret",
"GSC_TOKEN_PATH": "/absolute/path/to/gsc-mcp/token.json"
}
}
}
}Use absolute paths for everything. Then fully quit and reopen Claude Desktop (not just close the window).
To confirm it loaded: click the "+" button at the bottom of the chat box and choose Connectors, which lists connected MCP servers and their tools — or check connection status under Settings → Developer.
- "List my Search Console sites." →
list_sites - "For
https://example.com/, show the top 20 queries by clicks for May 2026." →query_search_analytics - "Break down
sc-domain:example.comby device for the last 28 days."
Run list_sites first if unsure of the exact siteUrl — the trailing slash and the sc-domain: prefix matter.
index.js— the MCP server (reads the stored refresh token, never opens a browser)login.js— the one-time browser login that producestoken.jsontoken.json— your saved refresh token (gitignored; treat it like a password)
- Keep
token.jsonprivate — it grants read access to your Search Console as you. - To go read-write later (e.g. submit sitemaps), change the scope in both files from
webmasters.readonlytowebmasters, then re-runnpm run login. - If a call ever fails with an auth error, re-run
npm run loginto refresh the token.