On this page
Google Search Console unlocks Wire's most powerful features: keyword cannibalization detection, SEO rewriting, and content gap analysis. None of that works until Wire has three things: a Google Cloud OAuth client, credentials in .env, and token.json next to wire.yml. The gsc-setup wizard gets you from zero to all three in about five minutes.
The one command you need
From your site directory (where wire.yml lives), run:
python -m wire.chief gsc-setup
The wizard does five things in order:
- Opens Google Cloud Console Credentials in your browser.
- Waits for you to create an OAuth Desktop-app client and download the JSON.
- Reads the downloaded
client_secret_*.json, extractsclient_idandclient_secret, writes them to.env. - Runs the OAuth consent flow in your browser and writes
token.jsonnext towire.yml. - Calls
sites().list()to verify access and prints the GSC properties your Google account owns.
When it finishes, run python -m wire.chief data and Wire starts pulling search metrics.
Google Cloud walkthrough
The wizard pauses after it opens the browser so you can complete the Cloud Console steps. In the browser:
- Pick or create a project. The name is irrelevant. Wire never sees it. The project is just a container Google needs before it hands out credentials.
- Enable the Search Console API. APIs & Services > Library > search "Search Console" > Enable. Without this, your client ID will authenticate but every API call returns a permission error.
- Configure the OAuth consent screen. User type: External. Add your own email as a test user. No app verification is required because you are the only user.
- Create OAuth client credentials. Credentials > Create credentials > OAuth client ID > Application type: Desktop app. Name it "Wire" (or anything). Google generates a client ID and secret and offers a JSON download.
- Download the JSON. Click the download icon next to the new client. The file is named
client_secret_<long-id>.apps.googleusercontent.com.jsonand lands in your Downloads folder.
Back in the terminal, paste the full path to the downloaded file. On Windows Git Bash, use /c/Users/you/Downloads/client_secret_...json. The wizard parses the JSON and fills .env for you.
What the wizard writes
Three files end up next to wire.yml:
| File | What it is | Rotate? |
|---|---|---|
.env | GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET | Google Cloud Credentials |
token.json | OAuth consent receipt from your Google account | Re-run gsc-setup or gsc-auth |
client_secret_*.json | Original download. Wire no longer needs it after setup. Delete it. | Regenerate in Google Cloud |
All three contain secrets. wire.chief init writes a .gitignore that excludes them. If you already initialized before that gate shipped, re-run init once. It preserves your existing .gitignore. Wire's build refuses if any of these files end up tracked in git.
Why Google splits this into three pieces
Each file answers a different question, which is why "just give me a token" does not exist as an option.
The Google Cloud project answers "does this app exist at all?" Without a project, Google will not hand out credentials. The project is purely administrative.
GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in .env answer "which app is calling right now?" Every Wire install presents this ID card on every API call. Quota is tracked per credential, so each customer has their own pair. The .env file is the right place because these are per-machine secrets, not part of your site config.
token.json answers "did the human say yes?" The client ID proves Wire is Wire. It does not prove you, the user, want Wire reading your Search Console data. That permission gets recorded separately when you click Allow in the consent screen. Google writes a one-time consent receipt (token.json) valid only for your Google account plus the exact client ID you configured. Lose the file, re-run gsc-auth. Revoke access in your Google account, and token.json stops working immediately.
gsc-setup vs gsc-auth
Two commands exist because they do different work.
gsc-setup(interactive, use this first) walks through Google Cloud, parsesclient_secret_*.json, writes.env, runs OAuth, and verifies. Safe to re-run any time; it updates the existing keys in place.gsc-auth(low-level, use this to refresh) runs only the OAuth consent flow. It requiresGOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETto already be set. Use this when you already have working.envcredentials buttoken.jsonexpired, went missing, or you want to switch Google accounts.
Wire's error messages point at the right one depending on what is missing. If the keys are missing, Wire tells you to run gsc-setup. If only token.json is missing, Wire suggests gsc-auth.
Troubleshooting
"client_secret file not found". Double-check the path you pasted. On Windows, use forward slashes in Git Bash (/c/Users/.../Downloads/...) or the full Windows path in PowerShell and cmd. Quotes around the path are fine; the wizard strips them.
"not a client_secret file. Expected 'installed' or 'web' top-level key". You downloaded the wrong JSON. Make sure you clicked DOWNLOAD next to an OAuth 2.0 Client ID, not next to a Service account or API key. Desktop apps nest their credentials under "installed".
"No GSC property found matching 'https://example.com'". The Google account you authenticated with does not own the property in Search Console. Add the site at search.google.com/search-console, verify ownership (DNS, HTML file, or meta tag), then re-run python -m wire.chief data. Wire lists the properties your account actually has so you can confirm the mismatch.
"Google Search Console credentials not found" after running the wizard. The .env file was written but Wire did not reload it for this process. Close the terminal, reopen it in the same directory, and run python -m wire.chief data. The wizard already wrote the keys correctly; only the current shell is stale.
"Error 403: access_denied" in the browser. You did not add yourself as a test user on the OAuth consent screen. Go back to Cloud Console > OAuth consent screen > Test users > Add your email, then re-run gsc-setup.
After setup
Once the wizard finishes cleanly, everything downstream just works:
python -m wire.chief data # Pull search metrics into .wire/gsc.db
python -m wire.chief audit # Now includes SEO analysis
The audit now shows keyword overlaps, content gaps, reword opportunities, and dead pages computed from real search data. See the workflow guide for the full daily sequence and the SEO reference for the lint rules that trigger on GSC evidence.