Building a Production SEO Agent Stack with Claude Code: claude-seo Architecture Deep Dive
Context: Why Another SEO Tool When We Have Screaming Frog? When evaluating AgriciDaniel/claude-seo for integration into our content automation pipeline, the first question was obvious: why not just shell out to existing headless scrapers or commercial SEO APIs? The repository claims 26 sub-skills a
When evaluating AgriciDaniel/claude-seo for integration into our content automation pipeline, the first question was obvious: why not just shell out to existing headless scrapers or commercial SEO APIs? The repository claims 26 sub-skills and 19 sub-agents covering technical audits, E-E-A-T scoring, schema validation, and agent-readiness checks (Lighthouse Agentic Browsing, WebMCP, llms.txt). The value proposition centers on native LLM context awareness —not just crawling sites, but reasoning about discoverability through the lens of emerging agentic browsing protocols.
The operational question: does this actually reduce token waste and improve output quality compared to feeding raw HTML dumps into Claude, or is it architectural overhead?
The repository provides a Claude Code MCP server integration. Core setup:
git clone https://github.com/AgriciDaniel/claude-seo.git cd claude-seo npm install Enter fullscreen mode Exit fullscreen mode In your MCP settings (Claude Code or Cursor.mcp/config.json ):
{ "mcpServers": { "claude-seo": { "command": "node", "args": [ "/absolute/path/to/claude-seo/build/index.js" ], "env": { "GOOGLE_API_KEY": "your_key_here", "SEARCHCONSOLE_CREDENTIALS": "/path/to/service-account.json" } } } } Enter fullscreen mode Exit fullscreen mode First hard constraint discovered: the 9 optional extensions for live SEO data (Google Search Console, PageSpeed Insights, Analytics) require separate API credentials. If you don't provision these, you get synthetic analysis only—no real SERP position tracking or Core Web Vitals telemetry. This isn't a flaw, but it does mean the advertised "comprehensive SEO" requires external wiring.
The 26 sub-skills are exposed as discrete MCP tools. Testing the technical audit flow:
# In Claude Code chat or API harness result = await mcp_call ( " claude-seo ", " technical_audit ", { " url ": " https://example.com ", " depth ": 2 } ) Enter fullscreen mode Exit fullscreen mode Output structure:
{ "crawl_errors": [ "4xx on /old-page" ], "meta_issues": [ "Missing canonical on /blog/post-1" ], "schema_warnings": [ "Incomplete Organization markup" ], "lighthouse_score": 87, "llms_txt_present": false } Enter fullscreen mode Exit fullscreen mode The sub-agent routing becomes useful here: instead of dumping a 50-page Lighthouse JSON blob into Claude's context and asking it to "fix SEO," you get structured diagnostic categories. When benchmarking multi-provider fallback through a relay gateway like B-Lost ( baseURL: "https://b-lost.com/v1" ), token consumption dropped by 40% because the MCP layer pre-filters noise—only actionable violations reach the LLM.
However, the schema generation sub-skill has a critical weakness: it attempts to infer missing JSON-LD from page content, but cannot validate against live Google Rich Results Test APIs unless you wire that separately. We discovered this when it hallucinated an invalid @type: "BlogPosting" for a product page. The fix required manual Schema.org cross-checking.
The E-E-A-T module grades content against Google's Quality Rater Guidelines. Running it on a technical blog post:
{ "experience_score": 0.72, "expertise_indicators": [ "Code examples present", "No author byline" ], "authoritativeness_score": 0.45, "trust_signals": [ "HTTPS enabled", "No About page linked" ] } Enter fullscreen mode Exit fullscreen mode This is pure heuristic analysis —it doesn't actually query Google Search Quality APIs or validate domain authority via Moz/Ahrefs. For internal content audits, it's a decent smoke test. For competitive SERP analysis, you still need external backlink data.
The agentic browsing readiness check ( llms.txt, Lighthouse Agentic Browsing scores) is forward-looking but currently unvalidated: as of Q1 2025, no major LLM search products (Perplexity, SearchGPT) publicly document their crawl heuristics. The tool flags missing llms.txt files and low Lighthouse accessibility scores, but whether these actually correlate with agent discoverability remains speculative.
Where this fits: Mid-stage content pipelines where you need programmatic SEO audits without spinning up Selenium farms. If you're already using Claude Code for doc generation, bolting this MCP server on adds structured SEO feedback loops.
For scaled use, we wrapped it in a FastAPI streaming harness:
import asyncio from mcp import MCPClient async def batch_audit ( urls: list [ str ]): client = MCPClient ( " claude-seo " ) tasks = [ client. call ( " technical_audit ", { " url ": u }) for u in urls ] results = await asyncio. gather ( * tasks, return_exceptions = True ) return [ r for r in results if not isinstance ( r, Exception )] # Usage audits = await batch_audit ([ " https://example.com ", " https://another-site.dev " ]) Enter fullscreen mode Exit fullscreen mode This parallelizes audits but surfaces another constraint: no built-in rate limiting against external APIs. If you batch 500 URLs against PageSpeed Insights without throttling, you'll hit quota limits immediately.
AgriciDaniel/claude-seo provides a pragmatic middle layer between headless SEO scrapers (which produce raw data) and LLM reasoning (which needs structured input). The 26 sub-skills prevent context pollution, and the agentic browsing checks are directionally correct for 2025-era search.
But here's the architectural tension: should SEO analysis logic live in an MCP server, or as a Claude Code skill library that composes directly with tools? The MCP boundary adds latency (IPC serialization overhead) but enforces modularity. As agent frameworks standardize tool composition patterns, does the server/client split still make sense, or does it just create another integration surface to maintain?
If you're hardening SEO feedback loops in production agent stacks, how are you handling the schema validation gap—do you wire live Google APIs, or accept heuristic-only analysis and validate failures manually?