Skip to content

fenjo26/opengsc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

297 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenGSC

OpenGSC

Your Google Search Console, all in one place — plus an AI SEO content suite and a private indexing network.

Self-hosted on your own VPS. No subscriptions, no seat limits, no third party touching your data.

Version 1.0 License: MIT Next.js 16 TypeScript Self-hosted GitHub stars GitHub issues

Русская версия · English version

Website · Install · Features · SEO Tools · Indexer · Docs


curl -fsSL https://raw.githubusercontent.com/fenjo26/opengsc/main/install.sh | sudo bash

OpenGSC main dashboard

Why OpenGSC

Tools like seogets.com charge $19–$79/month to show you the Google Search Console data you already own, aggregated across sites. OpenGSC gives you the same core analytics — clicks, impressions, CTR, position, striking-distance keywords, content decay, cannibalization — for the cost of a $5/month VPS, because it is the VPS: one install script, your own SQLite database, your own domain, your own Google OAuth app. Nothing about your Search Console data ever passes through a third-party server.

On top of that dashboard, OpenGSC ships two things most GSC tools don't: a full AI-powered SEO content generation suite (/seo-tools — competitor research, entity-driven outlines, full articles, GEO/AI-search-citation audits, brand sentiment tracking) and a private indexing network (/indexer — your own doorway-domain infrastructure with cloaked bot verification, for operators who need fast, free indexing outside of Search Console's normal discovery flow).

OpenGSC Typical SaaS GSC dashboard
Price Free forever $19–$79/month
Hosting Your own VPS Their cloud
Data privacy 100% private Stored on their servers
Sites / Google accounts Unlimited Plan-limited
AI SEO content suite ✓ included, your own API key Rarely included
Private indexing network ✓ included Not offered
Open source
Setup time ~5 minutes, one command Instant sign-up

Trade-offs, honestly: you need a VPS and a domain (Google OAuth won't work against a bare IP), you run your own updates (git pull && npm run build && pm2 restart), and there's no built-in team/white-label layer. If that's an acceptable trade for owning your data and never paying a subscription, read on.


📑 Table of Contents


✨ Features

Unified GSC Dashboard

  • One dashboard, every account — every site from every connected Google account, on one screen, with a sparkline traffic chart per site.
  • Google · Bing · Yandex portfolio dashboards — switch the entire dashboard between search engines with one click. Google reads from your local store; Bing and Yandex pull live from their Webmaster APIs across every connected account — showing their own verified sites (not just the Google list), the same KPI cards, per-site sparkline cards, sorting, search, tags, and CSV. Live engine results are cached server-side, so a tab opens instantly after the first build; the Sync button refreshes all three engines at once.
  • Fast period controls — inline 7d / 28d / 3m / 6m / 12m / 16m buttons, plus Previous-period, Year-over-Year, or a fully custom range comparison.
  • Clicks / Impressions / CTR / Position shown as labeled toggles, with an aggregate summary across every visible site that recalculates instantly when you filter by tag.
  • Tags, favorites, sorting, hiding — organize hundreds of sites, remember your last sort order between sessions, pin the important projects, hide the dead ones.
  • Quick engine site search — next to each site name, a small badge opens a site:domain.com search in a new tab for instant manual indexing checks; it follows the active tab (G → Google, b → Bing, Я → Yandex).
  • Portfolio SEO Analytics — view aggregated Striking Distance keywords, Cannibalization, and Content Decay reports across your entire site network on the main dashboard.
  • Privacy Blur — one click blurs every account name, email, domain, and metric — safe to screen-share or screenshot.
  • Ahrefs DR badges — every site card (and the site detail header) shows the domain's Domain Rating, pulled from Ahrefs' free public endpoint and cached server-side for 7 days. No API key needed. Domain Rating by Ahrefs.
  • CSV export with selectable dimensions, and right-click → open in new tab on any site card.
Site dashboard

Site Detail & Advanced SEO Analytics

Every site gets its own deep-dive page with clicks/impressions/CTR/position trends, and four analyses that a stock GSC UI doesn't give you:

  • Striking Distance Keywords — queries ranking position 4–20 with real impression volume: your fastest wins to page 1.
  • Keyword Cannibalization — queries where multiple URLs on your own site compete against each other, with a clear winner/loser breakdown.
  • Content Decay Map — a heatmap of pages losing traffic over time, so you catch decay before it's a crisis.
  • CTR Benchmark — your actual click-through rate vs. industry-standard CTR curves by position, surfacing pages where a better title/meta could unlock clicks you're currently leaving on the table.
Site detail analytics
Country breakdown analytics

Google Analytics 4 & Microsoft Clarity

Link a GA4 property to any site (sessions, engagement, key events, revenue with period-over-period deltas) and a Microsoft Clarity project (session recordings / heatmap stats, aggregated over 30 days) — both optional, both configured once per Google account, both fully documented in docs/GA4-SETUP.md.

GA4 and Clarity integration

Rank Tracker

Track keyword rankings (country/language/device-aware) via your configured SERP provider (Serper, DataForSEO, or ScrapingRobot), checked on demand or daily, overlaid against real GSC average position, clicks, and impressions for the same query — so you can see whether a rank change actually moved traffic.

AEO Tracker — AI Answer Engine Visibility

"Answer Engine Optimization": tracks whether your site gets cited when real questions are asked to AI assistants — ChatGPT and Perplexity via live web-search citation matching, Claude and Grok via brand-mention detection — building a per-engine, per-question cited/not-cited history over time. Needs the API key(s) of whichever engines you want to track.

Backlinks Checker

A curated backlink inventory per site with liveness checks (is the link still there?) and indexed-status checks via XML River, rolled up into total / alive / dead / indexed counts.

Site Health Checks

One panel per site combining SSL certificate inspection (expiry, issuer, grade), a Google Safe Browsing blacklist check, a VirusTotal reputation check, and Core Web Vitals via the PageSpeed Insights API (mobile) — the latter three need their own free API keys, configured once in Settings.

Site Audit — Built-in Crawler

A free technical audit with zero external APIs: OpenGSC crawls your site from your own VPS (up to 500 pages, BFS from the root) and reports broken internal links, missing/too-long/duplicate titles, missing meta descriptions, H1 problems, noindex pages, canonical mismatches, thin content, images without alt, and slow responses — rolled up into a health score with a filterable per-page table. Runs as a background job in the site's Audit tab; results are kept as audit history.

Alerts & Digests — Telegram Notifications

Bring your own Telegram bot (one-time @BotFather setup, token pasted in Settings → Notifications) and OpenGSC pushes what matters straight to your chat — free, no third-party service:

  • Alerts (checked hourly, each event fires once): a tracked keyword fell N+ positions, a site's clicks dropped X%+ week-over-week, an SSL certificate is about to expire, a site audit came back with a low health score. Thresholds are configurable per rule.
  • Digests (the Digest tab): a portfolio report over all sites or one tag — so a site network you care about gets its own summary. The on-screen view is rich and full (explicit date range, portfolio KPIs, biggest gainers/losers by site, rising/falling queries, all striking-distance queries, sites needing attention, rank movements — each section with "show all" and CSV), while Telegram receives a shorter capped summary (4 000-char safe). Google / Bing / Yandex tabs split the report per engine (engine tabs reuse the cached engine portfolio). An optional AI conclusion (your own AI key) is written on top and is on by default when any AI key is configured. Preview on screen, send on demand, or schedule daily/weekly delivery.
  • A Slack Incoming Webhook can be connected alongside (or instead of) Telegram — alerts and digests go to every configured channel.

Shared Dashboards — Read-Only Guest Links

Share a site's dashboard with a client without giving them an account: site → Settings → Public Link generates a tokenized read-only URL (/share/…). Guests see that one site's analytics and nothing else; the link can be regenerated or revoked at any time. Pairs well with Privacy Blur for screenshots.

MCP Server — Connect AI Agents

OpenGSC ships a built-in MCP (Model Context Protocol) server at /api/mcp, so Claude Code, Claude Desktop, Cursor, Codex, or any MCP client can query your SEO data directly: sites, search performance, striking-distance keywords, cannibalization, rank tracking, AEO visibility, backlinks, Link Monitor mentions, site health, indexing status, audit results, and running arbitrary read-only SQL queries. Generate a token under Settings → API & MCP, then:

claude mcp add --transport http opengsc https://your-domain.com/api/mcp \
  --header "Authorization: Bearer <token>"

All tools read from your instance's local store — agent traffic never spends your SERP/AI credits or Google quota. The repo also ships ready-made agent skills in .agents/skills/ (performance review, link prospecting, AEO review, site triage) — copy them into your agent's skills folder for guided SEO workflows. Details: docs/MCP-SETUP.md.

Indexing Status Tools

Inside each site's "Indexing" tab: real sitemap discovery and sync (recursive, sitemap-index aware, up to 20k URLs), a searchable per-URL status table, genuine Google URL Inspection API checks through your own OAuth token, and three optional paid accelerators for URLs that need a push — 2index.ninja submission, NeuralIndexer (queued slow/fast/Yandex indexing with balance/job polling), and XML River index-status verification. Each accelerator is opt-in and needs its own account/API key.

It also includes built-in free integrations:

  • IndexNow Integration — push new or updated URLs dynamically to the IndexNow API protocol in one click for instant crawler notification (supported by Bing, Yandex, etc.).
  • Bing Webmaster Tools — an engine switcher on the site dashboard shows a full live Bing view next to your GSC data: clicks, impressions, CTR, weighted avg position, traffic chart, top queries, top pages, pages in the Bing index and crawl errors — plus sitemap submission (API or ping) from the Indexing tab.
  • Yandex.Webmaster — the same switcher shows the full live Yandex view: SQI (ИКС), pages in search/excluded, clicks/impressions chart, top queries with positions, and Yandex's own site diagnostics (FATAL/CRITICAL problems) — plus sitemap submission and quota-aware URL recrawl via your own OAuth token. The Sync button refreshes every connected engine at once. Setup: docs/SEARCH-ENGINES-SETUP.md.
  • Smart Sitemap URL inspection fallback — if a newly added site has no Search Console traffic or ranking query history, the inspection tool automatically crawls and retrieves up to 20 URLs from the site's sitemap.xml (or custom sitemap location) to inspect them.

🧠 AI SEO Content Suite (/seo-tools)

A full competitor-research-to-published-article pipeline, plus AI-search-visibility auditing — all under one settings screen for your AI/SERP/scraping keys. Everything here is optional and needs your own API key (Anthropic, Z.AI, OpenAI, Gemini, OpenRouter, Kimi/Moonshot, kie.ai, or any custom OpenAI-compatible endpoint) — pay-per-use at cost, no markup. Each provider card in Settings lets you pick the exact model from a live list fetched from the provider's API.

SEO Tools suite
Keyword Clustering — SERP-based topic grouping

Paste a keyword list and OpenGSC pulls a live TOP-10 SERP for each keyword, then hard-clusters keywords whose results share N+ overlapping URLs (threshold selectable, with an in-context guide) — the classic "one cluster = one page" planning method, grounded in what Google actually ranks together rather than semantic guesswork. Optional DataForSEO search volumes per keyword, CSV export, and a one-click handoff of any cluster straight into the Outline Generator. Runs as a background job — close the tab, the result lands in History.

Outline Generator — competitor-grounded content briefs

Enter a keyword, target country/language, and search engine (Google or Bing). OpenGSC runs a live SERP query, classifies every ranking page by site type (official store, monobrand, aggregator, forum/UGC, editorial) and intent (buy / info / review / listicle / use-case), lets you pick which competitors to analyze, scrapes them (direct fetch, falling back to Firecrawl on anti-bot pages), and runs a multi-pass pipeline:

  1. MAP — extract compact, verified facts from each competitor separately (specs, prices, entities, headings covered).
  2. REDUCE — build one Entity-Attribute-Value (EAV) outline from those facts: headings, per-section word budgets, weighted entities with roles, keywords, FAQ, visual-element suggestions (tables/infographics/checklists).
  3. Fact-scrub — an LLM pass actively corrects fabricated-looking specifics (wrong screen size, invented colors, wrong dates) before they can leak into the article.
  4. Structure-expand — grafts extra H3 subsections under headings that came back too flat.
  5. Heading-localize — translates/styles template headings into the article's actual language and narration voice.
  6. Volume-normalize — rescales every section's word budget so they actually sum to your target length.
  7. Section-enrich — deepens every section's entities/summary/copywriter-notes in parallel batches, so the outline reads like a real creative brief, not a skeleton.

Optional: a Casino RAG toggle grounds igaming-niche outlines (slots, casino brands) against a verified knowledge base of RTP/volatility/provider/launch-date facts, virtually eliminating hallucinated specs in that niche.

Text Generator — full articles from an outline

Takes any outline from History and writes the complete article as a background job (close the tab, come back later). Long outlines are written in small chunks (3–5 sections per model call, run in parallel) rather than one giant prompt — this keeps prose quality consistent instead of degrading into bullet-point sludge halfway through a 3,000-word article. Supports tone/persona, an editorial Policy, a table of contents, and three source-grounding modes: off, facts-only (real numbers, no competitor names/links), or cited (real numbers with inline source links, rate-limited to one link per 1-2 paragraphs).

A volume guard keeps the final word count within your target (±15%): expand thin drafts, iteratively trim bloated ones — and it runs as the very last step, after fact-checking, so a fact-correction pass can never silently re-inflate an article that was already trimmed to length. Failures surface a real reason (e.g. a provider's content-policy rejection) instead of a bare "generation failed."

Content Rewriter — refresh & de-duplicate pages into unique variants

Paste text or a page URL (auto-scraped) and get N unique variants (1–5) that keep the exact meaning, facts, numbers, entities, and links while rewording everything — same format in, same format out (HTML→HTML, Markdown→Markdown). Each variant shows a uniqueness score (word-trigram similarity vs. the source) and a word count, with copy / download. Optional target language and tone, and a "mask AI patterns" toggle that strips common machine tells (em-dashes, "furthermore", "it is important to note", unicode bullets…) for a more natural, human read. Runs on your own multi-provider AI (Anthropic / OpenAI / Kimi / …). Wired into Content Decay: every decaying page has a one-click Rewrite action that opens the tool with its URL prefilled — spot a page losing traffic, refresh it in seconds. Built for large affiliate networks where duplicate content across sites is a real risk.

Googlebot View — cloaking & PBN inspector for competitors

"See" any page the way Google's crawler does and catch what a normal browser visit hides. The tool fetches the same URL with several User-Agents (Googlebot smartphone, Googlebot desktop, a real browser, optionally Googlebot + SERP Referer), manually walks each redirect chain hop-by-hop, and diffs the responses to flag cloaking, hidden redirects, and PBN schemes — with a clear verdict banner (clean / suspicious / cloaking) and a comparison table of final status, final URL, canonical (HTML vs X-Robots-Tag), meta robots, hreflang, JS redirects (meta refresh / window.location), content volume, and indexability. For your own GSC-verified sites it adds a True Google View — Google's real verdict via the URL Inspection API (googleCanonical vs userCanonical, robots state, last crawl) — plus an optional Wayback snapshot. Honest technical model: it compares User-Agents (nobody can send requests "from Google's IPs"). Spec: docs/GOOGLEBOT-VIEW-SPEC.md.

Content Gap Analysis — what your page is missing

Point it at a keyword and (optionally) your existing URL. It pulls the SERP, scrapes the competitors you pick, and returns a structured gap report: topics, entities, and whole sections competitors cover that your page doesn't — each gap tagged with a recommendation (add / expand / merge / skip) and the specific competitor URLs that justify it. For improving a page you already have, rather than starting from zero.

Landing Page Builder — briefs, wireframes, and text for commercial pages

The same SERP → select → scrape research flow as Outline, aimed at conversion pages instead of articles. Four structuring strategies: mirror the SERP consensus, copy your own existing page 1:1, a hybrid of both, or an "SEO-block" layout (conversion blocks up top, a deep SEO text block underneath). Generates a technical brief (ТЗ), the brief plus full text, or a complete block-by-block wireframe (hero / USP bar / comparison table / FAQ / CTA, etc.). Distinctive: you can import your own page's structure either from its live HTML or — for non-technical users — from a screenshot, read by a vision-capable model.

GEO Audit — Generative Engine Optimization

Traditional rank tracking tells you nothing about whether an AI assistant recommends you. GEO Audit sends a real user question to an AI model with live web-search tool-use enabled and mines the model's own search trace and citations to answer: which brands/domains actually get surfaced and cited for this query, what "selection factors" drove the answer (pricing, support, feature breadth…), which source types dominate (official sites, marketplaces, review aggregators, forums, Wikipedia, editorial), and where your own coverage gaps are. Output is a brand leaderboard, a per-domain trust-signal table, a source-type breakdown, and narrative insight into what a brand needs to do to get cited. Runs on OpenAI or kie.ai only — no separate SERP key needed, since search happens inside the model's own tool call. Full history is persisted server-side.

Citation & Sentiment Tracker — brand mentions across the web

Not to be confused with GEO's AI-citation tracking — this tracks classic web-wide brand/keyword mentions and their sentiment, via DataForSEO's Content Analysis API: polarity (positive/neutral/negative), six emotion dimensions (anger, happiness, love, sadness, share, fun), a monthly mention trend, and the top citing domains. Needs only a DataForSEO key.

Link Monitor — competitor backlink watchlist (Ahrefs API)

Watch any set of competitor brand domains and pull their fresh quality backlinks through your own Ahrefs API v3 key, filtered the way link-building pros do (the detailed.com workflow): in-content links only, live, DR ≥ 50 (configurable), first seen within the last 3 months, one per referring domain. The report surfaces multi-linker domains — sites that link to two or more of your watched brands, i.e. your highest-probability outreach targets — plus an AI insights pass over the data: which content types earn links, in what context authors mention the brands, anchor patterns, and concrete content/PR opportunities. Not to be confused with the per-site Backlinks Checker above, which tracks your own curated link inventory.

Editorial Policy — one style guide, applied everywhere

Define — or have AI draft, grounded in your own brand pages — a reusable editorial policy: brand description and values, audience profile, voice/tone/formality, structural rules (headings, paragraph length, lists vs. tables), quality bar (citation style, E-E-A-T notes, fact-checking behavior), and hard restrictions (banned words/topics, compliance rules like "never fabricate a license — leave a placeholder instead"). Save up to 10, mark one active, and it's applied automatically across Outline, Text, and Landing generation.

History — every generation, resumable

A unified log across Cluster, Outline, Text, Analysis, and Landing runs. Generation jobs run server-side and fire-and-forget, so you can close the tab; History polls for completed jobs, auto-imports them, and auto-fails anything stuck "processing" for more than 20 minutes so nothing spins forever. History — along with your API keys, provider/model choices, and Editorial Policies — is automatically backed up server-side, so clearing browser data or switching browsers no longer loses your generations or settings: everything is restored on the next page load.


🕸️ Private Indexer Network

A self-hosted doorway-domain network for operators who need pages indexed fast and for free, outside the normal discovery flow Search Console relies on. You bring the domains; OpenGSC gives you the management console, the cloaking script, and the crawl-analytics to run them safely.

  • Domains — register a doorway domain, pick a generated-content template (Ecommerce / Directory / Blog / Portfolio), set the real "money site" redirect target, choose which bots are allowed in (Google / Bing / Yandex), and get a unique API key per domain.
  • Queue — bulk-paste the money-site URLs that should be woven as internal links into the next batch of generated doorway pages.
  • Dictionary — a keyword pool that seasons generated content, built manually or AI-generated per niche (ecommerce / crypto / finance / general).
  • Links — a visual cross-linking planner: pick a topology (ring / mesh / pyramid) across your owned domains, see an SVG node graph, export the HTML link snippet.
  • Settings — the deployment hub: generates ready-to-paste code in four flavors — dynamic PHP doorway, static PHP wrapper, an Astro SSR middleware, or an Nginx config that routes bots to index.php while serving humans static files directly.
  • Stats — a 30-day dashboard: hits by bot (Google / Yandex / Bing / Mail.ru / other / redirected humans), a stacked area chart, per-domain Google-hit-share, and a 304 Not Modified breakdown that tells you how efficiently each bot is re-checking pages without burning crawl budget. CSV export included.
  • Logs — a raw, filterable, optionally live-polling crawl log (time, domain, path, IP, detected bot, HTTP status).

How the cloaking works: the deployed script identifies bots by user-agent, then — if strict verification is on — runs a double DNS lookup: a reverse lookup of the visitor's IP must resolve to a known suffix (googlebot.com, yandex.ru, search.msn.com, mail.ru), and a forward lookup of that hostname must resolve back to the exact same IP. This defeats spoofed user-agents, since an attacker can't fake a PTR record inside Google's or Yandex's own IP ranges. Verified bots get a generated page (with ETag-based 304 short-circuiting on repeat crawls) and a logging ping; everyone else — humans and fake bots alike — gets redirected straight to the real site, so the doorway is invisible to anyone outside the whitelisted crawlers. Full setup walkthrough: docs/INDEXER-SETUP.md.

⚠️ See Disclaimer — doorway/cloaking techniques sit outside major search engines' webmaster guidelines. This is a power-user tool; understand the risk to a domain before pointing it at anything you can't afford to lose.


Requirements

Parameter Minimum Recommended
OS Ubuntu 22.04 LTS Ubuntu 22.04 / 24.04 LTS
CPU 1 vCPU 2 vCPU
RAM 1 GB 2 GB
Disk 10 GB SSD 20 GB SSD
Domain Required With SSL (Let's Encrypt)

Node.js, PM2, Nginx, and every dependency are installed automatically by the script — nothing to set up by hand.

⚠️ A domain is required. Google OAuth does not work against a bare IP address. Point a domain at your server's IP before installing.

Tested on Ubuntu 22.04 LTS; other Debian-based distros also work. CentOS/RHEL and Windows are not supported.


🚀 Installation

Prefer Docker? cp .env.template .env, fill it in, docker compose up -d — full guide in docs/DOCKER-SETUP.md. The steps below cover the recommended one-line VPS install.

1. Create a Google OAuth app (~5 minutes)

Every step below is a direct link that opens exactly the right page in Google Cloud Console. Sign in with the Google account that owns your Search Console sites.

  1. Create a project (or reuse one): console.cloud.google.com/projectcreate. Any name works, e.g. opengsc. Make sure this project stays selected in the top bar for all following steps.

  2. Enable the Search Console API: open console.cloud.google.com/apis/library/searchconsole.googleapis.com and click Enable.

  3. Configure the OAuth consent screen (required once before creating credentials): open console.cloud.google.com/auth/branding. Choose External, fill in the app name and your email — defaults are fine everywhere else. Then open console.cloud.google.com/auth/audience and add your own Google account (plus any accounts whose GSC sites you'll connect) under Test users.

  4. Create the OAuth client: open console.cloud.google.com/auth/clients/create (the same page is reachable via Credentials → Create Credentials → OAuth client ID at console.cloud.google.com/apis/credentials). Application type: Web application. Fill in:

    Field Value
    Authorized JavaScript origins https://your-domain.com
    Authorized redirect URIs https://your-domain.com/api/auth/callback/google

    Note: Google does not accept bare IP addresses here — a domain is required (the only exception is http://localhost for local development). Any subdomain you control works fine, e.g. gsc.your-domain.com.

  5. Copy the Client ID and Client Secret from the confirmation dialog — the installer asks for both. You can always find them again at console.cloud.google.com/apis/credentials.

Tip: if sign-in later fails with access_denied, your account isn't in Test users (step 3) — either add it there, or publish the app on the same page (Publish app).

2. Run the one-line installer

curl -fsSL https://raw.githubusercontent.com/fenjo26/opengsc/main/install.sh | sudo bash

The script clones the repo into /root/opengsc, then asks for: your domain, whether to install Nginx (recommended), whether to set up SSL via Let's Encrypt (recommended), an email for the SSL cert, and your Google Client ID/Secret. It then automatically installs Node.js 20 LTS, installs PM2 and runs the app as a managed service, configures Nginx as a reverse proxy, issues an SSL certificate via Certbot, and configures the UFW firewall (ports 22/80/443).

3. Open it

https://your-domain.com

Sign in with Google — the first account becomes the dashboard owner. Add more Google accounts under Settings → My Google Accounts; their sites appear on the dashboard automatically.


Manual Installation

Prefer to set everything up yourself? Click to expand.
# Clone
git clone https://github.com/fenjo26/opengsc.git
cd opengsc

# Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt-get install -y nodejs

# PM2
npm install -g pm2

# Project dependencies
npm install

# .env — copy the template and fill it in
cp .env.template .env
nano .env

# Database & build
npx prisma generate
npx prisma db push
npm run build

# Run
pm2 start npm --name opengsc -- start
pm2 save
pm2 startup

Environment Variables

Variable Description Example
DATABASE_URL Path to the SQLite database file:/root/opengsc/data/prod.db
NEXTAUTH_SECRET Random secret used to encrypt sessions openssl rand -base64 32
NEXTAUTH_URL The app's full URL, including domain https://your-domain.com
GOOGLE_CLIENT_ID From Google Cloud Console 123...apps.googleusercontent.com
GOOGLE_CLIENT_SECRET From Google Cloud Console GOCSPX-...

NEXTAUTH_URL must exactly match the Authorized redirect URI in Google Console, down to http:// vs https://. A mismatch causes redirect_uri_mismatch.

Generate a secret:

openssl rand -base64 32

Managing the App

pm2 logs opengsc       # view logs
pm2 restart opengsc    # restart
pm2 stop opengsc       # stop
pm2 status             # status of all processes

Updating to a new version

From the UI (easiest): when a newer version is on main, a "New version available" bar appears at the top of the dashboard. Click UpdateStart update and OpenGSC runs the whole upgrade on your server (fetch, install, migrate, rebuild, restart), streaming the log live; when it's done it prompts a page reload. The update button is owner-only and never shown to guests.

By hand (or for Docker):

cd /root/opengsc
git pull            # or: bash update.sh  (does everything below in one step)
npm install
npx prisma db push
npm run build
pm2 restart opengsc

Connecting Google Analytics 4

The GA4 tab on a site card shows real Google Analytics data — sessions, engagement, key events, and revenue, with period-over-period trends. It's fully optional: the dashboard and GSC work without it. If the GA4 tab is empty, the app shows an in-context step-by-step guide with buttons to enable the right APIs — the same steps are detailed in docs/GA4-SETUP.md, including common errors like insufficient authentication scopes and API has not been used in project ... or it is disabled.

Short version: enable the Google Analytics Data API and Google Analytics Admin API in the same Google Cloud project as your OAuth client, reconnect your Google account under Settings → My Google Accounts so it picks up the new analytics.readonly scope, make sure that account has at least Viewer access to the GA4 property in question, then link the property from the site's GA4 tab.


Setting Up the Indexer

The Indexer ships disabled by default — it's an advanced, opt-in module. Full walkthrough (domain setup, script deployment for PHP/Astro/Nginx, DNS verification behavior, and safe operating practices) lives in docs/INDEXER-SETUP.md.


Troubleshooting

GA4 tab is empty with ... API has not been used in project ... or it is disabled
The required Google API isn't enabled. Enable Google Analytics Data API and Google Analytics Admin API in the same Google Cloud project as your OAuth Client ID (links in Connecting Google Analytics 4), wait 1–2 minutes, and refresh.
GA4 tab shows insufficient authentication scopes
The account hasn't been granted Analytics access. Reconnect it under Settings → My Google Accounts — after re-authenticating, the account shows a GA4 ✓ badge.
GA4 property list is empty even though the APIs are enabled and access is granted
That Google account doesn't have access to the GA4 property itself. Add its email under Google Analytics → Admin → Property Access Management with at least the Viewer role.
redirect_uri_mismatch when signing in with Google
NEXTAUTH_URL in .env doesn't match the Authorized redirect URI in Google Console. They must be identical, including http:// vs https://. The redirect URI must be https://your-domain.com/api/auth/callback/google.
Infinite redirect to /login after signing in
Check NEXTAUTH_URL in .env — it must match your domain and protocol exactly, and the SSL certificate must be valid.
Database disappeared after a restart
Use an absolute path in DATABASE_URL, not a relative one. The installer sets this automatically (file:/root/opengsc/data/prod.db); on a manual install, set it explicitly.
pm2 restart opengsc doesn't pick up changes after git pull
Rebuild first:
npm run build && pm2 restart opengsc
Text generation fails with generation_failed
Check pm2 logs opengsc for a line starting with [LLM] — it carries the real provider status/error (invalid key, exhausted quota, a context-length limit on a very large outline, or the provider's own content-policy filter rejecting the topic). As of the latest version this reason is also surfaced directly in the job's error in History, so you shouldn't need to check server logs for most failures.

Tech Stack

  • Next.js 16 (App Router) + React 19 + TypeScript
  • Prisma 7 + SQLite (single-file database, zero external DB server)
  • NextAuth v4 — Google OAuth authentication
  • Recharts — charts and graphs
  • Google Search Console API / Google Analytics Data & Admin APIs — first-party data sources
  • Anthropic / Z.AI / OpenAI / Gemini / OpenRouter / Kimi (Moonshot) / kie.ai — pluggable AI providers for the SEO Tools suite
  • MCP server (/api/mcp) — connect Claude Code / Claude Desktop / Cursor / any MCP client to your data
  • Serper / DataForSEO / ScrapingRobot — SERP data providers; Firecrawl — scraping fallback; Ahrefs API — Domain Rating badges & Link Monitor backlinks
  • PM2 — process manager · Nginx — reverse proxy · Let's Encrypt — SSL · UFW — firewall

Project Structure

src/
  app/
    page.tsx                     # Main dashboard — every site, every account
    site/[id]/page.tsx           # Site detail: analytics, indexing status, health, backlinks, GA4, Clarity
    login/page.tsx
    settings/page.tsx            # Global settings — Google accounts, AI/SERP/API keys
    seo-tools/                   # AI SEO Content Suite
      cluster/page.tsx           # Keyword Clustering (SERP URL-overlap)
      outline/page.tsx           # Outline Generator
      text/page.tsx              # Text Generator
      analysis/page.tsx          # Content Gap Analysis
      landing/page.tsx           # Landing Page Builder (TZ / wireframe / text)
      geo/page.tsx                # GEO Audit (Generative Engine Optimization)
      citations/page.tsx         # Citation & Sentiment Tracker
      links/page.tsx             # Link Monitor (Ahrefs competitor backlinks)
      policy/page.tsx            # Editorial Policy builder
      history/page.tsx           # Unified generation history (server-backed)
      settings/page.tsx          # Redirects to global Settings
    indexer/                     # Private Indexer Network
      domains/page.tsx           # Doorway domain management
      queue/page.tsx             # Internal-link queue
      dictionary/page.tsx        # Content keyword pools
      links/page.tsx             # Cross-linking topology planner
      stats/page.tsx             # 30-day crawl analytics
      logs/page.tsx              # Raw crawl log
      settings/page.tsx          # Script generator (PHP / Astro / Nginx)
    api/
      auth/                      # NextAuth
      gsc/                       # Sites, accounts, sync, striking distance, cannibalization,
                                  # decay, CTR benchmark, URL inspection, health, branded keywords
      ga4/                       # Property linking & reporting
      clarity/                   # Microsoft Clarity snapshots
      rank/                      # Rank Tracker
      aeo/                       # AEO Tracker (AI answer-engine citations)
      backlinks/                 # Backlink inventory & liveness/index checks
      dr/                        # Ahrefs Domain Rating proxy (7-day SQLite cache)
      linkwatch/                 # Link Monitor: brands, Ahrefs v3 pull, AI insights
      audit/                     # Site Audit: built-in crawler (start/poll/results)
      mcp/                       # MCP server endpoint (Streamable HTTP, token auth)
      indexing/                  # Sitemap sync/inspection + 2index.ninja / NeuralIndexer / XML River
      indexer/                   # Doorway domains, queue, dictionary, stats, logs, webhook
      seo/                       # Outline, text, analysis, landing, geo, citations, policy,
                                  # background jobs, images, keyword data, model lists
  lib/
    auth.ts                      # NextAuth configuration
    prisma.ts                    # Prisma client
    llm.ts                       # Multi-provider LLM client (retry/backoff, error surfacing)
    seo/
      generate.ts                # Outline/text/analysis generation pipelines, volume guard
      prompts.ts                 # All LLM prompt builders
      rag.ts                     # Casino RAG knowledge base lookups
      serp.ts / scrape.ts        # SERP + competitor scraping providers
      history.ts / jobs.ts       # Client-side History + server-side background jobs
    PrivacyContext.tsx / ThemeContext.tsx / LayoutContext.tsx
  components/
    StrikingDistanceKeywords.tsx / KeywordCannibalization.tsx / ContentDecayMap.tsx / CtrBenchmark.tsx
    RankTracker.tsx / AeoTracker.tsx / ClarityPanel.tsx / SiteSettingsTab.tsx
  lib/
    mcp/tools.ts                 # MCP tool registry (read-only, Prisma-backed)
    audit/crawler.ts             # Site Audit crawler (BFS, regex extraction, issue detection)
prisma/
  schema.prisma                  # Full data model
.agents/skills/                  # Ready-made agent skills for the MCP server
install.sh                       # One-command VPS installer (Ubuntu/Debian)
Dockerfile / compose.yaml        # Docker deployment (docs/DOCKER-SETUP.md)
docs/
  GA4-SETUP.md
  INDEXER-SETUP.md
  MCP-SETUP.md
  DOCKER-SETUP.md
  ARCHITECTURE.md

Documentation

  • docs/ARCHITECTURE.md — how the app is built: the background job system, the multi-pass SEO generation pipeline, the multi-provider LLM abstraction, the MCP server, the audit crawler, the indexer's cloaking/verification mechanism, and the full data model.
  • docs/GA4-SETUP.md — connecting Google Analytics 4, step by step.
  • docs/MCP-SETUP.md — connecting AI agents (Claude Code, Claude Desktop, Cursor, Codex) to your instance.
  • docs/SEARCH-ENGINES-SETUP.md — Bing Webmaster, Yandex.Webmaster and IndexNow: getting the keys/tokens and what data each engine provides (site + portfolio dashboards, digests, and the site-search badge).
  • docs/GOOGLEBOT-VIEW-SPEC.md — the Googlebot View cloaking/PBN inspector: how the multi-UA fetch, redirect-chain walk, and cloaking diff work.
  • docs/DOCKER-SETUP.md — running OpenGSC with Docker instead of the VPS installer.
  • docs/INDEXER-SETUP.md — deploying and operating the private indexer network.

Disclaimer

The Private Indexer Network implements doorway pages and user-agent/DNS-based cloaking — techniques that sit outside the webmaster guidelines of Google, Bing, and Yandex, and can result in penalties up to and including deindexing for domains that use them. This module is provided as infrastructure tooling for users who understand and accept that risk; it is not enabled or required for any other part of OpenGSC. You are solely responsible for how you use it and for compliance with the terms of service of any search engine, hosting provider, or jurisdiction that applies to you. See also opengsc.org/disclaimer.


Contributing

Issues and PRs are welcome — this is a self-hosted, community-run project with no roadmap gatekeeping. If you're adding a feature, a short description of the use case in the issue/PR helps a lot; if you're fixing a bug, a pm2 logs opengsc excerpt or a reproduction is the fastest way to get it looked at.


License

MIT — free for personal and commercial use. Attribution appreciated but not required.

Built with ❤️ — free forever. Self-host it on your own VPS.

About

Open-source Google Search Console dashboard — sync GSC data, track rankings, analyze branded vs non-branded traffic. Self-hosted on your VPS.

Topics

Resources

License

Stars

9 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages