Claude Code for SEO: what it can fix in your repository, and what it cannot see
Claude Code can fix almost everything SEO touches in your code: titles, descriptions, rendering, internal links, sitemaps, structured data and the copy itself, in minutes. What it cannot see is search data: which queries your pages are shown for, where they rank, how often they are clicked, and who beats you. So give it that data, one finding at a time, keep each change small, and judge it in Search Console over 28 days.
By Théophile Louvart, founder of Porteur · Updated 23 September 2026 · Markdown
The split that decides everything
Claude Code reads and edits the files in the repository it runs in, and it can run shell commands: build the site, start it, fetch a page with curl. Everything that lives in your code is within its reach.
Search performance does not live in your code. It lives in Search Console, which records the queries each page appears for, its average position, impressions and clicks. It also lives with search data providers, who know volumes and who ranks. None of that is in the repository, so Claude Code does not know it unless you bring it in.
Ask it "improve the SEO of my pricing page" without data and it will do its honest best from general knowledge: tidy the title, add a description, maybe suggest keywords. The keywords are guesses. Ask it "/pricing is shown for 'invoice software for freelancers' at position 9 and the title says 'Plans'" and it has a precise job it can do well.
| Task | Where it stands | Why |
|---|---|---|
| Titles, descriptions, h1, canonicals across every route | Good at it | All in code; it can check the served HTML after the change |
| Server rendering: content present before JavaScript | Good at it | It can build, curl and compare, then move content to the server |
| Sitemap, robots.txt, 404 status, redirects | Good at it | Files and config, verifiable with a command |
| Structured data that matches the page | Good at it | It writes JSON-LD from what the page already shows |
| Internal links between related pages | Good at it | It can read every page and add links in the right places |
| Rewriting a page for the query it is shown for | Needs data | It must be told the query, from Search Console |
| Choosing which page to work on first | Needs data | Impressions and positions decide it, not the code |
| Deciding what new page to write | Needs data | Needs volumes, who ranks, and a check that no page already covers it |
| Estimating traffic, volumes or positions | Do not delegate | Anything it states without data is invented |
| Generating many pages at once | Do not delegate | Google's spam policies name it as scaled content abuse |
Bringing search data into the session
There are three ways to give Claude Code the figures it lacks. Start with the first; move to the second when you are tired of exporting.
A Search Console export in the repository
In Search Console, open Performance, set the date range to the last 28 days, and export. Put the CSV files in a folder such as seo-data/ and add that folder to .gitignore. Claude reads them like any other file.
An MCP server for Search Console
An MCP server exposes Search Console's API as tools the agent calls itself: it can ask which queries a page is shown for while it edits that page. The guide on a Google Search Console MCP server walks through the setup.
A report with findings
A written report that already says which page, which query and what to change can be pasted in, or read over MCP if its maker offers that. The agent then works from findings instead of raw rows.
Adding an MCP server is one command. For a remote server:
claude mcp add --transport http <name> <url> --header "Authorization: Bearer <token>"
# or a server that runs locally on your machine
claude mcp add <name> -- <command> [args]Mind the scope. The default, local, keeps the server in ~/.claude.json for you alone. Project scope writes .mcp.json at the repository root, which is committed and shared, so a token must never be written there. User scope makes the server available in all your projects.
A worked session, from finding to judgement
The setup: yourproduct.com has a guide at /guides/csv-import. The Search Console export shows it is shown for "import csv into postgres" at an average position of 12, with impressions and almost no clicks. Its title is "Importing data | YourProduct". Position 12 is the top of the second page: close enough that a page which plainly answers the query can move up.
The prompt gives the agent the data, the page and the limits:
seo-data/queries.csv is a Search Console export (Queries tab, last 28 days).
The page /guides/csv-import is shown for "import csv into postgres" at an average
position of 12, and its title does not say that.
1. Read app/guides/csv-import/page.tsx and show me the current title, meta
description, h1 and first paragraph.
2. Propose one change: a title and h1 that say "import a CSV into Postgres" in plain
words, and a first paragraph that answers it. Keep the URL. Do not touch other pages.
3. Apply it in one commit, build, and curl the page to show the served title and h1.The diff that comes back is small, which is the point:
--- a/app/guides/csv-import/page.tsx
+++ b/app/guides/csv-import/page.tsx
export const metadata = {
- title: "Importing data | YourProduct",
- description: "Learn about importing data with YourProduct.",
+ title: "Import a CSV into Postgres in three steps | YourProduct",
+ description: "Import a CSV file into a Postgres table: map the columns, fix types and dates, and load it without writing COPY by hand.",
alternates: { canonical: "/guides/csv-import" },
};
export default function Page() {
return (
<article>
- <h1>Importing data</h1>
- <p>YourProduct makes it easy to work with your data from many sources.</p>
+ <h1>Import a CSV into Postgres</h1>
+ <p>Upload the CSV, check the column types YourProduct detects, and load it
+ into a new or existing Postgres table. Dates and empty cells are handled
+ for you.</p>Before you accept it, check three things. The new title says the query in the searcher's words. The first paragraph answers it, instead of introducing the company. And the claims in the copy are true of your product: the agent writes plausible sentences, and "dates and empty cells are handled for you" must be something your importer really does.
Then judge it. Note the date you shipped. Four weeks later, in Search Console, filter on the page, compare the last 28 days with the 28 days before, and look at that query: position, impressions, clicks. Because the commit changed one page for one query, whatever moved can be read as the result of that change. Ship five pages at once and you will not know which one worked.
Rules to put in CLAUDE.md
CLAUDE.md at the repository root holds the project instructions Claude Code reads at the start of every session. A short SEO section there stops the classic mistakes before they happen, in every session, without you repeating them.
## SEO work
- Never invent figures. No traffic, positions, clicks or volumes unless they come from
a file in seo-data/ or an MCP tool, and say which one.
- One change per commit for SEO work, with the query and page it targets in the message.
- Do not create a new page when an existing page covers the topic: improve that page.
- Do not generate pages in bulk from templates, lists of keywords or lists of cities.
- Every public page keeps: a unique title (about 60 characters), a unique meta
description (about 155), one h1, a self-referencing canonical, content present in the
server HTML without JavaScript, internal links as <a href>.
- Never vary a page's content by user agent or referrer.
- Before calling SEO work done, curl the built page and show the title, h1 and canonical.
Each line answers a mistake agents make on SEO work. Invented figures sound authoritative in a commit message. A new page on a topic you already cover competes with the old one for the same searches. Bulk generation is what Google's spam policies call scaled content abuse: many pages made mainly to rank, whatever produced them. The curl check at the end catches the change that looked right in the source and never reached the served HTML.
An audit as a skill
CLAUDE.md holds rules. A repeatable procedure, such as a full technical audit, belongs in a skill: a SKILL.md file in .claude/skills/<name>/ that you run as /<name>. The guide on a Claude SEO skill gives a complete one to paste, which maps your routes, fetches the built HTML and writes each finding with a file, a fix and a check.
Run the audit when you set up, before a launch and after a large refactor. Between audits, the daily work is the loop above: one query, one page, one change, judged four weeks later.
A weekly routine for a founder
- Export the last 28 days from Search Console, or ask the MCP server, and find pages at positions 4 to 20 with impressions and few clicks.
- Pick one page and the one query it is shown for most. Check its title and first paragraph say that query plainly.
- Give Claude Code the page, the query, the position and the limits. Review the diff for claims that are not true of your product.
- Ship it in its own commit, and write the date and the query in a log file.
- Look back at the change from four weeks ago in the same log. Keep what worked, and learn what did not.
That is an hour a week, and after a few months it is a record of what actually moves your site, which no generic advice can give you.
Questions
It can audit everything in your code and in the HTML your server sends: titles, descriptions, canonicals, rendering, sitemaps, status codes, links and structured data. Give it a written procedure, as a skill, so it checks the served HTML and not only the source. It cannot audit your rankings or rivals without search data.
They answer different needs. Claude Code works inside your repository, so it can make and verify the change itself. A chat assistant gives advice you apply by hand. Neither knows your search data unless you give it.
It can draft a page, but you should decide which page to write from search data, check that no existing page already covers it, and read every claim before publishing. Pages produced in bulk mainly to rank fall under Google's scaled content abuse policy, whatever wrote them.
Search Console data arrives about two to three days late, and a change needs time to be recrawled and settle. Compare 28 days after the change with the 28 days before, for the page and the query you targeted.
Yes, if the code is in a repository you can open locally. Check rendering first: if the site is a single page app, the HTML it serves may hold almost nothing before JavaScript runs, and that matters more than any title.
Check my site, free
Before you hand Claude Code a finding, get three for free: the check reads your site, the searches around it and the rivals on them from a URL, in about thirty seconds.
- Free check, no card
- Read-only, your own accounts
- Readable by your agent
Read next
- GuideA Claude SEO skill for your repository: what it should hold, and one to copy
- GuideGoogle Search Console MCP: giving Claude or Cursor your search data
- GlossaryModel Context Protocol (MCP)
- GuideHow to use Google Search Console in ten minutes a week
- GuideStriking distance keywords: the searches one page from the light
- GuideChatGPT for SEO: what it does well, what it invents
- GlossaryScaled content abuse
- GuideSEO for sites built with AI app builders: Lovable, Bolt, v0 and Replit