| name | gsc-cli |
| description | Google Search Console CLI workflow for agents. Use when Codex needs to query Search Console properties, search analytics performance data, URL inspection status, sitemap state/actions, or Google organic search reporting through the `gsc-cli` terminal command with strict JSON output. |
gsc-cli
gsc-cli is a JSON-first Google Search Console CLI. Use it to discover properties, query Search Analytics, inspect URL index status, and read or mutate sitemap submissions.
Install:
npm i -g @zuppif/gsc-cli
Core Loop
gsc-cli auth status
gsc-cli sites list
gsc-cli analytics query ...
gsc-cli url inspect ...
gsc-cli sitemaps list ...
Always use the exact siteUrl returned by sites list. Domain properties look like sc-domain:example.com. URL-prefix properties look like https://www.example.com/; preserve protocol, host, path, and trailing slash.
Output
Stdout is always JSON. Do not pass --json; that flag does not exist. Use --pretty only for human inspection.
Success:
{"ok":true,"command":"analytics.query","data":{},"meta":{"elapsedMs":421}}
Failure:
{"ok":false,"command":"analytics.query","error":{"code":"MISSING_SITE","message":"Missing required --site"}}
Read payloads from .data, runtime from .meta, and failures from .error.code / .error.message.
Global flags:
--credentials <path>
--timeout-ms <number>
--pretty
If GOOGLE_APPLICATION_CREDENTIALS is set, omit --credentials.
Dates
Use user-provided dates exactly. Convert relative dates to absolute YYYY-MM-DD.
If no dates are given, use the last complete 28 days and avoid today. Search Console dates are interpreted in Pacific Time.
Use --data-state final for stable reporting, --data-state all for fresh data, and --dimensions hour --data-state hourly_all for hourly data.
Properties
gsc-cli sites list
gsc-cli sites list | jq -r '.data.siteEntry[].siteUrl'
gsc-cli sites get --site "sc-domain:example.com"
Use sites list whenever the exact property is unknown. Do not invent https://, www, or slash variants.
Search Analytics
Base:
gsc-cli analytics query \
--site "sc-domain:example.com" \
--start 2026-06-01 \
--end 2026-06-12 \
--dimensions page,query \
--type web \
--data-state final \
--limit 100
Rows contain keys, clicks, impressions, ctr, and position. keys follow dimension order: with page,query, keys[0] is page and keys[1] is query.
Dimensions:
page
query
date
hour
country
device
searchAppearance
Types:
web
image
video
news
discover
googleNews
Common queries:
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions page --type web --data-state final --limit 100
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions query --type web --data-state final --limit 100
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions page,query --type web --data-state final --limit 1000
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions query --filter "page:equals:https://example.com/page" --limit 100
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions page --filter "query:equals:example keyword" --limit 100
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions date --type web --limit 1000
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions country --limit 250
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions device --limit 10
gsc-cli analytics query --site "sc-domain:example.com" --start 2026-06-01 --end 2026-06-12 --dimensions searchAppearance --limit 100
For large pulls, use --limit 25000 --start-row 0, then repeat with 25000, 50000, etc. Stop when .data.rows is missing or empty.
Filters
Format:
dimension:operator:expression
Allowed dimensions: country, device, page, query, searchAppearance.
Allowed operators: contains, equals, notContains, notEquals, includingRegex, excludingRegex.
Examples:
--filter "page:contains:/blog/"
--filter "query:contains:pricing"
--filter "query:includingRegex:^(best|top|review)"
--filter "country:equals:usa"
--filter "device:notEquals:DESKTOP"
Repeated filters are AND filters.
Raw Bodies
Use --body for exact API bodies or generated requests:
gsc-cli analytics query --site "sc-domain:example.com" --body '{"startDate":"2026-06-01","endDate":"2026-06-12","dimensions":["page"],"rowLimit":10}'
printf '%s' '{"startDate":"2026-06-01","endDate":"2026-06-12","dimensions":["page"]}' | gsc-cli analytics query --site "sc-domain:example.com" --body -
Do not mix --body with --start, --end, --dimensions, --type, --data-state, --aggregation, --limit, --start-row, or --filter.
URL Inspection
gsc-cli url inspect --site "sc-domain:example.com" --url "https://example.com/page" --language-code en-US
gsc-cli url inspect --site "sc-domain:example.com" --url "https://example.com/" | jq '.data.inspectionResult.indexStatusResult'
URL Inspection returns indexed-state information, not a live crawl. The inspected URL must belong to the supplied property. Use URL-prefix properties when exact prefix ownership matters.
Sitemaps
Read sitemap state:
gsc-cli sitemaps list --site "sc-domain:example.com"
gsc-cli sitemaps list --site "sc-domain:example.com" --sitemap-index "https://example.com/sitemap-index.xml"
gsc-cli sitemaps get --site "sc-domain:example.com" --sitemap "https://example.com/sitemap.xml"
Mutate only when explicitly requested:
gsc-cli sitemaps submit --site "sc-domain:example.com" --sitemap "https://example.com/sitemap.xml"
gsc-cli sitemaps delete --site "sc-domain:example.com" --sitemap "https://example.com/sitemap.xml"
Common Workflows
High-impression, low-CTR pages: query --dimensions page, then sort rows with high impressions and low ctr.
Query opportunities for a page: query --dimensions query --filter "page:equals:<url>"; positions around 4-20 are often optimization candidates.
Competing pages for one query: query --dimensions page --filter "query:equals:<query>"; multiple meaningful URLs may indicate intent split or cannibalization.
Branded vs non-branded: run query:includingRegex:(brand|brandname) and query:excludingRegex:(brand|brandname).
Traffic drop: query --dimensions date; if page-specific, use date,page plus a page or section filter.
Section audit: query --dimensions page,query --filter "page:contains:/blog/" --limit 25000.
Index check: run url inspect for each important URL and summarize verdict, coverage state, canonical fields, and inspection link.
Sitemap health: run sitemaps list then sitemaps get for suspicious sitemaps; check warnings, errors, pending state, stale lastDownloaded, and submitted counts.
Decision Guide
Use sites list when the exact property is unknown.
Use analytics query --dimensions page for landing pages, URLs, page-level clicks, impressions, CTR, or position.
Use analytics query --dimensions query for keywords, user searches, demand, or intent.
Use analytics query --dimensions page,query to connect pages to queries.
Use analytics query --dimensions date for trends, growth, declines, migrations, releases, or incident timelines.
Use analytics query --dimensions country for geography and device for desktop/mobile/tablet comparisons.
Use analytics query --type image|video|news|discover|googleNews for non-web surfaces.
Use url inspect for index status of specific URLs.
Use sitemaps list/get for sitemap state, warnings, errors, and submission status.
Use sitemaps submit/delete only for explicit mutation requests.
Troubleshooting
If auth fails, run gsc-cli auth status --pretty.
If the property is missing, run gsc-cli sites list --pretty.
If Search Analytics returns no rows, check date range, property string, filters, search type, and whether the site has data.
If URL Inspection says the URL is outside the property, use the correct domain property or matching URL-prefix property.
If sitemap mutation fails, verify write permission. Read-only credentials are enough for analytics, sites, URL inspection, and sitemap reads, but not submit/delete.
Reference
gsc-cli auth status
gsc-cli sites list
gsc-cli sites get --site <siteUrl>
gsc-cli analytics query --site <siteUrl> --start <YYYY-MM-DD> --end <YYYY-MM-DD> [analytics flags]
gsc-cli analytics query --site <siteUrl> --body <json|->
gsc-cli url inspect --site <siteUrl> --url <url> [--language-code <code>]
gsc-cli sitemaps list --site <siteUrl> [--sitemap-index <url>]
gsc-cli sitemaps get --site <siteUrl> --sitemap <url>
gsc-cli sitemaps submit --site <siteUrl> --sitemap <url>
gsc-cli sitemaps delete --site <siteUrl> --sitemap <url>