Self-improving SEO agent. Measures, acts, learns.
Project description
seo-pilot
Self-improving SEO agent. Measures, acts, learns.
seo-pilot syncs your Google Search Console data, identifies what needs fixing, suggests concrete changes, and measures whether they worked. It's the closed feedback loop most SEO workflows are missing.
What it does
- Syncs GSC data daily (queries, pages, impressions, clicks, position)
- Analyzes on a weekly and monthly schedule:
- Low hanging fruit: pages with high impressions but low CTR for their position
- Content gaps: queries where Google shows your site but you have no dedicated page
- Rising queries: search terms growing >30% week-over-week
- Position drops: pages losing ground (>2 positions)
- Suggests concrete title/meta rewrites via LLM (Claude, OpenAI, Gemini, or Ollama)
- Tracks every action in a queue with priority scoring
- Measures the impact of your changes automatically and writes changelog entries
- Audits internal links: finds orphan pages, broken links, missing product links
What makes it different
Most SEO tools tell you what happened. seo-pilot tells you what to do and then checks if it worked.
- Closed feedback loop: change title → measure CTR after 14d → auto-log result
- Action queue: every finding becomes a trackable action with priority
- Auto-changelog: records before/after for every change with baseline metrics
- Scoring engine: prioritizes pages by impression volume, position, and CTR gap
- Expert guidelines: built-in 2026 SEO best practices (customizable)
Quick start
# Install
pip install seo-pilot
# Interactive setup
seo-pilot init
# Check everything works
seo-pilot doctor
# Sync last 90 days of GSC data
seo-pilot sync --backfill
# Run your first review
seo-pilot review
Requirements
- Python 3.10+
- Google Search Console access (service account)
- Optional: LLM API key (for title suggestions)
- Optional: Telegram/Slack (for notifications)
Setup
1. Google Search Console credentials
Create a Google Cloud service account with Search Console API access:
- Go to Google Cloud Console
- Create a project (or use existing)
- Enable "Google Search Console API"
- Create a service account → download JSON key
- Add the service account email as a user in your GSC property
Save the JSON key as credentials.json in your project root.
2. Configuration
seo-pilot init
This creates config.yaml with your settings. Or copy config.example.yaml and edit manually.
3. First sync
# Backfill 90 days of historical data
seo-pilot sync --backfill
# Run first analysis
seo-pilot review
Commands
| Command | What it does |
|---|---|
seo-pilot init |
Interactive setup, generates config.yaml |
seo-pilot doctor |
Checks config, GSC auth, DB, notifications |
seo-pilot sync |
Sync yesterday's GSC data |
seo-pilot sync --backfill |
Load last 90 days |
seo-pilot review |
Weekly review (28d vs prev 28d) |
seo-pilot review --monthly |
Monthly review (90d trend) |
seo-pilot audit links |
Internal linking audit via HTTP crawl |
seo-pilot actions list |
Show open actions |
seo-pilot actions resolve <id> |
Mark action as resolved |
Review schedule
| Frequency | Window | What it covers |
|---|---|---|
| Weekly | 28 days vs previous 28 days | LHF, content gaps, rising queries, drops, title suggestions |
| Monthly (1st week) | 90 days, month-by-month | Trend analysis, position movers, action queue summary, stale action escalation |
How scoring works
Every low-hanging-fruit page gets a composite score (0-100):
| Factor | Weight | Example |
|---|---|---|
| Impression volume | 30% | 200 imp = 30/30 |
| Position (5-15 sweet spot) | 25% | pos 8 = 25/25 |
| CTR gap vs expected | 25% | pos 3 + 0% CTR (expected 11%) = 25/25 |
| Title quality | 10% | question format + year = 10/10 |
| Content freshness | 10% | current year = 10/10 |
Score 85+ = urgent (fix today). Score 70+ = action this week.
Expected CTR benchmarks (2026):
- Position 1: 28%, Position 3: 11%, Position 5: 7%, Position 10: 3%
LLM providers
seo-pilot uses an LLM to generate title/meta suggestions. Supported providers:
| Provider | Config value | Model examples |
|---|---|---|
| Google Gemini | gemini |
gemini-2.0-flash |
| Anthropic Claude | claude |
claude-sonnet-4-6 |
| OpenAI | openai |
gpt-4o |
| Ollama (local) | ollama |
llama3, mistral |
Title suggestions are optional. The analysis runs without an LLM.
Internal linking audit
seo-pilot audit links
Crawls your site via HTTP (no headless browser needed), maps all internal links, and identifies:
- Orphan pages: pages with zero inbound internal links
- Broken links: internal links pointing to 404s
- Missing product links: blog posts without a link to pricing/conversion pages
- Cluster mapping: groups pages into topic clusters
Output: linking-map.md in your project root.
Docker
# Build
docker build -t seo-pilot .
# Run a review
docker run -v ./config.yaml:/app/config.yaml \
-v ./credentials.json:/app/credentials.json \
-e TELEGRAM_BOT_TOKEN=xxx \
-e GEMINI_API_KEY=xxx \
seo-pilot review
Or with docker-compose:
docker-compose run seo-pilot review
Guidelines
seo-pilot includes default SEO guidelines at guidelines/default.md. These encode 2026 best practices for title tags, meta descriptions, content scoring, and internal linking.
Customize by editing the file or pointing to your own:
guidelines:
path: "./my-guidelines.md"
Guidelines should be refreshed quarterly. The scoring engine reads thresholds from the guidelines.
File structure
seo-pilot/
├── config.yaml # Your config (gitignored)
├── config.example.yaml # Template
├── credentials.json # GSC service account (gitignored)
├── seo-pilot.db # SQLite database (gitignored)
├── guidelines/
│ └── default.md # SEO best practices
├── templates/
│ ├── weekly_report.j2 # Weekly report template
│ └── monthly_report.j2 # Monthly report template
├── seo_pilot/
│ ├── cli.py # CLI commands
│ ├── config.py # Config loader
│ ├── gsc_client.py # Google Search Console API
│ ├── storage.py # SQLite/Postgres storage
│ ├── analyzer.py # Analysis engine
│ ├── changelog.py # Auto-changelog
│ ├── linking_audit.py # Internal link crawler
│ ├── notifier.py # Telegram/Slack/webhook
│ ├── llm.py # LLM title suggestions
│ └── reporter.py # Report generator
└── docs/
└── architecture.md # System design
Roadmap
- v0.1 — Core: GSC sync, analysis, action queue, changelog, CLI
- v0.2 — MCP server mode (use from Claude Code directly)
- v0.2 — Web dashboard (lightweight, static HTML)
- v0.2 — OAuth support (not just service account)
- v0.2 — Slack + Discord notifications
- v0.3 — Competitor watch plugin
- v0.3 — WordPress/CMS content discovery
Contributing
Contributions welcome. Please open an issue first to discuss what you'd like to change.
# Development setup
git clone https://github.com/Palicz91/seo-pilot.git
cd seo-pilot
pip install -e ".[dev]"
pytest
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file seo_pilot-0.1.0.tar.gz.
File metadata
- Download URL: seo_pilot-0.1.0.tar.gz
- Upload date:
- Size: 35.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cee62940f3bf4205a367b4d22754829c453ec0df7293d117ced56c282a805aaa
|
|
| MD5 |
e38d894c02335c0ae415a22cafec155f
|
|
| BLAKE2b-256 |
d9196b69c56c33b89d6a125012fa5d95e49506daae801951bcace5634ccc6f30
|
File details
Details for the file seo_pilot-0.1.0-py3-none-any.whl.
File metadata
- Download URL: seo_pilot-0.1.0-py3-none-any.whl
- Upload date:
- Size: 36.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0429cd45a93d43937ad4865e2ed38d3dc67142b3a91d142592b25ec8b8680a76
|
|
| MD5 |
ced4213a66ad19f6809b04f72c061dd4
|
|
| BLAKE2b-256 |
c775bdae0f4fa57405dd54026895f34403ce152eee2a4eff6efba5d2767a7cd7
|