Google Search Console CLI

  • Agents and operations
  • Operations CLI
  • 2026
  • Open source

Go, Search Console API, OAuth 2.0 with PKCE, OS keychain

Google Search Console CLI is a Go binary called gsc for search performance, URL inspection, sitemaps and properties. It implements all ten active methods of the Search Console API. On top of them it adds what the web interface lacks: period comparisons, a resumable day by day export, and opportunities computed locally. I built it for a person at a terminal and for a coding agent that needs stable JSON.

The web interface answers one question at a time and caps its tables at a thousand rows. The questions I actually ask are joins. Which queries sit just off page one, which pages compete for the same query, which queries vanished since last month. Each answer meant a spreadsheet export and arithmetic by hand, and an agent can do neither through a browser.

siteprojects.piyushgambhir.com/gsc-cli
Google Search Console CLI cover
A Go CLI for Google Search Console. Search analytics with period comparisons, URL inspection, sitemaps and resumable export, after one browser login.

gscsession

# parsed with the real command tree, never rungsc commands resolve -- auth token{  "command": "gsc auth token",  "effect": "read",  "conditional": false,  "interactive": false,  "secret_output": true,  "flags": {},  "args": []}

1 command9 lines of output

Chapter
Agents and operations
Category
Operations CLI
Year
Availability
Open source
Last commit
stack4 parts
  • Go
  • Search Console API
  • OAuth 2.0 with PKCE
  • OS keychain

Go, CLI, Google Search Console, SEO, OAuth

Signing in once

Search Console data belongs to a Google account, so every request needs an OAuth token. API keys do not work, and Google’s device-code flow excludes the Search Console scopes. gsc auth login listens on a free port on 127.0.0.1 and opens the consent page with PKCE and a random state. The refresh token goes into the OS keychain. Release binaries carry a Desktop OAuth client injected through -ldflags, so a first login needs no Google Cloud project. Service accounts, Application Default Credentials and impersonation cover CI. Without a keychain, login stops and offers --insecure-storage rather than writing plaintext quietly. Nothing falls back to ambient credentials on its own, so an agent never runs as an identity nobody chose.

Reading the numbers

Most of the code exists so the numbers are not misread. Dates are Pacific Time and inclusive, and --last 28d ends at the latest day with data, found by one small probe. Rows arrive in pages of up to 25,000, and complete: true means pagination ended, never that every query was seen. Google withholds anonymized queries, so totals come from gsc performance, not from summed query rows. --compare previous or yoy runs a second query and joins the two. A row missing from one period is null, not zero, and CTR changes are in percentage points. trend --by month sums clicks and impressions, recomputes CTR from the sums and weights position by impressions.

Safety by effect

Each command is classified by what it does, not by its HTTP verb. Search Analytics and URL Inspection are POST requests, yet both only read and run under --read-only. sites remove and sitemaps delete are remote writes, export is a local write, and auth token is refused under --read-only because it prints a credential. GSC_READ_ONLY=1 in the environment cannot be undone by --read-only=false later. TestAgentSafetyCommandManifest hashes every command with its annotations, so reclassifying one is a deliberate change. gsc commands resolve parses arguments with the real command tree and reports their effect without running them. Reckon calls it before each run and refuses anything that is not a plain read.

Choices and their cost

  • I call the REST endpoints directly, not through the generated searchconsole/v1 Go client. Ten methods did not justify its dependency graph. The cost is upkeep. TestAPICoverage checks a vendored discovery snapshot and fails for every method a refresh adds, removes or changes.
  • The built-in OAuth client ships inside release binaries, which is what makes login one command. Everyone on it shares one project’s quota, and source builds have no client at all.
  • Nothing retries automatically except export --retry N. Search Analytics has unpublished load quotas, and a retry loop is how an agent burns them. A transient failure stops the command instead.
  • Logins default to the full webmasters scope, with --scope readonly as the option. This is the one I would revisit. A read-only default would put the guard against a stray sitemaps delete in Google’s token, not only in my flag.

A weekly search review

bash6 lines
gsc auth login
gsc freshness
gsc performance --last 28d --compare previous -o json
gsc insights striking-distance --last 28d --min-impressions 200
gsc insights cannibalization --last 3m -o json
gsc export --last 16m -d query -d page --out ./gsc-export

freshness comes first, because final data usually lags two to three days. Each insight prints its thresholds, and striking-distance defaults to positions 4 to 20. The export writes one CSV per day through a temporary file and a rename, and manifest.json records finished days. Rerunning resumes, preliminary days are fetched again, and a changed request needs --restart.

Where it stops

It is an independent client, not affiliated with Google, and it reports only what the API exposes. Core Web Vitals, Page indexing, manual actions, links and live URL tests are absent. So are the AI Overviews and AI Mode reports, whose traffic sits inside ordinary totals. gsc inspect shows the indexed version only, and stops cleanly at the quota of 2,000 inspections per property per day. The name collides with Ghostscript and Gambit Scheme, so the installer and gsc doctor warn. It is MIT licensed, at v0.1.8, and updates itself on macOS, Linux and Windows. Bing gets the same treatment in Bing Webmaster CLI.

All 43 projects