name: gseo description: Google SEO CLI for querying GSC, GA4, and BigQuery data directly via Google APIs. Use when the user wants to pull search analytics, find keyword cannibalization, striking distance keywords, content decay, CTR benchmarks, export SEO data, or run BigQuery queries against GSC/GA4 exports. Triggers include "query GSC", "get search data", "find cannibalized keywords", "striking distance", "content decay", "CTR benchmark", "export queries", "list sites", "GA4 data", "search console", "bigquery", "bq", or any request involving GSC/GA4/BigQuery data. allowed-tools: Bash(bun run src/main.ts:), Bash(./gseo:)
gseo — Google SEO CLI
CLI that talks directly to the Google Search Console API and GA4 Data API. No third-party proxy — your data goes straight from Google to your terminal.
Setup
bun install
bun run src/main.ts <command>
# Or compile a standalone binary
bun build src/main.ts --compile --outfile gseo
./gseo <command>
Authentication
Requires Google OAuth2 credentials. One-time setup:
# Option 1: OAuth2 (interactive — opens browser)
# First, download client credentials JSON from https://console.cloud.google.com/apis/credentials
bun run src/main.ts login --client-credentials ~/Downloads/client_secret_*.json
# Option 2: Service account
bun run src/main.ts login --service-account /path/to/key.json
# Verify
bun run src/main.ts whoami
Required Google Cloud APIs: Search Console API + Analytics Data API (+ Analytics Admin API for ga4-properties).
Global Options
-f, --format <fmt> ascii (default) | markdown | json | csv
-o, --output <file> Write to file instead of stdout
-p, --property <id> Property ID (e.g. "sc-domain:example.com")
Configuration
Set defaults
bun run src/main.ts config set-property sc-domain:example.com
bun run src/main.ts config link-ga4 sc-domain:example.com 123456789
bun run src/main.ts config set-branded "brandname" "brand name"
Topic Clusters (query keyword groups)
Named regex/substring filter groups applied to the query dimension.
# Add patterns (substring match by default)
bun run src/main.ts config add-cluster "gravel" "gravel bike" "bikepacking"
# Add regex patterns
bun run src/main.ts config add-cluster "gravel" --regex "touring|adventure"
# Add exclusion patterns
bun run src/main.ts config add-cluster "gravel" --exclude "cheap" "free"
# List clusters
bun run src/main.ts config list-clusters
# Remove
bun run src/main.ts config remove-cluster "gravel"
Content Groups (page URL groups)
Named filter groups applied to the page dimension.
bun run src/main.ts config add-group "blog" "/blog/" "/articles/"
bun run src/main.ts config add-group "products" --regex "^/products/"
bun run src/main.ts config list-groups
bun run src/main.ts config remove-group "blog"
Tags (property groups)
bun run src/main.ts config add-tag "clients" sc-domain:a.com sc-domain:b.com
bun run src/main.ts config list-tags
Import from seogets
If you have a seogets account, import all config (clusters, groups, branded keywords, GA4 links, tags) in one shot:
# Reads session from ~/.config/seogets/session.json
bun run src/main.ts import-seogets --dry-run # preview first
bun run src/main.ts import-seogets # import for real
Commands
List Sites
bun run src/main.ts sites
bun run src/main.ts sites --tag "clients"
GSC Search Analytics (query)
# Top queries (last 6 months)
bun run src/main.ts query -p "sc-domain:example.com" --dimension query --take 20
# Pages by clicks
bun run src/main.ts query -p "sc-domain:example.com" --dimension page --take 20
# Daily time series
bun run src/main.ts query -p "sc-domain:example.com" --dimension date --from 2026-01-01
# Query+page pairs
bun run src/main.ts query -p "sc-domain:example.com" --dimension page+query --take 50
# With filters
bun run src/main.ts query -p "sc-domain:example.com" --dimension query \
--filter "query:contains:gravel" \
--filter "country:equals:usa"
# With topic cluster / content group
bun run src/main.ts query --cluster "gravel" --dimension query --take 20
bun run src/main.ts query --group "blog" --dimension page --take 20
# Export
bun run src/main.ts query -p "sc-domain:example.com" --dimension page -f csv -o pages.csv
Dimensions: date, page, query, page+query
Search types: --search-type web|discover|news|image|video
Filter format: dimension:operator:expression
- Operators:
contains,notContains,equals,includingRegex,excludingRegex
GA4 Analytics
bun run src/main.ts ga4 -p "sc-domain:example.com" --dimension date --take 14
bun run src/main.ts ga4 -p "sc-domain:example.com" --dimension landing-page --organic-only --take 20
bun run src/main.ts ga4 -p "sc-domain:example.com" --dimension source-medium
bun run src/main.ts ga4 -p "sc-domain:example.com" --dimension event-name
bun run src/main.ts ga4 -p "sc-domain:example.com" --dimension totals
# With content group filter
bun run src/main.ts ga4 --group "blog" --organic-only
Dimensions: date, landing-page, source-medium, event-name, totals
GA4 property ID is auto-resolved from config. Override with --ga4-id <id>.
List GA4 Properties
bun run src/main.ts ga4-properties
Discovers all GA4 properties accessible to your account. Use the numeric ID with config link-ga4.
Optimization Reports
All optimization commands support --cluster and --group flags to scope the analysis.
# Striking distance (position 3-10)
bun run src/main.ts optimize striking-distance -p "sc-domain:example.com" --take 20
bun run src/main.ts optimize striking-distance --cluster "product-keywords"
# Keyword cannibalization
bun run src/main.ts optimize cannibalization -p "sc-domain:example.com" --exclude-branded
bun run src/main.ts optimize cannibalization --group "blog" --min-pages 3
# Content decay (pages losing clicks)
bun run src/main.ts optimize decay -p "sc-domain:example.com" --take 20
bun run src/main.ts optimize decay --group "blog"
# CTR benchmark
bun run src/main.ts optimize ctr -p "sc-domain:example.com" --take 20
bun run src/main.ts optimize ctr --cluster "gravel"
BigQuery
Query GSC and GA4 data from BigQuery exports — unlimited history, no row limits, raw SQL.
# Setup
bun run src/main.ts config set-bq-project my-gcp-project
bun run src/main.ts config set-bq-gsc-dataset searchconsole
bun run src/main.ts config set-bq-ga4-dataset analytics_123456789
# GSC via BigQuery (same flags as gseo query, but no 16-month or 25k row limit)
bun run src/main.ts bq gsc --dimension query --take 50
bun run src/main.ts bq gsc --dimension page --from 2023-01-01 --cluster "gravel"
bun run src/main.ts bq gsc --dimension date --from 2023-01-01 --to 2024-01-01
# GA4 via BigQuery
bun run src/main.ts bq ga4 --dimension date --from 2023-01-01
bun run src/main.ts bq ga4 --dimension source-medium --organic-only
bun run src/main.ts bq ga4 --dimension landing-page --group "blog"
# Raw SQL
bun run src/main.ts bq sql "SELECT query, SUM(clicks) as clicks FROM \`project.searchconsole.searchdata_site_impression\` WHERE data_date > '2024-01-01' GROUP BY query ORDER BY clicks DESC LIMIT 10"
# Discovery
bun run src/main.ts bq datasets
bun run src/main.ts bq tables searchconsole
Output Formats
| Format | Flag | Use case |
|---|---|---|
| ASCII | -f ascii |
Terminal display (default) |
| Markdown | -f markdown |
Docs, reports, Notion |
| JSON | -f json |
Piping, scripting |
| CSV | -f csv -o file.csv |
Spreadsheets, analysis |
Environment Variables
| Variable | Description |
|---|---|
GOOGLE_CLIENT_ID |
OAuth2 client ID |
GOOGLE_CLIENT_SECRET |
OAuth2 client secret |
GOOGLE_APPLICATION_CREDENTIALS |
Service account JSON path |
GSEO_PROPERTY |
Default property ID |
Config Storage
- Auth tokens:
~/.config/gseo/auth.json - Client credentials:
~/.config/gseo/credentials.json - Config (properties, clusters, groups, tags):
~/.config/gseo/config.json