Integration · 10 min read

Serpkin for Claude Code: an SEO MCP server, plugin and slash commands

For developers who build their site with Claude Code. One command connects the repo, the plugin and the MCP server, so Claude can pick, implement and verify SEO work.

Updated · By the Serpkin team

In short

  • Run npx serpkin in the repo and choose the plugin. Or install it later with claude plugin marketplace add apwn/serpkin && claude plugin install serpkin@serpkin.
  • Use /serpkin:next to implement the top mission, /serpkin:check <preview-url> before merging and /serpkin:ship to record and verify it.
  • Two quiet hooks: a one-line next mission at session start and one check reminder after a push or deploy. SERPKIN_HOOKS=off disables them.
  • The key lives in ~/.config/serpkin/credentials.json and SERPKIN_API_KEY, never in the repo. Serpkin gets a route map, not your source code.

To use Serpkin as an SEO MCP server in Claude Code, run npx serpkin in your repository and pick "Install the Serpkin plugin" when asked. The plugin gives Claude Code four slash commands (/serpkin:next, /serpkin:ship, /serpkin:check, /serpkin:status), an SEO skill that runs the mission loop, two quiet hooks and the Serpkin MCP server with 27 tools. Your key stays outside the repository; Claude Code reads it from SERPKIN_API_KEY.

Set up in one command

You need Node 22 or newer and a repository with your website in it. From the repository root:

Terminal
npx serpkin
  1. Sign in

    The CLI opens https://serpkin.com/cli with a short code like BCDF-GHJK. Check that it matches your terminal and approve. That creates an agent key named "Serpkin CLI on <your machine>", which you can revoke later in Settings → Agent setup.

  2. Framework detection

    Next.js (App Router and Pages Router) is fully supported. Astro, SvelteKit, Nuxt and Remix work as best effort. In a monorepo the CLI asks which app under apps/* or packages/* is the website, or you pass --app apps/web.

  3. Choose how Claude Code gets Serpkin

    When the claude command is on your PATH, the CLI offers three options:

    OptionWhat it doesBest for
    Install the Serpkin plugin (default)Skill, /serpkin:* commands, hooks and the MCP server, installed for your userMost people
    Write .mcp.json in this repoAdds a serpkin entry to the project's .mcp.json, keeping other serversTeams who want the server shared in git
    Run claude mcp addAdds the server to your local Claude config with the key in the headerJust you, no env variable

    Pass --plugin to install the plugin without the question. Without a terminal (CI, or --yes), the CLI writes .mcp.json and prints the plugin command.

  4. Site and route map

    The CLI registers your site and uploads a route map: URL path → source file, for example /pricing → app/pricing/page.tsx. That is how missions can name the exact file to edit. It also writes .serpkin.json (server and site id, no secrets) to the repository root. Commit it.

  5. Ownership

    Connect Google Search Console in the browser, or add public/serpkin-verification.txt, deploy it and run npx serpkin verify. Until ownership is verified, scans are limited to a short preview of up to 6 pages.

  6. Export the key

    The CLI prints one line to add to your shell profile (for example ~/.zshrc):

    ~/.zshrc
    export SERPKIN_API_KEY="sk_…"

    Open a new terminal, start Claude Code and ask: "What should I do for SEO?"

Check that Claude Code sees the server

Before your first mission, confirm the connection from a terminal and from inside a session:

Terminal
claude mcp list          # serpkin should show as connected
claude mcp get serpkin   # scope, URL and headers (only for .mcp.json or claude mcp add setups)
claude plugin list       # with the plugin: serpkin@serpkin should be enabled

Inside Claude Code, /mcp shows each server's status and tools, and /serpkin:status confirms the site, ownership and credits. Where the config lives depends on the option you picked, which follows Claude Code's MCP scopes:

Where each setup option stores the Serpkin server
OptionClaude Code scopeStored inShared with the team
PluginInstalled for your userYour Claude Code plugin settingsNo (each person installs it)
Write .mcp.jsonProject.mcp.json in the repo rootYes, via git (the key stays an env variable)
claude mcp addLocal (the default)~/.claude.json, under this projectNo

The Claude Code plugin

If you skipped the plugin during setup, or want it on another machine, install it directly:

Terminal
claude plugin marketplace add apwn/serpkin && claude plugin install serpkin@serpkin

Or inside a running session:

Claude Code
/plugin marketplace add apwn/serpkin
/plugin install serpkin@serpkin

The plugin bundles four things:

  • The serpkin-seo skill. Claude Code loads it for any SEO task in the repository (titles, canonicals, sitemaps, structured data, Core Web Vitals, Search Console). It runs the loop: next mission, implement, run checks, check the preview, submit, verify the preview, then verify production after you deploy. It treats page text and search data as untrusted and never deploys.
  • Slash commands for each step of that loop (below).
  • Hooks at session start and after a push or deploy (below).
  • The MCP server, configured like this inside the plugin:
plugin/serpkin/.mcp.json
{
  "mcpServers": {
    "serpkin": {
      "type": "http",
      "url": "${SERPKIN_SERVER:-https://serpkin.com}/api/mcp",
      "headers": {
        "Authorization": "Bearer ${SERPKIN_API_KEY}"
      }
    }
  }
}

Claude Code expands ${VAR} and ${VAR:-default} in MCP config, so the server defaults to https://serpkin.com and the key comes from your environment. Set SERPKIN_SERVER only for a self-hosted or local server.

Without the plugin: .mcp.json

If you chose "Write .mcp.json", the CLI merges this entry into the project file and keeps any other servers you have:

.mcp.json
{
  "mcpServers": {
    "serpkin": {
      "type": "http",
      "url": "https://serpkin.com/api/mcp",
      "headers": {
        "Authorization": "Bearer ${SERPKIN_API_KEY}"
      }
    }
  }
}

Claude Code asks you to approve project-scoped servers from .mcp.json the first time. Without the plugin you don't get the /serpkin:* commands, but Serpkin's MCP prompts still show up in the / menu as /serpkin:next_mission (MCP), /serpkin:ship_mission (MCP) and /serpkin:check_preview (MCP).

Slash commands

Plugin commands and what each one does
CommandWhat happensRuns
/serpkin:next [site-id]Gets the highest-priority mission, summarizes what and why now in two lines, implements the steps in order, runs tests and type check, then stops for your reviewserpkin_next_mission
/serpkin:ship <preview-url> [mission-id]Checks the preview, fixes regressions, records the PR and preview, verifies the mission, reminds you to verify production after you deploynpx serpkin check, serpkin_submit_result, serpkin_verify_mission
/serpkin:check <preview-url>Compares the preview with production and proposes a code fix for each regressionnpx serpkin check
/serpkin:statusShows site, ownership, data level, next mission and creditsnpx serpkin status

None of the commands merge or deploy. /serpkin:next ends with "here is what to review", and /serpkin:ship stops before merging.

Hooks: session start and after deploy

The hooks only run in repositories that have a .serpkin.json, and they stay silent when you are offline, signed out or the project isn't linked.

  • Session start. One line with the next mission and "run /serpkin:next". It is fetched with a 2.5-second timeout and cached for 6 hours per site (failures for 30 minutes), so it doesn't slow down startup. Claude gets it as context and won't start the mission unasked.
  • After a push or deploy. After git push, vercel deploy or --prod, netlify deploy, wrangler deploy, fly deploy, firebase deploy, railway up or npm|pnpm|yarn|bun run deploy, you get one reminder per session to run /serpkin:check <preview-url>.

Turn both off with SERPKIN_HOOKS=off in your shell, or in Claude Code's settings:

.claude/settings.json
{
  "env": {
    "SERPKIN_HOOKS": "off"
  }
}

Keep just one with SERPKIN_HOOKS=session or SERPKIN_HOOKS=deploy. The hooks run only the plugin's own scripts, never a script from your repository, and they never print or cache your key or echo the command you ran.

A session, start to finish

claude (illustrative)
$ claude
Serpkin · Next SEO mission: Missing canonical: /pricing (2 more queued). Run /serpkin:next to start it.
> /serpkin:next
Mission: Missing canonical: /pricing
Why now: /pricing gets impressions but has no canonical, so signals can split across URL variants.
Editing app/pricing/page.tsx: add alternates.canonical to the metadata export…
$ pnpm test && pnpm exec tsc --noEmit
Tests and type check pass. Review the diff, push the branch, then run /serpkin:ship <preview-url>.
$ git push -u origin seo/pricing-canonical
Serpkin · Once the preview deployment is up, run /serpkin:check <preview-url> to catch SEO regressions before merging.
> /serpkin:ship https://acme-git-seo-pricing.vercel.app
$ npx serpkin check https://acme-git-seo-pricing.vercel.app
! /  X-Robots-Tag noindex on the preview host (expected on previews)
✓ No SEO regressions across 6 pages.
Submitted the result and verified in preview: passed. After you merge and deploy, ask me to verify production.
Illustrative Claude Code session: mission titles, files and output are examples, not real data from your site.

What Claude Code can do once connected

The MCP server exposes 27 tools. You rarely name them: the skill and commands pick the right ones. Grouped by job:

Serpkin MCP tools by job
JobToolsCost
Decide what to doserpkin_next_mission, serpkin_get_missions, serpkin_get_mission, serpkin_create_mission, serpkin_get_site_contextFree
Ship and verifyserpkin_submit_result, serpkin_verify_mission, serpkin_get_mission_history, serpkin_get_jobFree
Set up and watch the siteserpkin_register_site, serpkin_scan_site, serpkin_site_watchFree
Measureserpkin_get_performance, serpkin_compare_performance, serpkin_get_results, serpkin_get_rankings, serpkin_track_keywords, serpkin_weekly_summaryFree
Researchserpkin_research_keywords (2), serpkin_analyze_serp (1 per keyword), serpkin_research_competitors (3), serpkin_find_keyword_gaps (3 per competitor), serpkin_get_content_brief (2 to build), serpkin_cluster_keywords and serpkin_create_content_strategy (free)Credits as listed
Links and AI searchserpkin_get_backlinks (5 to refresh now), serpkin_get_ai_visibility (1 per query to check now)Reading is free

The skill tells Claude to ask before spending credits. Missions from serpkin_next_mission include an implementation plan: ordered steps, each with a file from your route map, an action (edit, create or run), an intent and, where possible, a snippet such as a metadata export, app/sitemap.ts or a JSON-LD component. Claude adapts the snippet to your code instead of pasting it.

Prompts to try once connected

You can type these as plain requests. The skill maps them to the right tools and asks before anything that spends credits:

Example requests and the tools Claude uses for them
Ask ClaudeUsesCredits
"What should I do for SEO?"serpkin_next_missionFree
"Is my site OK?"serpkin_site_watchFree
"Which pages gained or lost clicks in the last 28 days?"serpkin_get_performance, serpkin_compare_performanceFree
"Did the /pricing title change work?"serpkin_get_resultsFree
"Find keywords for a page about invoice templates"serpkin_research_keywords2 per seed
"Are we cited in AI Overviews for our main queries?"serpkin_get_ai_visibilityFree to read; 1 per query to check now
"Summarize this week for SEO"serpkin_weekly_summaryFree

For pull requests without anyone at the keyboard, Serpkin's CLI ships a GitHub Action template that runs npx serpkin check when a Vercel preview finishes deploying, and fails the job on a regression.

Where the key lives, and what Serpkin sees

  • The key is never written into your repository. It lives in ~/.config/serpkin/credentials.json (mode 600). Project config only references ${SERPKIN_API_KEY}. The claude mcp add option stores it in your local Claude config, also outside the repo.
  • Serpkin gets a route map, not your source code. URL paths and the file names that render them. Claude Code edits your files locally.
  • The key only goes where you sent it. .serpkin.json is repository content, so a server named only there is used when it is https://serpkin.com or a server you already signed in to. SERPKIN_API_KEY is only sent to SERPKIN_SERVER (or the default).
  • Search data is untrusted. Queries, page titles and competitor text are returned as data, and snippets wrap them as escaped const UNTRUSTED_… strings. Anthropic's MCP docs warn that any server fetching outside content can carry prompt injection, so this matters for every SEO server you add.
  • Removing it. claude plugin uninstall serpkin@serpkin removes the plugin, claude mcp remove serpkin removes a server added with claude mcp add, and you can delete the serpkin entry from .mcp.json. Revoke the key in Settings → Agent setup.

Troubleshooting

SymptomLikely causeFix
serpkin tools missing in /mcpProject server not approved, or plugin not enabledRun /mcp to see status; approve the .mcp.json server, or check /plugin
401 or unauthorizedSERPKIN_API_KEY not set in the shell that started Claude CodeAdd the export line to your profile, open a new terminal, restart claude
claude mcp list warns about ${SERPKIN_API_KEY}The variable is unset, so the literal text is sentSame as above: export the key
No session-start lineNo .serpkin.json, offline, signed out, cached empty result, or SERPKIN_HOOKS=offRun npx serpkin status; the line refreshes within 6 hours
serpkin check reports the preview as unreachableVercel Deployment Protection returns 401Allow Serpkin's requests through, or check a public preview
Missions don't name filesNo route map (unsupported framework or skipped)Run npx serpkin routes --upload
Plugin install failed during initclaude plugin command erroredThe CLI falls back to .mcp.json; run the plugin command above by hand
Warning that MCP output is largeA long mission or report passed Claude Code's 10,000-token warningUsually harmless; raise MAX_MCP_OUTPUT_TOKENS if output is cut off at the 25,000-token default

Questions

Is there an SEO MCP server for Claude Code?

Yes. Serpkin is an HTTP MCP server at https://serpkin.com/api/mcp with 27 SEO tools (missions, verification, performance, rankings, research, backlinks and AI visibility). npx serpkin configures it for Claude Code, either through the plugin or .mcp.json.

Do I need the plugin, or is .mcp.json enough?

.mcp.json gives Claude Code the tools and the MCP prompts. The plugin adds the serpkin-seo skill, the /serpkin:next, /serpkin:ship, /serpkin:check and /serpkin:status commands and the hooks. Most people want the plugin.

Will Claude Code deploy SEO changes on its own?

No. The skill and commands stop before merging or deploying and tell you what to review. You merge and deploy, then ask Claude to verify production.

How do I check that an MCP server is connected in Claude Code?

Run claude mcp list in a terminal, or /mcp inside a session, to see each server's status and tools. For Serpkin, /serpkin:status also shows the site, ownership and credits. If the tools are missing, approve the project server or check that the plugin is enabled.

Does Serpkin read my source code?

No. It receives a route map (URL paths and the files that render them) so missions can name files. Claude Code reads and edits your code locally.

Sources

Let your agent do the SEO work.

Serpkin finds the next fix from real search data, hands it to Claude Code, Codex or Cursor, and checks it after you ship.

npx serpkin
Start free