Google Search Console MCP Server to serwer łączący klientów AI (Windsurf, Devin, Factory Droid) z Google Search Console API. Agent może konwersacyjnie pytać o ruch, sitemapy, właściwości i stan indeksacji URL-i, a serwer zwraca surowe dane GSC wzbogacone o kontekstowe obserwacje (hints).
Projekt zbudowany na szablonie streamable-mcp-server-template Adama Gospodarczyka (AI_DEVS, overment) i rozbudowany do pełnego, deployment-ready serwera MCP w pięciu epikach.
📋 Metryki projektu
- Start: lipiec 2026
- Status: MVP v1 kompletny i deployment-ready (projekt eksperymentalny, dalszy rozwój jako v2)
- Rola: System Architect / Full-Stack Developer
- Cel: Udostępnienie danych Google Search Console agentom LLM przez typowane narzędzia MCP
- Walidacja: 753 testów (0 fail), lint + typecheck czyste, CI 17 s, Docker smoke (cold start 0.418 s, RAM 27 MB idle, volume persistence)
🚀 Ewolucja produktu (Product Journey)
- Architektura: Layered architecture z Tool Registry (AD-1..AD-14) - ratyfikacja brownfield z szablonu, spójne zasady dla 4 narzędzi.
- Fundament: Upgrade MCP SDK ^1.29.0 (Streamable HTTP), całkowity cleanup Cloudflare Workers, migracja z
better-sqlite3nabun:sqlite+ drizzle-orm. - Autoryzacja:
GscAuthService- Service Account JWT RS256 (RFC 7523), wymiana na access token, cache 1h z auto-renew i fail-fast startupem. - Klient API:
GscApiClient- jedyny interfejs do GSC, siteUrl encoding, smart retry (exponential backoff, daily-limit aware) i spójny model błędów. - Narzędzia: Cztery narzędzia
gsc__z akcjami jako discriminated union -sites(list/get/add/delete),analytics(query z auto-paginacją),sitemaps(list/get/submit/delete),inspect(URL Inspection). Write Operations chronione elicitation gate. - Caching:
UrlInspectionCache- SQLite 24h TTL chroniący limit 2 000 zapytań URL Inspection dziennie, z graceful degradation. - Produkcja: Dockerfile multi-stage (pure bundle, USER bun, HEALTHCHECK), GitHub Actions CI, graceful shutdown z drain phase (bounded cleanup, deterministyczny exit 0/1).
🎯 Problem biznesowy
Dane w Google Search Console są dostępne, ale bariera między nimi a zdolnością analizy jest wysoka. Człowiek z wieloletnim doświadczeniem SEO ma intuicję, ale manualne przeglądanie GSC UI jest na tyle uciążliwe, że analizy nie są prowadzone. Agent LLM potrafi przesiewać duże ilości danych, ale nie ma dostępu do GSC.
Serwer MCP zamyka tę lukę: agent staje się analitykiem, człowiek strategiem.
❌ „Bóle” i wyzwania operacyjne
- Uciążliwe UI: Przeglądanie GSC panelu przy 4-6 właściwościach to żmudna manualna praca.
- Limity API: URL Inspection ma limit 2 000 zapytań dziennie per właściwość, Search Analytics 1 200 na minutę - łatwo je wyczerpać.
- Różne formaty siteUrl:
sc-domain:example.comihttps://example.com/wymagają poprawnego encodowania w pathach. - Write Operations: Dodawanie/usuwanie właściwości i sitemap to operacje destrukcyjne - API nie ma granularnej kontroli uprawnień.
- Dane opóźnione: Search Analytics ma 2-3 dni opóźnienia, co bez kontekstu prowadzi do błędnych wniosków.
- Diagnostyka: Sprawdzanie stanu indeksacji konkretnego URL-a wymaga osobnego narzędzia i męczącej nawigacji.
💡 Dlaczego to działa? (Podejście produktowe)
- 4 narzędzia zamiast 10 endpointów: Konsolidacja w
gsc__sites,gsc__analytics,gsc__sitemaps,gsc__inspect- mniej schematów w kontekście LLM, mniej pomyłek, niższe zużycie tokenów. - Hints jako obserwacje, nie dyrektywy: Serwer opisuje dane (np. "7 zapytań na pozycji 5-10 z CTR < 3% - potencjał na optymalizację"), agent sam stawia hipotezę.
- Auto-discovery fan-out: Gdy agent nie poda
siteUrl, serwer sam znajduje właściwości, robi fan-out z rate limitingiem i etykietuje wyniki per właściwość. - Smart retry: Odróżnia limit per-minutowy (retry z backoff) od dziennego (natychmiastowy błąd z recovery hints) - nie marnuje prób API.
- Cache ochronny: URL Inspection cache 24h TTL eliminuje powtórne zapytania o ten sam URL (limit 2 000 QPD).
- Elicitation gate: Write Operations wymagają potwierdzenia użytkownika (kill switch
WRITE_OPS_ENABLED+ elicitation) - jedyna ochrona przed nieautoryzowanymi zmianami. - Autentykacja zero-interakcji: Service Account JWT działa headless - brak OAuth popupów, token auto-odnawia się co 5 minut.
- Graceful shutdown z drain phase: Bezpieczne redeploye - in-flight requesty się kończą, dane (sessions, cache, tokens) są flushowane przed exitem.
📈 Wpływ na pracę (ROI)
| Obszar | Przed Google Search Console MCP | Z Google Search Console MCP | Efekt |
|---|---|---|---|
| Analiza danych GSC | Ręczne przeglądanie panelu GSC | Konwersacyjne zapytania agenta | Mniej przełączania kontekstu |
| Znajdowanie striking distance | Ręczny eksport i sortowanie CSV | Zapytanie z wymiarami query/page + hints | Gotowi kandydaci do planu content |
| Diagnoza problemów SEO | Ręczne szukanie w panelu | gsc__inspect z cache (24h) | Szybsza diagnoza indeksacji |
| Write Operations | Ryzyko kosztownych błędów | Elicitation gate + kill switch | Bezpieczne zarządzanie zmianami |
„Zamiast tonąć w panelu GSC, można po prostu zapytać agenta: co się dzieje z domeną X? I dostać dane wraz z kontekstem do podjęcia decyzji.”
🛠️ Architektura i stack techniczny
- Runtime: Bun 1.3.0 (TypeScript strict, ESM)
- Protokół: MCP Streamable HTTP (@modelcontextprotocol/sdk ^1.29.0)
- HTTP: Hono + @hono/node-server
- Schema: Zod ^3.23 (JSON Schema dla MCP,
.describe()na każdym polu) - JWT/JWS: jose (Service Account RS256)
- Storage: bun:sqlite (sessions + cache), drizzle-orm/bun-sqlite, encrypted token store (AES-256-GCM)
- Testy: bun test (753 testów, 17 plików)
- CI/CD: GitHub Actions (lint + typecheck + test, 17 s, bun 1.3.0 pin)
- Deployment: Docker multi-stage (
oven/bun:1.3.0-alpine, pure bundle 111 MB, USER bun) + Dokploy/Traefik
🔒 Bezpieczeństwo i decyzje operacyjne
- Service Account JSON tylko w env/Docker secrets - nigdy w git.
- Dostęp do serwera chroniony Bearer tokenem (AUTH_STRATEGY: none/bearer/oauth/api_key/custom).
- Tokeny klientów szyfrowane AES-256-GCM (RS_TOKENS_ENC_KEY).
- Logger sanitizuje kluczowe wartości - sekrety nigdy nie trafiają do logów.
- Fail-fast startup w produkcji: brak poprawnego SA JSON = brak startu serwera.
- Write Operations zablokowane przez elicitation gate + kill switch WRITE_OPS_ENABLED.
- Graceful shutdown: drain (30 s) + force-close grace (2 s) + cleanup bound (15 s), deterministyczny exit 0/1,
tokenStore.flush()awaited przed exit. - Kontener działa jako non-root (USER bun), dane trwałe w VOLUME /app/.data.
✅ Walidacja
Projekt zawiera:
- 753 testów jednostkowych i integracyjnych (0 fail, 1 718 expect)
- lint (Biome) + typecheck (tsc) czyste, CI na GitHub Actions zielone w 17 s
- testy drain phase (single-close, timeout, resilience, re-entry guard, exit policy)
- testy cache (TTL, graceful degradation, odporność na corrupted rows)
- Docker smoke: build, /health 200, cold start 0.418 s (< 2 s NFR), RAM 27 MB idle (< 80 MB NFR), volume persistence po redeploy
- graceful shutdown smoke: SIGTERM →
Graceful shutdown complete+ tokens.json zapisany + exit 0 - Zustand: pełny flow E2E z MCP Inspector na realnych danych GSC
🚀 Dalsze plany
- Triage ~20 deferred debt items z deferred-work.md (decyzja: naprawić vs świadomie zostawić).
- OAuth user flow / multi-user - wielu użytkowników z własnymi właściwościami (oauth4webapi już w deps).
- Hardening produkcyjny: atomic token write, volume monitoring, backup .data.
- Rozszerzenie arsenalu narzędzi analitycznych - kolejne serwery MCP wg wizji PRD.
- Dystrybucja publiczna - projekt oznaczony jako eksperymentalny, brak pełnego zestawu funkcji roadmapy.
Artefakty
- Kod źródłowy: RafalWojciechRolsky/mcp-server-gsc
- Serwer MCP:
mcp-server-gsc - Szablon: streamable-mcp-server-template (Adam Gospodarczyk / overment / AI_DEVS)
- API: Google Search Console (webmasters/v3 + searchconsole.googleapis.com/v1)
