

To connect Google Search Console to Claude (or any script) through the API, create a Google Cloud service account, enable the Search Console API, add the service account as a user in your Search Console property, and give Claude the path to the JSON key file. From then on Claude can pull your queries, pages and positions with a few lines of Python, with no export to CSV and no third-party connector.
This is the setup we use at MaslonLabs to analyze our own sites, so the steps and the pitfalls below come from doing it, not from the documentation alone. It takes about 15 minutes.
What You Need
- A Google account that is an owner or full user of the Search Console property.
- A Google Cloud project (free to create). The Search Console API is free to use within Google’s usage quotas.
- Python 3 with the
google-authandrequestspackages (pip install google-auth requests).
Step 1: Create a Project and Enable the Search Console API
- Open the Google Cloud console and create a project, or pick an existing one.
- Go to APIs & Services, then Library, search for Google Search Console API and click Enable.
Enable it in the same project that will own the service account, or every request will fail with a 403 error.
Step 2: Create a Service Account and a JSON Key
- In IAM & Admin, open Service Accounts and create a service account. It does not need any roles.
- Open the account, go to Keys, then Add key, Create new key, choose JSON and create it.
- Save the downloaded file somewhere safe, for example
gsc-key.json, outside any project folder you share or commit.
Google shows the private key only once. If you lose the file you cannot download it again, but you can create a new key for the same service account without affecting the old ones.
Step 3: Add the Service Account in Search Console
This is the step people miss. The service account can only see properties it has been added to.
- Open Search Console and select the property.
- Go to Settings, then Users and permissions, then Add user.
- Paste the service account email (it ends in
iam.gserviceaccount.com) and choose a permission. Restricted is enough to read data.
Step 4: Test the Connection
List the properties the service account can see:
from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession
creds = service_account.Credentials.from_service_account_file(
"gsc-key.json",
scopes=["https://www.googleapis.com/auth/webmasters.readonly"],
)
session = AuthorizedSession(creds)
r = session.get("https://www.googleapis.com/webmasters/v3/sites")
print(r.status_code, r.json())
A 200 response with your properties means everything works. A property added with Restricted permission shows up as siteRestrictedUser. If the list is empty, the service account has not been added to the property yet.
Step 5: Pull Your Queries and Pages
import datetime as dt
import urllib.parse
site = urllib.parse.quote("sc-domain:example.com", safe="")
end = dt.date.today() - dt.timedelta(days=2)
start = end - dt.timedelta(days=90)
body = {
"startDate": str(start),
"endDate": str(end),
"dimensions": ["query", "page"],
"rowLimit": 25000,
"startRow": 0,
}
url = f"https://www.googleapis.com/webmasters/v3/sites/{site}/searchAnalytics/query"
rows = session.post(url, json=body).json().get("rows", [])
for row in sorted(rows, key=lambda x: -x["impressions"])[:10]:
print(row["keys"], row["clicks"], row["impressions"], round(row["position"], 1))
This returns your top query and page pairs for the last 90 days. Change the dimensions to ["query"] or ["page"] for a simpler view, and use startRow to page through more than 25,000 rows.
Pitfalls We Ran Into
- Property format. A domain property is addressed as
sc-domain:example.comand a URL-prefix property ashttps://example.com/. Use the exact value from the sites list, and URL-encode it in the request path. - Data delay. Search Console data is a couple of days behind, so end your date range two days before today.
- Anonymized queries are missing. Query-level rows leave out rare queries that Google anonymizes, so the sum of query rows is lower than the page totals.
- Read-only scope. Use the
webmasters.readonlyscope unless you really need to submit sitemaps or change settings. - Rate and row limits. One request returns up to 25,000 rows. Page with
startRowinstead of widening the date range.
Using It With Claude
Give Claude the path to the key file and the property name. Do not paste the contents of the key into a chat, because it contains a private key. Claude (for example in Claude Code) can then run the script, read the results and answer questions such as which queries have many impressions but few clicks, or which pages rank on page two.
Keep the key out of git, keep the permission on Restricted, and delete the key in the Google Cloud console when you no longer need it.
Service Account vs. an MCP Server
An MCP server wraps the same API so that Claude can call it as a tool, which is convenient for long sessions. A plain script is simpler to audit and has fewer moving parts. Both need the service account setup above. See our overview of the best MCP servers for SEO specialists if you want the tool version, and how to track AI performance in Google Search Console for what to look for in the data.
Frequently Asked Questions
Can Claude access Google Search Console?
Yes. Claude can read Search Console data through the Search Console API when it has a way to authenticate, for example a service account key file that you add as a user in your property. Share only the file path, never the contents of the key.
Do I need an MCP server to connect Search Console to Claude?
No. An MCP server is optional. A short Python script that uses a service account can pull the same data, and Claude can run it for you.
Why does the service account see no sites?
The service account must be added as a user in each Search Console property under Settings, Users and permissions. Without that, the sites list is empty.
What permission does the service account need?
Restricted permission is enough to read search analytics. Use the read-only API scope unless you need to change settings or submit sitemaps.
Why are my query totals lower than my page totals?
Search Console leaves out queries that Google anonymizes for privacy, so query-level rows add up to less than the totals for the same pages.
Is it safe to give Claude a service account key?
Share the path to the key file instead of its contents, keep the permission on Restricted, keep the file out of version control, and delete the key in Google Cloud when you are done.



