I run a small dev agency. Like most founders, SEO is one of those things I know I should be doing, but never actually get to. I would check Google Search Console once every few weeks, glance at the numbers, and move on. No systematic tracking. No real optimization. Just vibes.
Last week I decided to fix that - by configuring an AI agent to do it for me. Here is exactly how I set it up.
The Goal
I wanted an SEO assistant that:
- Checks my search performance every single day
- Flags problems (ranking drops, weird CTR) before I notice them
- Finds content opportunities I would miss
- Sends me a weekly report combining Search Console + Analytics
- Runs autonomously - no manual triggers, no forgetting
I have two domains to manage: vistaran.com (my agency site) and boomerr.ai (a SaaS product).
Step 1: Create a Dedicated Hermes Agent Profile
I use Hermes Agent - an open-source AI agent framework that runs locally on my Windows machine. The key insight: Hermes supports isolated profiles. Each profile has its own skills, memory, cron jobs, and scripts. Other profiles cannot access or interfere with them.
I created a profile called eisen-seo-wizard:
hermes profile create eisen-seo-wizard
This profile is now my SEO specialist. Everything below lives inside it - sealed off from my other automation (email summaries, banking alerts, etc.).
Step 2: Connect to Google Cloud APIs
The agent needs access to two Google APIs:
| API | Purpose | Google Service Name |
|---|---|---|
| Google Search Console | Keyword rankings, clicks, impressions, CTR | webmasters.googleapis.com |
| Google Analytics 4 | Sessions, page views, engagement duration | analyticsdata.googleapis.com |
The OAuth Setup
I already had a Google Cloud project (hermes-agentic-systems) with both APIs enabled. I created an OAuth 2.0 Desktop client, downloaded the credentials, and ran a one-time browser authorization.
The result: a google-token.pickle file that the scripts auto-refresh. No API keys. No manual re-auth. The agent handles token refresh transparently.
Domain to Property Mapping
Each domain maps to a GSC property and a GA4 property ID:
# From seo_utils.py - the shared config module GSC_PROPERTIES = { "vistaran.com": "sc-domain:vistaran.com", "boomerr.ai": "sc-domain:boomerr.ai", } GA4_PROPERTIES = { "vistaran.com": "438910146", "boomerr.ai": "524940807", }
The sc-domain: prefix tells GSC we are using domain properties (covers all subdomains and protocols - https://www., https://blog., etc. - without separate tracking).
Step 3: Write the Scripts
This is where the actual SEO logic lives. I built four Python files:
eisen-seo-wizard/scripts/ ├── seo_utils.py - shared auth, API clients, helpers ├── daily_monitor.py - daily anomaly scanner ├── content_generator.py - opportunity finder + prompt builder └── monday_report.py - weekly GSC + GA4 combined report
seo_utils.py - The Foundation
The shared module that all three scripts import. It handles:
- OAuth token loading & auto-refresh: Loads the pickle token, refreshes if expired, saves the new token back.
- GSC query wrapper: Calls
searchanalytics.querywith automatic pagination (handles the 25,000-row limit) and retry-on-429 for rate limits. - GA4 query wrapper: Calls the GA4 Data API with pagination and retry logic.
- Date helpers: Generates date range strings for "last 3 days", "same 3 days last week", etc.
- The domain-to-property mapping shown above.
All three scripts do from seo_utils import ... - zero duplicated auth code.
daily_monitor.py - The Daily Anomaly Scanner
This runs every morning at 10 AM IST via a cron job. Here is what it does:
- Fetches two 3-day windows from GSC: the most recent 3 days, and the same 3 days from the previous week.
- Joins them on (query, page, device) to compute Week-over-Week deltas.
- Flags ranking drops: Any keyword that was ranking last week and has now slipped more than 3 positions, or lost over 20% of its clicks.
- Flags CTR anomalies: Pages with high impressions (top 10% for the domain) but abnormally low CTR for their position band (e.g., a rank-5 page with 0.5% CTR when the band average is 2.5%+).
- Position band migration: Tracks keyword movement between bands (1-3, 4-10, 11-20, 21-50, 51+).
Live output from today:
════ ================================================== DAILY MONITOR | vistaran.com | 2026-07-08 ════ ================================================== Rows: curr=25 prev=24 | Clicks: 1 (prev 1) | Impressions: 78 ▼ RANKING DROPS (3 flagged): ▸ [MOBILE] companies in gandhinagar - pos 17.5 - 22.0 ▸ [DESKTOP] scanview - pos 25.8 - 33.0 ▸ [MOBILE] scanview - pos 25.0 - 38.0 ⚠ CTR ANOMALIES (1 flagged): ▸ /terms-and-conditions - "techtronix fraud" - 23 imp, 0% CTR ↕ POSITION BAND MIGRATION: 1-3 - 4-10: 1 kw 11-20 - 21-50: 1 kw
It flagged my scanview product page slipping from position ~25 to ~33-38 in a single week. Without this, I would have missed it entirely until it dropped off the map.
content_generator.py - The Opportunity Miner
This is the one that actually helps me create content, not just monitor numbers.
It pulls 28 days of GSC data and does two things:
1. Striking-Distance Keywords
Finds every keyword ranking between positions 11 and 20 - the "almost page 1" zone. These are the highest-ROI keywords because a small optimization push can tip them onto the first page.
It sorts them by impression volume and formats them into a ready-to-use LLM prompt:
| # | Keyword | Avg Pos | Impressions | |---|---------|---------|-------------| | 1 | scanview software | 17.7 | 27 | | 2 | companies in gandhinagar | 17.1 | 11 | | 3 | scanview | 19.2 | 4 | | 4 | vistaran in english | 11.8 | 4 | | 5 | robust api | 11.0 | 1 |
For each keyword, the prompt asks the LLM to produce:
- An SEO title (less than or equal to 60 characters)
- A meta description (less than or equal to 155 characters)
- A 5-8 item H2/H3 content outline
- A 100-word semantic paragraph addressing the core intent
2. Intent Gap Detection
Scans for informational queries (containing "how to", "what is", "best practices for", "guide to", etc.) that land on existing pages but have CTR below 2%. This means users are searching for something, finding the page in results, but not clicking - the page does not match what they are looking for.
For each gap, it suggests what content to add to close it.
monday_report.py - The Weekly Commander's Brief
Runs every Monday at 10 AM IST. This is the heavy lifter:
- Pulls 7 days of GSC data (clicks, impressions, CTR, average position)
- Pulls 7 days of GA4 data (sessions, page views, active users, engagement duration)
- Joins them on URL path using Pandas
- Computes Week-over-Week percentage deltas for every metric
- Ranks the top 25 pages by clicks
- Identifies the top 20 ranking shifts (both gains and losses)
- Auto-generates 3 priority action items based on the data
It writes a REPORT_vistaran_com.md and REPORT_boomerr_ai.md file. Here is a snippet of what it looks like:
## Google Search Console | Metric | Current Week | Previous Week | % WoW | |--------|-------------|---------------|-------| | Clicks | 1 | 4 | -75.0% | | Impressions | 180 | 149 | +20.8% | | Avg CTR | 0.56% | 2.68% | -79.3% | | Avg Position | 25.4 | 18.8 | +35.0% | ## Google Analytics 4 | Metric | Current Week | Previous Week | % WoW | |--------|-------------|---------------|-------| | Sessions | 126 | 148 | -14.9% | | Page Views | 684 | 927 | -26.2% | | Avg Engagement / Session | 494s | 501s | -1.4% | ## Top 3 Priority Actions 1. Traffic dip - clicks down 75%. Audit top pages losing clicks. 2. Engagement healthy (494s/session). Add conversion CTAs to high-traffic pages. 3. Run daily_monitor.py daily to catch ranking shifts early.
Step 4: Schedule the Cron Jobs
The final piece - automation. Two cron jobs, both bound to the eisen-seo-wizard profile:
| Job | Schedule | Mode | What It Does |
|---|---|---|---|
| daily-seo-monitor | Daily, 10:00 AM IST | Script mode (no LLM) | Runs daily_monitor.py, delivers stdout verbatim - zero token cost |
| monday-seo-report | Mondays, 10:00 AM IST | Agent mode | Runs monday_report.py, reads both generated reports, delivers them formatted |
The daily monitor uses no-agent mode - the script's output IS the message. No LLM call, no tokens burned, just pure data delivery in under 2 seconds.
The Monday report uses agent mode so the AI can read both generated .md files and present them in a clean, scannable format.
Both cron jobs are restricted to the eisen-seo-wizard profile. When my banking-summary cron runs in another profile, it has zero access to these scripts. Complete isolation.
What I Actually Get Every Day
Monday through Sunday mornings, around 10 AM IST, I receive a Discord message that looks like this:
DAILY MONITOR | vistaran.com | 2026-07-08
▼ RANKING DROPS (3 flagged):
- scanview - pos 25.8 - 33.0
- companies in gandhinagar - pos 17.5 - 22.0
⚠ CTR ANOMALIES (1 flagged):
- /terms-and-conditions - 23 imp, 0% CTR
Monday mornings, I get the full weekly report with GSC + GA4 side-by-side, WoW deltas, and prioritized action items.
The Real Value
The scripts are maybe 800 lines of Python total. None of it is rocket science - it is just Pandas dataframes, GSC API calls, and some SQL-style joins. But the value comes from:
- Consistency. It runs every single day whether I remember or not.
- Early warning. I caught the
scanviewpage sliding before it cost me real traffic. - Opportunity surfacing. I would never have noticed
vistaran in englishranking at 11.8 without the striking-distance scan. - Zero ongoing effort. Once the cron jobs are set, it is fully autonomous.
Want to Build Your Own?
Here is what you need:
- Hermes Agent installed locally (docs)
- A Google Cloud project with Search Console and Analytics Data APIs enabled
- An OAuth 2.0 Desktop client and one-time browser authorization
- The four scripts above (available in my
eisen-seo-wizard/scripts/directory) - Two cron jobs to wire it all together
The whole setup took me about two hours - and it has been running hands-free ever since.
But here is the thing - the hardest part is not the scripts or the cron jobs. It is getting the first iteration right without wasting a week on trial and error. If you are running an agency or a SaaS product and want this kind of automation without the setup overhead, our team at Vistaran builds custom AI agent workflows tailored to your stack. We handle the API wiring, the profile isolation, the cron scheduling, and the monitoring dashboards so you can focus on what your keywords are telling you instead of how to fetch them.
Talk to our team about your SEO automation
Got questions about this setup? Drop a comment or ping me on the Vistaran blog - happy to share the scripts.
Remain Ahead of the Curve
Stay upto date with the latest Technologies, Trends, Artificial Intelligence, Productivity Tips and more.
No spam. You can unsubscribe at any time.
Ready to accelerate
your growth?
Discover how Vistaran's tailored solutions can streamline your operations and scale your business. Talk to our experts for a personalized technical consultation.
Contact Sales
