@gscdump/cli 4.0.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -449
- package/dist/package.mjs +1 -1
- package/dist/route.mjs +8 -2
- package/package.json +7 -7
- package/skills/gscdump/SKILL.md +5 -0
package/README.md
CHANGED
|
@@ -1,459 +1,16 @@
|
|
|
1
1
|
# @gscdump/cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](https://npm.chart.dev/@gscdump/cli)
|
|
5
|
-
[](https://github.com/harlan-zw/gscdump/blob/main/LICENSE)
|
|
6
|
-
|
|
7
|
-
Query Google Search Console and Bing with hosted or local authentication.
|
|
8
|
-
Sync Google rows to a local Parquet Store, and run SEO Analyzers or Reports.
|
|
9
|
-
The package also provides the MCP server.
|
|
10
|
-
Use Node.js 22.13 or later in the 22 release line, or Node.js 24 or later.
|
|
11
|
-
|
|
12
|
-
## Install
|
|
3
|
+
Google Search Console CLI and MCP server.
|
|
13
4
|
|
|
14
5
|
```bash
|
|
15
6
|
npm install -g @gscdump/cli
|
|
16
|
-
# or run with npx
|
|
17
|
-
npx @gscdump/cli
|
|
18
7
|
```
|
|
19
8
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
gscdump init --mode local
|
|
25
|
-
gscdump auth login --mode local
|
|
26
|
-
|
|
27
|
-
# List sites
|
|
28
|
-
gscdump sites
|
|
29
|
-
|
|
30
|
-
# Sync 90 days to the Store
|
|
31
|
-
gscdump sync --site example.com --days 90 --tables pages,queries,page_queries,countries,dates
|
|
32
|
-
|
|
33
|
-
# Query the Store
|
|
34
|
-
gscdump query --site example.com --dimensions page,query --limit 50
|
|
35
|
-
|
|
36
|
-
# Run an Analyzer
|
|
37
|
-
gscdump analyze striking-distance --site example.com
|
|
38
|
-
|
|
39
|
-
# Start the MCP server
|
|
40
|
-
gscdump mcp
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Commands
|
|
44
|
-
|
|
45
|
-
| Command | Description |
|
|
46
|
-
|---|---|
|
|
47
|
-
| `init` | Full setup (OAuth + dataDir; offers to write a `.env` for later use). `--mode cloud\|local` saves the auth mode. Without a terminal it never prompts |
|
|
48
|
-
| `auth` | Manage authentication (`status`, `login`, `logout`, `refresh`) |
|
|
49
|
-
| `bing` | Connect Bing, list sites, dump datasets, inspect URLs, and check hosted verification |
|
|
50
|
-
| `config` | Manage CLI configuration (`show`, `set`, `unset`, `path`, `validate`) |
|
|
51
|
-
| `doctor` | Health checks: auth, scopes, dataDir writability, API reachability |
|
|
52
|
-
| `sites [--owner-only] [--with-sitemaps]` | List available GSC sites |
|
|
53
|
-
| `sites add <url>` / `sites delete <url> [--yes]` | Register or remove a Site in Search Console (add registers in unverified state) |
|
|
54
|
-
| `sites verify-token <url> [--method]` / `sites verify <url> [--method]` | Get a verification token, then trigger ownership verification (META/FILE/DNS_TXT/DNS_CNAME/ANALYTICS/TAG_MANAGER) |
|
|
55
|
-
| `sitemaps` | List, submit, or delete Google sitemaps; probe live URLs; read hosted snapshots (`current`, `history`, `membership`, `lastmod`, `export`) with `--site` |
|
|
56
|
-
| `inspect <url...> [--file]` | URL inspection for one or more URLs; renders Indexing Evidence, rich results, and AMP, and saves each result to the Store |
|
|
57
|
-
| `indexing` | Notify Google about URL changes (`submit`, `remove`, `status`, `batch`, `batch-status`, `quota`); supports `--retries`. `indexing urls --status not_indexed` lists hosted URL Inspection results |
|
|
58
|
-
| `sync` | Sync GSC data, sitemaps, and URL Inspection results to the local Store; `--inspect-limit`, `--max-calls`, `--all-sites`, `--no-sitemaps`, `--no-inspections`, `--retry-failed`, `--dry-run` |
|
|
59
|
-
| `query` | Run a search analytics query (the Store when it covers the dates, see [Routing](#routing); `--live` hits GSC API). Filters: `--query`, `--page`, `--country`, `--device`, `--search-appearance`, `--type`, `--data-state`, `--aggregation-type`. `--explain` previews the request body; `--output -` writes to stdout. `--sql` runs DuckDB SQL over the Store views; `--schema` lists them. |
|
|
60
|
-
| `dump` | Export the Store, inspections, sitemaps, and Bing data (`--format parquet\|csv\|json\|ndjson\|sqlite\|duckdb`, `--tables`, `--all-sites`, `--no-bing`). Every row has `site` and `search_type` |
|
|
61
|
-
| `analyze <tool>` | Run an SEO Analyzer against the Store, or live when the Site has no Store data (`--live` forces live for row-based Analyzers) |
|
|
62
|
-
| `entities` | Read saved URL inspections and snapshot indexing metadata into the local entity store |
|
|
63
|
-
| `store stats` | Show row/byte counts per table and on-disk footprint |
|
|
64
|
-
| `store compact` | Compact older data into weekly, monthly, and quarterly tiers (`--dry-run`) |
|
|
65
|
-
| `store gc` | Delete orphaned objects past the grace window (`--dry-run`) |
|
|
66
|
-
| `store rm-site` / `store reset` | Delete one Site's data or reset the Store; inspect `--help` before use |
|
|
67
|
-
| `store rollups rebuild` | Rebuild post-sync rollup tables |
|
|
68
|
-
| `report <id>` / `report list` | Run or list Reports; `--explain` previews a plan |
|
|
69
|
-
| `profile` | Create, select, list, or delete credential profiles |
|
|
70
|
-
| `mcp` | Start the MCP server for AI assistants |
|
|
71
|
-
| `skill install [--agent claude\|codex] [--target <dir>]` | Copy the packaged `gscdump` agent skill (SKILL.md) into an agent skill directory |
|
|
72
|
-
| `papercut --command <cmd> --comment <text> --agent <name> [--intent bug\|improvement] --yes` | Report a CLI problem to gscdump.com; anonymous, ten per hour per network address |
|
|
73
|
-
|
|
74
|
-
## Hosted and local authentication
|
|
75
|
-
|
|
76
|
-
One authentication mode applies to both Google and Bing.
|
|
77
|
-
Credentials and the saved mode belong to the current `--profile` or `--config-dir`.
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
# Use a user API key from https://gscdump.com/app/settings
|
|
81
|
-
export GSCDUMP_API_KEY=gsd_user_...
|
|
82
|
-
gscdump auth login --mode cloud
|
|
83
|
-
gscdump auth status --json
|
|
84
|
-
|
|
85
|
-
# Google uses the connection on gscdump.com
|
|
86
|
-
gscdump sites --json
|
|
87
|
-
gscdump query --live --site example.com --dimensions page
|
|
88
|
-
|
|
89
|
-
# Connect Bing through gscdump.com, then read its data
|
|
90
|
-
gscdump bing sites --json
|
|
91
|
-
gscdump bing login --site s_SITE_ID
|
|
92
|
-
gscdump bing status --site s_SITE_ID --json
|
|
93
|
-
gscdump bing dump --site s_SITE_ID --out ./bing-export --format csv
|
|
94
|
-
|
|
95
|
-
# Use local credentials for one command
|
|
96
|
-
gscdump bing sites --mode local --json
|
|
97
|
-
|
|
98
|
-
# Save local mode after successful Google login
|
|
99
|
-
gscdump auth login --mode local
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
`--mode cloud|local` overrides the mode for one invocation.
|
|
103
|
-
`GSCDUMP_AUTH_MODE` provides the same override.
|
|
104
|
-
A successful login saves the mode for later commands.
|
|
105
|
-
If no mode is saved, `GSCDUMP_API_KEY` selects hosted authentication.
|
|
106
|
-
With neither source, the CLI defaults to local authentication.
|
|
107
|
-
When a saved mode exists, it remains selected unless an explicit override applies.
|
|
108
|
-
`GSCDUMP_API_ROOT` defaults to `https://gscdump.com/api`.
|
|
109
|
-
If you change a saved API root, supply the API key explicitly.
|
|
110
|
-
|
|
111
|
-
| Operation | Hosted authentication | Local authentication |
|
|
112
|
-
| --- | --- | --- |
|
|
113
|
-
| Google queries, sync, sites, sitemaps, URL inspection | Uses the Google connection through gscdump.com | Calls Google with local credentials |
|
|
114
|
-
| Google Indexing API and Site Verification API | Requires local mode | Supported with the required Google scopes |
|
|
115
|
-
| Bing datasets | Reads synced datasets through the public API | Reads data currently returned by Bing |
|
|
116
|
-
| Bing connection and CNAME verification | Uses `bing login`, `bing status`, and `bing verify` | Verify sites in Bing Webmaster Tools |
|
|
117
|
-
| Hosted sitemap membership and history | Supported | Requires hosted authentication |
|
|
118
|
-
| Store queries and exports | Reads the local Store | Reads the local Store |
|
|
119
|
-
| Hosted sync progress | `status` and `sites` show it | Not available |
|
|
120
|
-
|
|
121
|
-
Hosted Bing access follows the API's plan and preview access rules.
|
|
122
|
-
`auth logout` removes the saved mode and saved Google and Bing credentials.
|
|
123
|
-
Environment credentials remain active until you unset them.
|
|
124
|
-
|
|
125
|
-
## Bing
|
|
126
|
-
|
|
127
|
-
For local Bing access, generate an API key in Bing Webmaster Tools under Settings, API Access.
|
|
128
|
-
See [Microsoft's authentication guide](https://learn.microsoft.com/en-us/bingwebmaster/getting-access).
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
export BING_API_KEY=...
|
|
132
|
-
gscdump bing login --mode local
|
|
133
|
-
gscdump bing sites --json
|
|
134
|
-
gscdump bing dump --site https://example.com/ --format json --out ./bing-export
|
|
135
|
-
gscdump bing dump --all-sites --format ndjson
|
|
136
|
-
gscdump bing inspect https://example.com/page --site https://example.com/ --json
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
`BING_ACCESS_TOKEN` also accepts an existing Bing OAuth access token.
|
|
140
|
-
Local API keys and OAuth credentials are saved separately from Google credentials.
|
|
141
|
-
`bing logout --mode local` removes only saved Bing credentials.
|
|
142
|
-
|
|
143
|
-
For local browser OAuth, register a Bing OAuth client with this exact redirect URI:
|
|
144
|
-
`http://127.0.0.1:53683/oauth/bing`.
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
export BING_CLIENT_ID=...
|
|
148
|
-
export BING_CLIENT_SECRET=...
|
|
149
|
-
gscdump bing login --mode local --oauth
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Use `--redirect-uri` or `BING_REDIRECT_URI` for another registered loopback URI.
|
|
153
|
-
`--no-browser` prints the authorization URL. Saved OAuth credentials refresh automatically.
|
|
154
|
-
|
|
155
|
-
`bing dump` exports `traffic`, `pages`, `keywords`, and `crawl` by default.
|
|
156
|
-
Use `--datasets traffic,pages` to select datasets.
|
|
157
|
-
Local mode also supports `--datasets crawl-issues`.
|
|
158
|
-
Files use JSON, NDJSON, or CSV, with one directory per Bing site and a `metadata.json` file.
|
|
159
|
-
|
|
160
|
-
In hosted mode, exports default to the last 366 days.
|
|
161
|
-
Use `--start YYYY-MM-DD --end YYYY-MM-DD` for a range up to 366 days.
|
|
162
|
-
The CLI follows every returned page and rejects unavailable datasets or a snapshot that changes during export.
|
|
163
|
-
In local mode, date options filter the rows Bing returns. They cannot recover older history.
|
|
164
|
-
Bing Indexing Evidence preserves uncertainty and does not imply an indexed verdict.
|
|
165
|
-
|
|
166
|
-
### Filter expressions
|
|
167
|
-
|
|
168
|
-
`query` accepts prefix-encoded filter expressions for `--query`, `--page`, `--country`, `--device`, `--search-appearance`:
|
|
169
|
-
|
|
170
|
-
| Prefix | Operator |
|
|
171
|
-
|---|---|
|
|
172
|
-
| (bare) | equals |
|
|
173
|
-
| `~foo` | contains |
|
|
174
|
-
| `!~foo` | not contains |
|
|
175
|
-
| `re:foo` | regex |
|
|
176
|
-
| `!re:foo` | not regex |
|
|
177
|
-
| `!foo` | not equals |
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
# pages under /blog/ with brand mentions in the query
|
|
181
|
-
gscdump query --live --site example.com \
|
|
182
|
-
--page '~/blog/' --query '~brand' --dimensions page,query
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
`--limit` and `--format` override saved `defaultLimit` and `defaultFormat` values.
|
|
186
|
-
Without saved values, queries use 1000 rows and JSON.
|
|
187
|
-
Limits must be positive integers. Formats must be `json` or `csv`.
|
|
188
|
-
|
|
189
|
-
Without dates, a query reads the last 28 days that end on the newest synced day of the table it reads.
|
|
190
|
-
With `--live`, the window ends three days ago, Pacific time: the newest final GSC date.
|
|
191
|
-
`--start` alone runs to that end date. `--end` alone reads the 28 days that end on it.
|
|
192
|
-
Dates must use `YYYY-MM-DD`, and `--start` cannot follow `--end`.
|
|
193
|
-
|
|
194
|
-
`--page` accepts a path or a full URL. The Store compares paths, so `https://example.com/a` matches `/a`.
|
|
195
|
-
Live queries expand a path to the Site's origin. For a domain property, a path matches that path on any host.
|
|
196
|
-
Filtered dimensions choose the Store table too: `-d query --page /a` reads `page_queries`.
|
|
197
|
-
If no Store table holds every dimension and filter, the query fails and names `--live`.
|
|
198
|
-
|
|
199
|
-
```bash
|
|
200
|
-
# Export query rows with a CSV header.
|
|
201
|
-
gscdump query --live --site example.com \
|
|
202
|
-
--dimensions page,query --format csv --output rows.csv
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### SQL over the Store
|
|
206
|
-
|
|
207
|
-
`query --sql` runs DuckDB SQL over one view per Store table.
|
|
208
|
-
Run `query --schema` to list the views, their columns, and their date ranges.
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
gscdump query --format json --sql "
|
|
212
|
-
SELECT p.page, SUM(q.clicks) AS clicks, gsc_position(q.sum_position, q.impressions) AS position
|
|
213
|
-
FROM pages p JOIN page_queries q USING (site, search_type, url, date)
|
|
214
|
-
WHERE p.search_type = 'web' AND p.date >= DATE '2026-08-01'
|
|
215
|
-
GROUP BY p.page ORDER BY clicks DESC LIMIT 20"
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
| Column | Meaning |
|
|
219
|
-
| --- | --- |
|
|
220
|
-
| `site` | The Site URL, such as `sc-domain:example.com` |
|
|
221
|
-
| `search_type` | `web`, `image`, `video`, `news`, `discover`, or `googleNews` |
|
|
222
|
-
| `url`, `page` | The page path. `page` is the same value as `url` |
|
|
223
|
-
| `sum_position` | Zero-based position multiplied by impressions |
|
|
224
|
-
|
|
225
|
-
- The Store keeps every search type. Filter or group by `search_type`, or a `SUM` adds web, image, and Discover rows together.
|
|
226
|
-
- `gsc_position(sum_position, impressions)` returns the impression-weighted average position. Use it with `GROUP BY`.
|
|
227
|
-
- The views cover every Site in the Store. `--site` and `--type` narrow them.
|
|
228
|
-
- Dates return as `YYYY-MM-DD`. Integers return as numbers, and an integer past 2^53 returns as a string.
|
|
229
|
-
- If the SQL names a table with no synced data, the CLI prints a warning.
|
|
230
|
-
|
|
231
|
-
### Export formats
|
|
232
|
-
|
|
233
|
-
`dump` reads only the Store. It never calls Google to fill a gap.
|
|
234
|
-
Every exported row has `site` and `search_type` columns.
|
|
235
|
-
|
|
236
|
-
| `--format` | Output |
|
|
237
|
-
| --- | --- |
|
|
238
|
-
| `parquet` (default) | `<site>/<search_type>/<table>.parquet` |
|
|
239
|
-
| `csv`, `json`, `ndjson` | `<site>/<search_type>/<table>.<ext>`, plus a per-row `position` |
|
|
240
|
-
| `sqlite` | One `gscdump.sqlite` file. Dates are `YYYY-MM-DD` text |
|
|
241
|
-
| `duckdb` | One `gscdump.duckdb` file |
|
|
242
|
-
|
|
243
|
-
Inspections, sitemaps, and Indexing API metadata go to `<site>/<dataset>.<ext>`, or to their own tables in a database file.
|
|
244
|
-
`manifest.json` lists every dataset with its row count, and the same coverage that `sync --status` reports.
|
|
245
|
-
`--format sqlite` needs Node.js 22.13 or later.
|
|
246
|
-
|
|
247
|
-
### Global flags
|
|
248
|
-
|
|
249
|
-
- `--no-color` / `NO_COLOR` env: strip ANSI from stdout (stderr keeps colour for interactive use).
|
|
250
|
-
- `--config-dir <path>` / `GSCDUMP_CONFIG_DIR`: override `~/.config/gscdump`.
|
|
251
|
-
- `--profile <name>` / `GSCDUMP_PROFILE`: separate tokens and config to a profile under `~/.config/gscdump/profiles/<name>` (separate Google credentials).
|
|
252
|
-
- Most commands accept `--quiet` and `--json` for scripts. The `query` command uses `--format json` instead.
|
|
253
|
-
|
|
254
|
-
Use `query --profile` for query timings. Use `--profile <name>` to select a credential profile.
|
|
255
|
-
Numeric flags reject fractions, negative counts, and text suffixes.
|
|
256
|
-
Saved config rejects invalid values and unknown keys. If parsing fails, fix the reported file.
|
|
257
|
-
|
|
258
|
-
## Analyzers
|
|
259
|
-
|
|
260
|
-
`gscdump analyze <tool>` runs one of 29 Analyzers from `@gscdump/analysis`.
|
|
261
|
-
See the [full list](../../README.md#analyzers) and [Source support](../analysis/README.md#sources).
|
|
262
|
-
|
|
263
|
-
Each Analyzer accepts `--site`, `--period`, `--start`, `--end`, `--limit`, `--fetch-budget`, and output flags.
|
|
264
|
-
Windows default to the last 28 days that end on the newest synced day.
|
|
265
|
-
`movers` and `decay` compare with the previous period by default. Override it with `--prev-start` and `--prev-end` together.
|
|
266
|
-
`movers` also accepts `--sort-by`: `clicksDelta` (default) sorts by absolute click change, `clicksDeltaPercent` by percent change.
|
|
267
|
-
`--limit` caps the rows shown. `--fetch-budget` caps the rows each live fetch reads (default 25000, max 100000).
|
|
268
|
-
If a fetch reaches the budget, the output shows a partial-data warning.
|
|
269
|
-
Use `gscdump analyze <tool> --help` for additional options.
|
|
270
|
-
|
|
271
|
-
`analyze` and `report` follow the [routing rules](#routing).
|
|
272
|
-
Pass `--live` to use Google explicitly.
|
|
273
|
-
SQL-only Analyzers require local data.
|
|
274
|
-
|
|
275
|
-
## Routing
|
|
276
|
-
|
|
277
|
-
Login is optional. Log in with Google or a hosted key, or sync a local Store.
|
|
278
|
-
`query`, `analyze`, and `report` pick one source for each run:
|
|
279
|
-
|
|
280
|
-
- If the Store covers every date the run needs, the run reads the Store. This is also true while a sync runs.
|
|
281
|
-
- If the Store has no data for the tables the run needs, and Google is connected, the run asks the live Search Console API.
|
|
282
|
-
stderr prints `No synced data for SITE; answering from the live Search Console API.` JSON output has `meta.source: "live"`.
|
|
283
|
-
- If the Store has no data and Google is not connected, the run stops and names `gscdump init`.
|
|
284
|
-
- If some dates are missing, the run stops and prints the `gscdump sync` command for the missing dates and tables. Pass `--live` to ask Google instead.
|
|
285
|
-
- If a sync for the Site is running and the dates are not covered yet, the run stops with `Sync running: 41 of 90 days done.`
|
|
286
|
-
A sync without a heartbeat in the last 2 minutes counts as stopped.
|
|
287
|
-
|
|
288
|
-
One run never mixes Store rows and live rows. Live results hold the top rows of each request, and synced data keeps more of the long tail.
|
|
289
|
-
`query --sql` reads the Store only.
|
|
290
|
-
With `--format json` or `--json`, a stop prints `{ "error": { "code", "message", "nextCommand" } }` on stdout and exits 1.
|
|
291
|
-
|
|
292
|
-
Every Search Analytics, URL Inspection, and Indexing API call goes through the quota ledger in the data dir, so all commands share one daily budget.
|
|
293
|
-
When a quota is spent, the command stops and says when the quota resets.
|
|
294
|
-
|
|
295
|
-
## Sync
|
|
296
|
-
|
|
297
|
-
```bash
|
|
298
|
-
# Default: catch every table and search type up to the latest final date.
|
|
299
|
-
# A table with no history starts 28 days back. Newest dates come first.
|
|
300
|
-
# Also saves sitemaps and inspects up to 50 due URLs. Skips completed dates.
|
|
301
|
-
gscdump sync --site example.com
|
|
302
|
-
|
|
303
|
-
# Backfill the 16 months Google keeps, plus 14 days Google often still serves
|
|
304
|
-
gscdump sync --site example.com --full
|
|
305
|
-
|
|
306
|
-
# Cap one run at 2,000 Search Analytics calls; the next run continues
|
|
307
|
-
gscdump sync --site example.com --full --max-calls 2000
|
|
308
|
-
|
|
309
|
-
# Every verified Site, one after another
|
|
310
|
-
gscdump sync --all-sites
|
|
311
|
-
|
|
312
|
-
# Custom range
|
|
313
|
-
gscdump sync --site example.com --start 2026-08-01 --end 2026-08-31 \
|
|
314
|
-
--tables pages,queries,page_queries,countries,dates
|
|
315
|
-
|
|
316
|
-
# Coverage, missing and failed dates per table, and a running sync
|
|
317
|
-
gscdump sync --site example.com --status
|
|
318
|
-
|
|
319
|
-
# Limit concurrent day requests per table
|
|
320
|
-
gscdump sync --site example.com --concurrency 4 \
|
|
321
|
-
--tables pages,queries,page_queries,countries,dates
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
Sync skips completed dates; `--force` refreshes them.
|
|
325
|
-
A day Google still updates stays `pending`, and the next sync fetches it again.
|
|
326
|
-
Sync records Google calls in a quota ledger in the Store directory.
|
|
327
|
-
If Google refuses a call for quota, sync stops, keeps the rest `pending`, and exits 0. The next run continues.
|
|
328
|
-
Cross-process locks coordinate `sync`, `compact`, and `gc`.
|
|
329
|
-
Pagination follows Google's 25,000-row pages and stops at the first short page, subject to [Google's data limits](https://developers.google.com/webmaster-tools/v1/how-tos/all-your-data).
|
|
330
|
-
|
|
331
|
-
## MCP server
|
|
332
|
-
|
|
333
|
-
Expose your GSC data to AI assistants over the Model Context Protocol.
|
|
334
|
-
|
|
335
|
-
```bash
|
|
336
|
-
gscdump mcp
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
Add to your Claude / VS Code config:
|
|
340
|
-
|
|
341
|
-
```json
|
|
342
|
-
{
|
|
343
|
-
"mcpServers": {
|
|
344
|
-
"gscdump": {
|
|
345
|
-
"command": "npx",
|
|
346
|
-
"args": ["-y", "@gscdump/cli", "mcp"]
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
Then ask questions like:
|
|
353
|
-
|
|
354
|
-
- "What pages lost traffic this week?"
|
|
355
|
-
- "Find queries in striking distance (positions 4 to 20)."
|
|
356
|
-
- "Which queries have cannibalization issues?"
|
|
357
|
-
- "Compare this month vs last month for /blog/ pages."
|
|
358
|
-
|
|
359
|
-
## Auth
|
|
360
|
-
|
|
361
|
-
This section covers local Google credentials. See [shared authentication](#hosted-and-local-authentication) for cloud mode and [Bing](#bing) for Bing credentials.
|
|
362
|
-
`gscdump init --mode local` configures Google OAuth and a Store directory.
|
|
363
|
-
Credentials are saved under `~/.config/gscdump/` on XDG systems, or the platform equivalent.
|
|
364
|
-
Use `gscdump auth login --mode local` to connect Google and save local mode.
|
|
365
|
-
|
|
366
|
-
If you configure your own Google OAuth client, browser login uses a temporary listener on `127.0.0.1` with a random port.
|
|
367
|
-
Each attempt uses state validation and PKCE S256 to bind the authorization response to that attempt.
|
|
368
|
-
The listener closes after authorization, denial, or a five-minute timeout.
|
|
369
|
-
|
|
370
|
-
By default, login opens gscdump.com. No Google Cloud project is required.
|
|
371
|
-
The platform handles Google login and token refresh. Data queries call Google directly.
|
|
372
|
-
This grants read-only Search Console access. It does not activate hosted sync, storage, or hosted MCP.
|
|
373
|
-
Hosted Pro is free during beta and will require payment after launch.
|
|
374
|
-
For Google write operations, configure your own OAuth client with the required scopes.
|
|
375
|
-
|
|
376
|
-
For your own OAuth client:
|
|
377
|
-
|
|
378
|
-
1. Create a Google Cloud project.
|
|
379
|
-
2. Enable **Search Console API**, **Web Search Indexing API**, and **Site Verification API**.
|
|
380
|
-
3. Create OAuth2 credentials (Desktop app).
|
|
381
|
-
4. Set `GSC_CLIENT_ID` and `GSC_CLIENT_SECRET` for your Desktop app.
|
|
382
|
-
5. Run `gscdump auth login --mode local` to save local mode.
|
|
383
|
-
|
|
384
|
-
### BYOK (Bring Your Own Key)
|
|
385
|
-
|
|
386
|
-
Skip `init` entirely by setting env vars. Either path works (`GSC_*` preferred, `GOOGLE_*` accepted):
|
|
387
|
-
|
|
388
|
-
```bash
|
|
389
|
-
# Option A: raw bearer token (e.g., from gcloud or another OAuth flow)
|
|
390
|
-
export GSC_ACCESS_TOKEN=ya29...
|
|
391
|
-
|
|
392
|
-
# Option B: refresh-token flow (OAuth refresh credentials)
|
|
393
|
-
export GSC_CLIENT_ID=...
|
|
394
|
-
export GSC_CLIENT_SECRET=...
|
|
395
|
-
export GSC_REFRESH_TOKEN=...
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
`gscdump auth status` shows which credential source is active.
|
|
399
|
-
`auth login --mode local` skips OAuth when it finds BYOK credentials and saves local mode.
|
|
400
|
-
|
|
401
|
-
### Service account
|
|
402
|
-
|
|
403
|
-
For CI / headless usage, point `gscdump` at a service-account JSON key. Grant the service account access to each Site in Search Console under Settings → Users and permissions.
|
|
404
|
-
|
|
405
|
-
```bash
|
|
406
|
-
gscdump auth login --mode local --service-account ./gsc-sa.json # smoke-test the key
|
|
407
|
-
export GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/gsc-sa.json
|
|
408
|
-
gscdump sites
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### Headless OAuth
|
|
412
|
-
|
|
413
|
-
If you want to open the authorization URL yourself, disable automatic browser opening:
|
|
414
|
-
|
|
415
|
-
```bash
|
|
416
|
-
gscdump auth login --mode local --no-browser
|
|
417
|
-
# Open the printed URL in your browser.
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
Default login works from a remote terminal without port forwarding. Keep the command running until you approve the browser request.
|
|
421
|
-
|
|
422
|
-
With your own OAuth client, login uses the Desktop application loopback flow.
|
|
423
|
-
|
|
424
|
-
If the CLI runs on another host, forward its printed loopback port before opening the URL.
|
|
425
|
-
Keep the login command running on that host.
|
|
426
|
-
For example, if the CLI prints port `45678`, run this command on your browser host:
|
|
427
|
-
|
|
428
|
-
```bash
|
|
429
|
-
ssh -N -L 45678:127.0.0.1:45678 user@host
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
Replace `user@host` with the CLI host.
|
|
433
|
-
Keep the forwarding command running until login completes.
|
|
434
|
-
Then open the printed authorization URL in your browser.
|
|
435
|
-
For containers or WSL, forward the same port to the environment running the CLI.
|
|
436
|
-
If you cannot forward loopback traffic, use a refresh token or service account.
|
|
437
|
-
|
|
438
|
-
See Google's [native application OAuth guide](https://developers.google.com/identity/protocols/oauth2/native-app)
|
|
439
|
-
and [device flow scope limits](https://developers.google.com/identity/protocols/oauth2/limited-input-device#allowedscopes).
|
|
440
|
-
|
|
441
|
-
Indexing notifications apply only to eligible job or livestream pages.
|
|
442
|
-
See [URL inspection and indexing](../../docs/guides/url-indexing.md).
|
|
443
|
-
|
|
444
|
-
## Related
|
|
445
|
-
|
|
446
|
-
- [`gscdump`](../gscdump) : Google and Bing clients with a typed query builder.
|
|
447
|
-
- [`@gscdump/engine`](../engine) : Storage engine the CLI syncs into.
|
|
448
|
-
- [`@gscdump/analysis`](../analysis) : SEO Analyzers (row-based + DuckDB-native).
|
|
9
|
+
- [Getting started](../../docs/gscdump-cli/guides/1.getting-started.md)
|
|
10
|
+
- [Authentication](../../docs/gscdump-cli/guides/2.authentication.md)
|
|
11
|
+
- [Command reference](../../docs/gscdump-cli/api/1.commands.md)
|
|
12
|
+
- [AI integration and MCP](../../docs/gscdump-cli/guides/3.ai-integration.md)
|
|
449
13
|
|
|
450
14
|
## License
|
|
451
15
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
## CLI charts
|
|
455
|
-
|
|
456
|
-
Human output shares chart styles and metric units across Analyzers, Reports, and Store stats.
|
|
457
|
-
Use `gscdump query --format table` for query charts.
|
|
458
|
-
JSON and CSV keep their existing payloads and defaults.
|
|
459
|
-
See [CLI charts](../../docs/guides/cli-charts.md) for examples and data limits.
|
|
16
|
+
MIT
|
package/dist/package.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var version = "4.0.
|
|
1
|
+
var version = "4.0.2";
|
|
2
2
|
export { version };
|
package/dist/route.mjs
CHANGED
|
@@ -79,11 +79,13 @@ function decideRoute(req, state) {
|
|
|
79
79
|
const connected = auth !== "none";
|
|
80
80
|
const syncCommand = syncCommandFor(req.site ?? req.siteHint, coverage);
|
|
81
81
|
const tables = [...new Set(coverage.flatMap((need) => need.kind === "window" ? [need.table] : need.tables))];
|
|
82
|
+
const searchTypes = [...new Set(coverage.flatMap((need) => need.searchType && need.searchType !== "web" ? [need.searchType] : []))];
|
|
82
83
|
const notConnected = {
|
|
83
84
|
kind: "prompt",
|
|
84
85
|
reason: {
|
|
85
86
|
kind: "not-connected",
|
|
86
|
-
tables
|
|
87
|
+
tables,
|
|
88
|
+
...searchTypes.length > 0 ? { searchTypes } : {}
|
|
87
89
|
},
|
|
88
90
|
nextCommand: CONNECT_COMMAND
|
|
89
91
|
};
|
|
@@ -162,7 +164,11 @@ function routeMessage(route, req, auth) {
|
|
|
162
164
|
}
|
|
163
165
|
const next = route.nextCommand;
|
|
164
166
|
switch (route.reason.kind) {
|
|
165
|
-
case "not-connected":
|
|
167
|
+
case "not-connected": {
|
|
168
|
+
const types = route.reason.searchTypes ?? [];
|
|
169
|
+
const slice = types.length > 0 ? `${types.join(", ")} ` : "";
|
|
170
|
+
return `${route.reason.tables.length > 0 ? `The Store has no ${slice}${route.reason.tables.join(", ")} data for ${site}, and Google is not connected.` : `\`${req.label}\` needs Search Console, and Google is not connected.`} Run \`${next}\` to connect Google and sync the Site, or \`${LOGIN_COMMAND}\` to query Search Console directly.`;
|
|
171
|
+
}
|
|
166
172
|
case "no-data": return `The Store has no ${route.reason.tables.join(", ")} data for ${site}. \`${req.label}\` reads synced data only. Run \`${next}\` first.`;
|
|
167
173
|
case "live-only": return `\`${req.label}\` runs against the live Search Console API only. Run \`${next}\`.`;
|
|
168
174
|
case "store-only": return `\`${req.label}\` reads synced data only. Remove --live. If the Store has no data for ${site}, run \`${next}\` first.`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.0.
|
|
4
|
+
"version": "4.0.2",
|
|
5
5
|
"description": "CLI for Google Search Console and Bing with hosted or local authentication, data exports, and an MCP server",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -44,16 +44,16 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@clack/prompts": "^1.8.1",
|
|
46
46
|
"@duckdb/node-api": "1.5.5-r.5",
|
|
47
|
-
"@gscdump/analysis": "^4.0.
|
|
48
|
-
"@gscdump/contracts": "^4.0.
|
|
49
|
-
"@gscdump/engine": "^4.0.
|
|
50
|
-
"@gscdump/engine-gsc-api": "^4.0.
|
|
51
|
-
"@gscdump/sdk": "^4.0.
|
|
47
|
+
"@gscdump/analysis": "^4.0.2",
|
|
48
|
+
"@gscdump/contracts": "^4.0.2",
|
|
49
|
+
"@gscdump/engine": "^4.0.2",
|
|
50
|
+
"@gscdump/engine-gsc-api": "^4.0.2",
|
|
51
|
+
"@gscdump/sdk": "^4.0.2",
|
|
52
52
|
"@modelcontextprotocol/sdk": "^1.30.1",
|
|
53
53
|
"citty": "^0.2.2",
|
|
54
54
|
"consola": "^3.4.2",
|
|
55
55
|
"google-auth-library": "^11.1.0",
|
|
56
|
-
"gscdump": "^4.0.
|
|
56
|
+
"gscdump": "^4.0.2",
|
|
57
57
|
"ofetch": "^1.5.1",
|
|
58
58
|
"open": "^11.0.4",
|
|
59
59
|
"proper-lockfile": "^4.1.2",
|
package/skills/gscdump/SKILL.md
CHANGED
|
@@ -20,8 +20,10 @@ Example: `gscdump query --site=SITE --start=DATE --end=DATE -d page -f json`.
|
|
|
20
20
|
2. Keep the requested Site, dates, dimensions, and task scope. A request for pages does not need query dimensions.
|
|
21
21
|
3. Before local queries, check coverage with `gscdump store stats --site SITE --json`.
|
|
22
22
|
Use `gscdump sync --site SITE --status --json` when you need coverage, gaps, or sync-state details.
|
|
23
|
+
On a fresh Store, `store stats` exits 1 and says it has no data. Continue with the bounded sync.
|
|
23
24
|
4. Read the table dimensions and watermarks. Sync only missing tables and the requested dates, once per task.
|
|
24
25
|
5. Use `sync --json`. Read its completion result before deciding what to do next. Never repeat a successful sync.
|
|
26
|
+
6. If the user asks for saved rows, check `meta.source: "local"` in the query result. A successful query can answer live when its table has no synced data.
|
|
25
27
|
|
|
26
28
|
If the task only asks about deletion, explain the scope and ask for consent.
|
|
27
29
|
You may read Store metadata with `store stats` and `sync --status`.
|
|
@@ -268,6 +270,7 @@ gscdump sync --site example.com --json
|
|
|
268
270
|
- `--dry-run` prints the planned dates and the fewest calls without calling Google.
|
|
269
271
|
- `--all-sites` syncs every verified Site, one after another.
|
|
270
272
|
- Use the user's date range. If the user names a range, pass `--start` and `--end`, not `--full`.
|
|
273
|
+
- If the user excludes rollups, pass `--no-rollups` on the sync command.
|
|
271
274
|
- Empty Store metadata is expected before the first sync. It does not prove zero traffic.
|
|
272
275
|
|
|
273
276
|
## Query rows
|
|
@@ -278,6 +281,8 @@ gscdump query --site example.com --dimensions page,query \
|
|
|
278
281
|
```
|
|
279
282
|
|
|
280
283
|
- Dimension names are singular: `page`, `query`, `date`, `country`, `device`.
|
|
284
|
+
- A page breakdown uses `--tables pages` for sync and `-d page` for query.
|
|
285
|
+
`-d page,query` needs `page_queries`; syncing only `pages` does not fill that table.
|
|
281
286
|
- Filters: `--query`, `--page`, `--country`, `--device`,
|
|
282
287
|
`--search-appearance`. Prefixes: bare equals, `~` contains, `!~` not
|
|
283
288
|
contains, `re:` regex, `!re:` not regex, `!` not equals.
|