Troubleshooting
Every failure below names its cause and its exact recovery command. Diagnose first with doctor and auth status --online — setup never uploads credentials anywhere, so a broken state is always local and repairable.
Client shows no tools
- Diagnose: the entry uses a relative command or a PATH-only binary. GUI apps ignore your shell PATH entirely.
- Fix: regenerate with
config print --client <name>, apply the absolute paths it prints, then restart the client. Confirm the merge touched onlymcpServers.gsc.
AUTH_REQUIRED / REAUTH_REQUIRED
- Diagnose: the server started without credentials — which is normal and by design. The tool response names the fix.
- Fix: run
auth loginin a terminal and complete the browser sign-in there. The MCP server never opens browsers by itself, so there is no in-client button to click.
PROPERTY_NOT_ALLOWED
- Diagnose: the requested property identifier is missing from that instance’s allowlist — usually a typo, a trailing slash mismatch (
https://example.comvshttps://example.com/), or asc-domain:prefix on a URL-prefix property. - Fix: compare byte-for-byte against
doctor’s reportedsite_urls, correct the identifier, and re-run setup with the exact--sitevalue if the allowlist itself is wrong. Tool arguments can never widen the allowlist.
Permission denied vs API_DISABLED vs quota
- Diagnose: run
auth status --online— the minimal Google validation. It separates the three cases instead of guessing: PROPERTY_PERMISSION_DENIED— the signed-in account (or service account) lacks access to that property. Fix: an Owner grants it under Search Console → Settings → Users and permissions.API_DISABLED— the Search Console API (or Indexing API, for submit tools) is not enabled on the Cloud project. Fix: enable it in the API Library for the same project that owns the credential.QUOTA_EXCEEDED— the project hit a Search Console API limit. Fix: wait for the quota window, narrow the query, and check the published quotas before retrying.
invalid_grant
- Diagnose: the stored refresh token is dead — revoked at Google, rotated, or expired. One possible cause, never the automatic diagnosis: grants to an External app still in Testing expire about seven days after consent (see Credentials).
- Fix:
auth loginagain in a terminal. If expiry recurs every week, move the OAuth app to In production or switch to a service account.
Partials and REQUEST_BUDGET_EXCEEDED
- Diagnose: the request asked for more rows or URLs than one call can carry. Partial results say which rows are missing.
- Fix: lower row or URL counts, split the range, and retry only the pending slice — never the whole report at a larger size.
DATASET_EXPIRED
- Diagnose: export and paging datasets live 15 minutes per profile and never cross profiles. The source query aged out.
- Fix: re-run the source query to mint a fresh dataset, then page or export within the window.
Scopes and the Indexing API boundary
- Default scope is
webmasters.readonly.fulladdswebmastersandindexing— never Gmail, Drive, or Analytics. A submit tool failing under readonly is expected: switch access withsetup access full, restart the client, confirm withdoctor. - The Indexing API notifies Google only for pages with
JobPostingmarkup orBroadcastEventembedded in aVideoObject. Any other URL fails by design — it is not a general indexing tool, a notification only requests a crawl, and the default quota is 200.
Nothing in setup or doctor ever transmits your secrets anywhere except Google’s own OAuth and API endpoints during sign-in and queries. If a fix ever asks for your key material outside your terminal, it is not from this project.