SEO Thermostat MCP
Imports Google Analytics 4 data including conversion events (e.g., signups, purchases) to measure page effectiveness in driving business outcomes.
Fetches search performance data (impressions, clicks, CTR) for pages to identify weak click-through rates and ranking issues.
Pulls product usage events (activation and interaction events) to correlate page traffic with user behavior and product outcomes.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@SEO Thermostat MCPWhich pages have high impressions but low CTR?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
SEO Thermostat MCP
SEO Thermostat is a local-first Model Context Protocol (MCP) project for improving existing SEO pages with evidence from search performance, analytics, product usage, and page content.
The goal is to help answer questions like:
Which pages have search demand but weak click-through rate?
Which pages rank for intents the content does not clearly satisfy?
Which pages are decaying over time?
Which traffic pages fail to create useful product or business outcomes?
Which low-visibility pages deserve more investment because they convert or activate well?
The project is designed for public GitHub distribution. Users bring their own credentials, local SQLite database, analytics data, and content folders.
Table of Contents
Related MCP server: Google Search Console MCP Server
Current Status
This repository is in an alpha implementation stage.
Currently present:
Technical specification in
docs/SEO_THERMOSTAT_SPEC.mdCanonical task checklist in
docs/TASKS.mdPython package under
src/seo_thermostat/seo-thermostatconsole scriptSQLite initialization and idempotent fact-table upserts
Content manifest indexing and import for Markdown, MDX, and HTML
Mock-friendly GSC, GA4, and PostHog connectors
CTR baselines, scoring, flags, recommendations, and nightly builds
Local stdio MCP server backed by SQLite analysis data
Public-safe
.env.examplePublic-safe
.gitignorePytest coverage and public-safe sample fixture content
Use docs/TASKS.md as the source of truth for what is done versus planned.
Setup
Requirements:
Python 3.10 or newer
pipOptional but recommended: a virtual environment
Create and activate a virtual environment:
python -m venv .venv
source .venv/bin/activateInstall the package in editable mode with development test dependencies and local OAuth setup helpers:
python -m pip install -e ".[dev,auth]"Run the test suite:
python -m pytestThe package declares a console script named seo-thermostat.
Configuration
Start from the example environment file:
cp .env.example .envThen edit .env locally with your own values.
Important configuration groups in .env.example:
SEO_THERMOSTAT_DB_PATH: local SQLite database path.SEO_THERMOSTAT_CONTENT_ROOT: local content folder to index.SEO_THERMOSTAT_CONTENT_MANIFEST: generated content manifest path.GSC_*: Google Search Console read-only OAuth settings.GA4_*: Google Analytics 4 property and credential settings.POSTHOG_*: PostHog host, project, API key, and event settings.SEO_THERMOSTAT_MCP_TRANSPORT: MCP transport setting, currentlystdio.SEO_THERMOSTAT_SETTLED_DATA_OFFSET_DAYS: default settled-data lag for nightly analysis.
Do not commit your real .env, OAuth client files, API keys, tokens, service-account JSON, private database files, generated manifests, or local MCP client configuration.
Credential Setup
Keep all credentials in .env, ./secrets/, ./.secrets/, or another ignored local path. The repository should contain placeholders only.
Google Search Console
Use OAuth for Search Console. The connector can use a short-lived bearer token, but for normal use you should give it a refresh token so it can mint fresh access tokens before API calls.
Open the Google Cloud Console and create or select a project.
Go to APIs & Services > Library, enable the Google Search Console API.
Go to APIs & Services > OAuth consent screen.
Choose Internal if you are on a Google Workspace account and only internal users need access; otherwise choose External.
Fill in the app name and support email. If the app is in testing mode, add your Google account as a test user.
Go to APIs & Services > Credentials > Create credentials > OAuth client ID.
Choose Desktop app as the application type.
Download the OAuth client JSON and save it locally:
mkdir -p secrets
mv ~/Downloads/client_secret_*.json ./secrets/google-oauth-client.jsonSet these values in
.env:
GSC_SITE_URL=https://example.com/
GSC_OAUTH_CLIENT_SECRETS_PATH=./secrets/google-oauth-client.json
GSC_OAUTH_TOKEN_PATH=./secrets/gsc-token.jsonUse the exact GSC_SITE_URL shown by Search Console, such as
https://example.com/ for a URL-prefix property or sc-domain:example.com for
a domain property.
Create the refresh token with the local Desktop OAuth flow:
python scripts/generate_gsc_token.pyThe script reads GSC_OAUTH_CLIENT_SECRETS_PATH and GSC_OAUTH_TOKEN_PATH from
.env, opens a browser consent flow, and writes the refresh token JSON locally.
Smoke-test access:
seo-thermostat gsc list-sitesIf you prefer the OAuth 2.0 Playground, create a Web application OAuth
client instead and add https://developers.google.com/oauthplayground as an
authorized redirect URI. The Playground route is not compatible with a Desktop
OAuth client.
Google Analytics 4
For unattended nightly builds, prefer a service account. OAuth refresh tokens also work, but service accounts are easier to operate on a schedule.
GA4 Option A: Service Account
Open the Google Cloud Console and create or select a project.
Go to APIs & Services > Library, enable the Google Analytics Data API.
Go to IAM & Admin > Service Accounts > Create service account.
Give it a clear name such as
seo-thermostat-ga4-reader.After the service account is created, open it and go to Keys > Add key > Create new key.
Choose JSON, download the key, and save it locally:
mkdir -p secrets
mv ~/Downloads/*.json ./secrets/ga4-service-account.jsonCopy the service account email from the JSON file or from Google Cloud. It looks like
name@project-id.iam.gserviceaccount.com.Open Google Analytics, select the GA4 property, and go to Admin > Property access management.
Add the service account email with Viewer or Analyst access.
Find the numeric GA4 property id in Admin > Property details.
Set these values in
.env:
GA4_PROPERTY_ID=123456789
GA4_CREDENTIALS_PATH=./secrets/ga4-service-account.json
GA4_CONVERSION_EVENTS=signup,trial_started,purchaseThe connector reads GA4_CREDENTIALS_PATH and refreshes a readonly GA4 access
token with google-auth.
Smoke-test GA4 access after setting .env:
seo-thermostat ga4 smoke-testThe smoke test runs a tiny GA4 Data API report for the last 7 days and prints how many rows were returned. It does not write to the local database.
GA4 Option B: OAuth Refresh Token
Use this when you cannot grant a service account access to the GA4 property.
Enable the Google Analytics Data API in Google Cloud.
Create a Desktop app OAuth client under APIs & Services > Credentials.
Save the OAuth client JSON locally:
mkdir -p secrets
mv ~/Downloads/client_secret_*.json ./secrets/google-oauth-client.jsonUse the OAuth 2.0 Playground with your own OAuth credentials.
Authorize this scope:
https://www.googleapis.com/auth/analytics.readonlyExchange the authorization code for tokens and copy the
refresh_token.Save the token locally:
{
"refresh_token": "REFRESH_TOKEN_PLACEHOLDER"
}Save that JSON as ./secrets/ga4-token.json.
Set these values in
.env:
GA4_PROPERTY_ID=123456789
GA4_OAUTH_CLIENT_SECRETS_PATH=./secrets/google-oauth-client.json
GA4_OAUTH_TOKEN_PATH=./secrets/ga4-token.json
GA4_CONVERSION_EVENTS=signup,trial_started,purchaseGA4_ACCESS_TOKEN is supported for short local smoke tests, but raw Google
access tokens expire quickly and are not enough for unattended scheduling.
PostHog
PostHog uses a project id, host URL, and a personal API key. Do not use the
public project token for POSTHOG_API_KEY; project tokens are for client-side
event capture and cannot query private analytics data.
Open your PostHog workspace.
Confirm the host:
US Cloud is usually
https://us.posthog.comorhttps://app.posthog.com.EU Cloud is usually
https://eu.posthog.com.Self-hosted deployments use your own base URL.
Open the project settings and copy the numeric project id.
Open your personal settings or account settings and create a personal API key with permission to read/query events. HogQL query endpoints require this private API key.
Decide which events represent product outcomes:
Activation events: examples include
onboarding_completed,project_created.Interaction events: examples include
cta_clicked,tool_used.
Set these values in
.env:
POSTHOG_HOST=https://us.posthog.com
POSTHOG_PROJECT_ID=12345
POSTHOG_API_KEY=POSTHOG_API_KEY_PLACEHOLDER
POSTHOG_ACTIVATION_EVENTS=onboarding_completed,project_created
POSTHOG_INTERACTION_EVENTS=cta_clicked,tool_usedSmoke-test PostHog access after setting .env:
seo-thermostat posthog smoke-testThe smoke test runs a small HogQL query for the configured activation and interaction events over the last 7 days and prints how many grouped rows were returned. It does not write to the local database.
Credential References
Search Console authorization: https://developers.google.com/webmaster-tools/v1/how-tos/authorizing
GA4 Data API quickstart: https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart-client-libraries
OAuth 2.0 Playground: https://developers.google.com/oauthplayground/
PostHog API docs: https://posthog.com/docs/api
CLI Examples
Common local commands:
seo-thermostat --help
seo-thermostat init-db --db ./seo_thermostat.db
seo-thermostat index-content --root ./content --out ./content_manifest.json
seo-thermostat import-content --manifest ./content_manifest.json --db ./seo_thermostat.db
seo-thermostat gsc list-sites
seo-thermostat ga4 smoke-test
seo-thermostat posthog smoke-test
seo-thermostat refresh-live
seo-thermostat compute-ctr-baseline --db ./seo_thermostat.db
seo-thermostat build-nightly --db ./seo_thermostat.db
seo-thermostat mcp --db ./seo_thermostat.dbLocal MCP Client Configuration
The MCP server is a local stdio server intended for clients such as Codex, Claude, and other MCP-compatible tools.
Local client configuration should point to the installed command and the private local database path, for example:
{
"command": "seo-thermostat",
"args": ["mcp", "--db", "./seo_thermostat.db"]
}If your MCP client requires a named server entry, use:
{
"mcpServers": {
"seo-thermostat": {
"command": "seo-thermostat",
"args": ["mcp", "--db", "./seo_thermostat.db"],
"cwd": "/path/to/seo-thermostat"
}
}
}Keep client config private. The repository ignores common local MCP files such as .mcp/, .mcp.json, mcp.json, and claude_desktop_config.json.
Using the MCP: Example Questions
The SEO Thermostat MCP supports natural-language queries about your site's SEO performance. Here are the kinds of questions you can ask:
Discovery & Overview
"What pages have the most search impressions but low click-through rates?"
"Show me all flagged pages that need attention."
"Which pages rank for search queries but don't clearly satisfy user intent?"
"List all pages in the blog directory with performance metrics."
"Find pages with the highest priority for improvement."
"What are the top SEO opportunities across my site?"
Page Analysis
"What is the health status of the /pricing page?"
"Show me specific improvements and recommendations for /about-us."
"Which queries does the /features page rank for, and where is it underperforming?"
"What content gaps exist that we should address?"
"Where can I find quick wins to improve CTR for a specific page?"
Data Refresh & Status
"Refresh the analysis with the latest search console data."
"Run an analysis build for a specific date."
"Show me the status of recent analysis builds."
"Update the dataset and show me what changed."
Available Tools
The MCP provides these core tools for querying your SEO data:
discover_urls — Find pages by search term, URL pattern, or flag status. Includes metrics like impressions, sessions, and recommendations.
get_page_health — Get comprehensive health data for a specific page including scores, flags, metrics, and recommendations.
list_flagged_pages — See all pages with open flags that need attention, filterable by flag type.
analyze_page_improvements — Get detailed improvement recommendations for a specific URL.
find_content_gaps — Identify pages with content gap flags and related recommendations.
list_seo_opportunities — View prioritized SEO opportunities ranked by impact potential.
get_query_opportunities — See query-level performance data for a specific page with CTR gap analysis.
get_analysis_build_status — Check the latest analysis build results and recent build history.
refresh_analysis_dataset — Fetch fresh data from Google Search Console, GA4, and PostHog, then recompute analysis.
Available Resources
Quick-access data resources for snapshot views:
seo://latest/summary — Overall SEO Thermostat analysis summary for the latest date.
seo://latest/pages — All discovered pages with current metrics and flag counts.
seo://latest/flagged-pages — All pages with open flags for the latest analysis date.
seo://latest/opportunities — Prioritized SEO opportunities ranked by impact.
seo://pages/{url}/health — Health snapshot for any specific page URL.
seo://pages/{url}/recommendations — Improvement recommendations for any page URL.
MCP protocol JSON should go to stdout, and logs should go to stderr so clients can parse responses reliably.
After credentials and local paths are set in .env, the MCP client can ask the
server to create the working dataset directly. The refresh_analysis_dataset
tool indexes SEO_THERMOSTAT_CONTENT_ROOT when configured, pulls live GSC, GA4,
and PostHog rows into SQLite, then runs the analysis build. For example, in an
LLM client you can ask: "Refresh the SEO dataset for the latest settled date,
then show the highest-priority opportunities."
The same tool accepts an explicit date, exact date range, or backfill_days.
Use sources to limit refresh work, such as ["gsc", "ga4"], and use
continue_on_source_error only when a partial dataset is acceptable.
Optional Nightly Scheduling
seo-thermostat build-nightly defaults to settled analytics data from T-3. Use --date YYYY-MM-DD for a deterministic backfill or --settled-offset-days N to change the lag.
To run the nightly workflow immediately instead of waiting for a scheduler, refresh live data for the settled date and then build the analysis:
seo-thermostat refresh-live
seo-thermostat build-nightlyFor an explicit date:
seo-thermostat refresh-live --date 2026-06-23
seo-thermostat build-nightly --date 2026-06-23For an initial backfill, fetch a wider live-data window before building the
latest settled date. --backfill-days is inclusive and ends on --date, or on
the default settled date (T-3) when --date is omitted:
seo-thermostat refresh-live --backfill-days 180
seo-thermostat build-nightlyTo pin that six-month backfill to a specific settled date:
seo-thermostat refresh-live --date 2026-06-23 --backfill-days 180
seo-thermostat build-nightly --date 2026-06-23If you already know the exact range, use explicit boundaries:
seo-thermostat refresh-live --start-date 2025-12-26 --end-date 2026-06-23refresh-live pulls GSC, GA4, and PostHog rows into SQLite. build-nightly
then computes baselines, scores, flags, and recommendations from that local
database.
Set SEO_THERMOSTAT_LOG_LEVEL=INFO in .env to see refresh progress for each
live source. Logs go to stderr so MCP protocol output on stdout stays clean.
Example cron entry for a nightly local build:
15 2 * * * cd /path/to/seo-thermostat && . .venv/bin/activate && seo-thermostat build-nightly --db ./seo_thermostat.db >> logs/nightly.log 2>&1Example macOS launchd command arguments:
cd /path/to/seo-thermostat
.venv/bin/seo-thermostat build-nightly --db ./seo_thermostat.dbKeep scheduler files that contain machine-specific paths outside the repository or in an ignored local config folder.
Public Repository Guidance
This repository should stay safe to publish.
Commit source code, tests, docs, and public-safe fixtures only.
Use
.env.examplefor placeholder configuration, never real credentials.Keep
.env,.envcopies, SQLite databases, generated manifests, tokens, OAuth files, service-account JSON,./secrets/,./.secrets/, and local client config out of version control.Use example domains such as
example.comin docs and fixtures.Prefer mocked connector tests for CI and public contributors.
Document any optional live API smoke tests separately from the default test path.
Run
python -m pytest tests/test_public_repo_hardening.pybefore publishing if credentials or fixtures changed locally.
Before publishing or opening a pull request, check that no private domains, tokens, analytics exports, or user-specific paths are included.
Project References
Technical spec:
docs/SEO_THERMOSTAT_SPEC.mdImplementation checklist:
docs/TASKS.mdExample local configuration:
.env.exampleIgnore rules for private/generated files:
.gitignore
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mehere14/SEO-Thermostat'
If you have feedback or need assistance with the MCP directory API, please join our Discord server