How to Integrate Google Search Console Data into OpenSEO: A Complete Technical Guide

OpenSEO integrates Google Search Console data through a layered architecture that separates OAuth authentication, service-level business logic, and server-function API endpoints, ensuring secure, client-side-free data retrieval using the user's own OAuth tokens.

The every-app/open-seo repository implements a robust Google Search Console (GSC) integration that allows projects to pull search analytics, inspect URLs, and manage property connections without persisting raw Google data beyond the essential connection records. This guide examines the exact file structure, service methods, and implementation patterns used to stream GSC data into the platform's reporting UI.

OAuth Configuration and Constants

All Google Search Console OAuth configuration resides in src/shared/gsc.ts. This file defines the provider ID (google-search-console) and required OAuth scopes that enable the application to query search analytics and site data on behalf of the user.

The low-level HTTP client wrapper, createGscClient, is exported from src/server/lib/gscClient.ts (imported throughout the service layer). This client encapsulates direct calls to the Google Search Console REST API, including listSites, querySearchAnalytics, and inspectUrl operations.

The GscService Layer

The core business logic for integrating Google Search Console data into OpenSEO lives in src/server/features/gsc/services/GscService.ts. This service orchestrates grant detection, connection management, and data retrieval while handling token-related failures gracefully.

Grant Detection

The userHasGrant method checks the account table for an existing Google Search Console grant by searching for providerId = "google-search-console". This determines whether the authenticated user has previously authorized the application to access their GSC data.

Connection Handling

getConnection, setSite, and disconnect manage the one-to-one mapping between an OpenSEO project and a GSC property:

  • getConnection: Retrieves the current project-to-property link from GscConnectionRepository
  • setSite: Binds a selected GSC property to a specific project, persisting the relationship
  • disconnect: Removes the link between a project and its associated GSC property

Data Retrieval

The getPerformance method forwards searchAnalytics.query requests to the GSC client. It returns rows of search performance data, request metadata, and the property's URL, which powers the platform's dashboard and CSV export features.

URL Inspection

inspectUrls runs batch URL inspections against the connected property. This method handles per-URL errors individually while propagating authentication failures (token expiration or revocation) upward for UI handling.

Error Handling

The service defines GscNotConnectedError to signal when a project lacks a linked GSC property. The isExpectedGrantFailure utility identifies 401/403 responses or token-related errors that should trigger a reconnection UI rather than display as internal server errors.

Server-Function API Endpoints

The public API exposed to the frontend resides in src/serverFunctions/gsc.ts. These server functions bridge the UI and the GscService layer:

  • getGscGrantStatus: Returns whether the authenticated user has authorized GSC access ({ connected: true|false })
  • getGscConnection: Provides the current project's connection status, including grant validity and site URL
  • listGscSites: Lists all GSC properties available to the user, marking which site is currently bound to the project
  • setGscSite: Executes GscService.setSite to bind a selected property
  • disconnectGsc: Removes the project-to-property link via GscService.disconnect
  • startSelfHostedGscLink: Generates an OAuth authorization URL for self-hosted deployments

Performance Data Integration

Search performance reports leverage src/serverFunctions/searchPerformance.ts, which calls GscService.getPerformance to assemble dashboard data, analytics tables, and CSV exports. Additionally, the MCP debugging tools in src/server/mcp/tools/search-console-tools.ts utilize the same service methods for development and diagnostics.

The data flow follows this architecture:


Frontend → Server Functions (gsc.ts) → GscService → GscConnectionRepository / GSC Client → Google Search Console API

All GSC data fetching occurs server-side only, using the user's own OAuth token without exposing credentials to the client or persisting raw Google data beyond the project-specific connection record.

Implementation Examples

Check grant status before displaying GSC features:

const { connected } = await getGscGrantStatus();
// Returns: { connected: true } or { connected: false }

List available properties for the user to select:

const { accounts } = await listGscSites({ projectId: "proj_123" });

accounts.forEach(account => {
  console.log(`Account ${account.email} has ${account.sites.length} sites`);
});

Connect a project to a specific GSC property:

await setGscSite({
  projectId: "proj_123",
  accountId: "gsc_acc_456",
  siteUrl: "https://example.com/",
});

Fetch search performance metrics for a date range:

const report = await getSearchPerformanceReport({
  projectId: "proj_123",
  dateRange: { start: "2024-01-01", end: "2024-01-31" },
  device: "mobile",
});

console.log(report.totals);

Summary

Frequently Asked Questions

What OAuth scopes does OpenSEO require for Google Search Console access?

OpenSEO requires standard Google Search Console API scopes defined in src/shared/gsc.ts, which typically include read-only access to search analytics data and site management permissions. The application uses these scopes solely to query searchAnalytics.query and inspectUrl endpoints, never persisting raw Google data beyond the connection metadata stored via GscConnectionRepository.

How does OpenSEO handle expired or revoked OAuth tokens?

The GscService implements isExpectedGrantFailure to detect 401 and 403 responses or token-related errors. When encountered, these errors surface to the frontend as expected grant failures rather than internal server errors, triggering the reconnection UI. Users must then re-authorize through startSelfHostedGscLink or the standard OAuth flow to restore access.

Can I connect multiple Google Search Console properties to a single OpenSEO project?

No, the architecture enforces a one-to-one mapping between a project and a GSC property. The setSite method in GscService binds one specific siteUrl to a given projectId, and getConnection retrieves only that singular relationship. To analyze multiple properties, you must create separate OpenSEO projects for each GSC site.

Where does OpenSEO store Google Search Console connection data?

Connection metadata persists in the database through GscConnectionRepository, storing only the project-to-property mapping (project ID, account ID, and site URL). Raw search analytics data is never persisted; instead, getPerformance fetches fresh data from Google's API on each request using the stored OAuth grant, ensuring reports always reflect current GSC metrics.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →