Blog · Claude Code × SEO

Claude Code for SEO: query Search Console from your terminal

Published July 17, 2026 · 7 min read

Claude Code becomes genuinely useful for SEO the moment it can read your Search Console data — and that takes one OAuth command. Most Claude Code SEO advice stops at crawl scripts and content briefs. Fine, but the questions that decide what you actually do on Monday — which queries are slipping, which pages earn less CTR than their position should, whether that dip is real or just Google's reporting lag — are data questions. This guide wires Claude Code to Google Search Console, walks through three queries worth stealing, covers the 2–3 day GSC lag that fools naive automations, and ends with a live pinned dashboard (embedded below — real data, not a mockup).

Where Claude Code fits in an SEO workflow

A coding agent already covers more of SEO than most people expect, because so much of technical SEO is code: it can audit your templates for canonical and hreflang mistakes, trace a redirect chain through your config, regenerate a sitemap, or grep server logs for crawl anomalies. It's also a competent drafting partner for briefs and on-page rewrites. What it cannot do, bare, is see performance — clicks, impressions, positions live in Search Console, behind OAuth and an API with its own quirks. So the loop breaks exactly where it matters: the agent can propose fixes but can't check what needs fixing or whether last month's fix worked.

You can bridge that with pasted CSV exports, but every export is a snapshot that's stale by tomorrow, and the agent burns context re-learning your column conventions each session. The durable fix is a data backend the agent can query directly — that's what TableBI is, and the general version of this argument is in Claude Code for marketing. Below is the SEO-specific path.

Set up the Claude Code SEO skill

Two minutes of setup: install the CLI, sign in, and plant the skill that teaches your agent the whole vocabulary. (Skills are markdown runbooks in ~/.claude/skills — the mechanism is worth understanding, and we unpack it in Claude Code marketing skills.)

terminal
npm i -g @tablebi/cli
tablebi login
tablebi install

Then connect Search Console. One command per property; the browser opens for OAuth:

terminal
tablebi connect gsc --site sc-domain:example.com

Data syncs into two altitudes. search_console_raw holds rows exactly as GSC reports them — query, page, position, clicks, impressions, by date — nothing averaged away. The unified facts table holds the cross-channel view, useful once GA4 or ad platforms join the party. Each new Claude Code session starts by rehydrating context — definitions, connected sources, freshness, command cheatsheet:

terminal
tablebi context --json

From here you stop typing commands and start stating intent — "which queries are slipping?" — and the agent writes the SQL. The next section shows what it writes.

Three Search Console queries worth stealing

1. Queries gaining or losing impressions. Compare the last 14 days against the 14 before — the fastest way to see a core update or a decaying page portfolio in one table. Note the window anchors to MAX(date) in the data, not the wall clock:

claude code → tablebi
tablebi ask "SELECT query,
             SUM(CASE WHEN date >= (SELECT MAX(date) FROM search_console_raw) - 13
                 THEN impressions ELSE 0 END) AS imp_recent,
             SUM(CASE WHEN date < (SELECT MAX(date) FROM search_console_raw) - 13
                 THEN impressions ELSE 0 END) AS imp_prior
             FROM search_console_raw
             WHERE date >= (SELECT MAX(date) FROM search_console_raw) - 27
             GROUP BY query
             ORDER BY (imp_recent - imp_prior) ASC LIMIT 20"

2. Pages whose CTR underperforms their position. Ranking in the top five but getting clicked like page two usually means the title or snippet is losing the SERP — the cheapest wins in SEO, because a rewrite needs no new links:

claude code → tablebi
tablebi ask "SELECT page, AVG(position) AS avg_pos,
             ctr(SUM(clicks), SUM(impressions)) AS ctr,
             SUM(impressions) AS impressions
             FROM search_console_raw
             WHERE date >= (SELECT MAX(date) FROM search_console_raw) - 28
             GROUP BY page
             HAVING AVG(position) <= 5
             ORDER BY ctr ASC LIMIT 20"

That ctr() is a definition macro — the backend computes it the same way in every query, so the agent never re-derives it slightly differently on a Tuesday.

3. The portfolio view. If you run several properties — client sites, a programmatic portfolio, docs plus marketing site — aggregate by site for the one-glance answer to "where did this week's traffic move?":

claude code → tablebi
tablebi ask "SELECT site, SUM(clicks) AS clicks, SUM(impressions) AS impressions,
             ctr(SUM(clicks), SUM(impressions)) AS ctr
             FROM search_console_raw
             WHERE date >= (SELECT MAX(date) FROM search_console_raw) - 28
             GROUP BY site ORDER BY clicks DESC"

The 2–3 day GSC lag, and how not to get fooled by it

Here's the trap every homegrown Search Console automation falls into at least once: Google's final GSC data officially lags around two to three days. A script that checks "yesterday's clicks" reads zero, and someone gets paged over a traffic collapse that never happened.

Two mechanisms keep the agent honest here. First, every query answer carries a trust block: per-source freshness (the exact date each source runs through), caveats, and lineage. Your agent reads "search_console: data through Monday" and reports the window it actually analyzed instead of raising a false alarm — and the caveats stop category errors like comparing GSC clicks with GA4 sessions, which are different populations and shouldn't be expected to match. Second, the query layer itself refuses clock-anchored date math like current_date; windows are written against the data's own high-water mark:

the honest date window
-- anchors to the freshest row, not the wall clock,
-- so a 28-day window is 28 days of *actual* data
WHERE date >= (SELECT MAX(date) FROM facts) - 28

Rule of thumb: treat GSC's last 2–3 days as provisional. Anchor every window to MAX(date), and let the freshness readout — not your memory — say how current the numbers are.

Pin a weekly SEO dashboard

Once a query earns its keep, stop re-running it — pin it. One command turns SQL into a dashboard at a public, read-only URL that refreshes itself as new data syncs in (on a schedule, and when someone opens it):

claude code → tablebi
tablebi pin --title "SEO weekly" \
  --widget "Daily clicks (28d)::line=SELECT date, SUM(clicks) AS clicks FROM search_console_raw WHERE date >= (SELECT MAX(date) FROM search_console_raw) - 28 GROUP BY date ORDER BY date" \
  --widget "Top queries=SELECT query, SUM(clicks) AS clicks, SUM(impressions) AS impressions FROM search_console_raw WHERE date >= (SELECT MAX(date) FROM search_console_raw) - 28 GROUP BY query ORDER BY clicks DESC LIMIT 20"
✓ published → https://dk.tablebi.com/d/dsh_…  (public, read-only, self-refreshing)

::line renders a line chart; widgets without it render as tables. The result is a link you can hand to a client or check from your phone. Here's a real one — an SEO portfolio overview pinned from live Search Console data exactly this way:

That dashboard is not a screenshot and nobody rebuilds it on Mondays — it keeps itself current. If you want to go deeper on the dashboard side (widget types, sharing, refresh behavior), that's covered in Claude Code dashboards; the cross-channel version of this workflow, with GA4 and paid sources in the same tables, is in Claude Code for marketing.

FAQ

Can Claude Code access Google Search Console?

Not by itself — it's a coding agent with no GSC connection. With TableBI installed, tablebi connect gsc --site sc-domain:example.com runs the OAuth flow in your browser, and from then on the agent queries your Search Console data with read-only SQL from the terminal.

Why does my Search Console data stop 2–3 days ago?

That's Google, not a broken sync: GSC's final data officially lags around 2–3 days. Every TableBI query carries a freshness readout showing the exact date each source runs through, so your agent reports "data through Monday" instead of misreading the lag as a traffic collapse.

Is there a Claude Code SEO skill I can install?

Yes. npm i -g @tablebi/cli, then tablebi login and tablebi install. That drops a skill into ~/.claude/skills, after which the agent understands "connect my Search Console", "which queries are slipping", or "pin a weekly SEO dashboard".

Can I share results with someone who doesn't use a terminal?

Yes — pin the analysis. tablebi pin turns queries into a dashboard at a public, read-only URL that refreshes itself as new data syncs. Send the link; they never touch the CLI.

Try it

Give your Claude Code a data backend in five minutes.

terminal
npm i -g @tablebi/cli && tablebi install