How to Connect and Authenticate Google Search Console in OpenSEO

OpenSEO authenticates Google Search Console through an OAuth 2.0 flow that stores grants in a gsc_grants table and automatically handles token refresh and reconnection.

Connecting your Google Search Console account to OpenSEO enables the platform to pull search analytics, inspect URL indexing status, and monitor site performance directly within your dashboard. This integration relies on a secure, standards-compliant OAuth 2.0 implementation that the OpenSEO team built into their generic authentication layer.

OAuth Provider Configuration

The GSC integration starts with provider registration in src/shared/gsc.ts. This file defines the unique provider identifier and the specific Google API scopes required for read-only access:

// src/shared/gsc.ts
export const GSC_OAUTH_PROVIDER_ID = "google-search-console";
export const GSC_OAUTH_SCOPES = [
  "https://www.googleapis.com/auth/webmasters.readonly",
];

These constants get referenced across the codebase whenever GSC-specific OAuth operations occur.

The global authentication configuration in src/lib/auth-config.ts registers this provider so the OAuth engine knows which scopes and redirect URLs to apply:

// Inside the OAuth providers array in src/lib/auth-config.ts
{
  providerId: GSC_OAUTH_PROVIDER_ID,  // line 41
}

This registration happens once at application startup and enables all subsequent GSC linking flows.

Initiating the Connection Flow

When a user clicks Connect Google Search Console, the client-side code in src/client/features/integrations/startGoogleLink.ts handles the handoff to Google's consent screen:

// Client-side initiation
import { startGoogleLink } from '@/client/features/integrations/startGoogleLink';

// Called from a button click
await startGoogleLink({ integration: 'gsc' });

The startGoogleLink function forwards GSC_OAUTH_PROVIDER_ID to the generic startOAuthLink helper, which redirects the user to Google's OAuth consent screen with the exact scopes defined in src/shared/gsc.ts.

Callback Handling and Token Storage

After the user grants permission, Google redirects back to OpenSEO's OAuth callback endpoint. According to the source code in every-app/open-seo, this callback:

  1. Creates a grant linked to the authenticated user
  2. Stores the grant in the gsc_grants database table
  3. Associates the grant with providerId: "google-search-console"

This grant persists the refresh token and expiration metadata needed for subsequent API calls without requiring repeated user consent.

Service Layer: GscService

The src/server/features/gsc/services/GscService.ts file orchestrates all GSC interactions. It reads the user's stored grant and creates a GscClient instance:

// GscService retrieves the grant using the provider ID
providerId: GSC_OAUTH_PROVIDER_ID  // line 41

GscService validates connections on every request and automatically detects expired or revoked tokens (lines 83 and 128). When a token fails validation, it surfaces a reconnect UI rather than throwing raw errors—this graceful degradation keeps the user experience smooth.

Key methods exposed by GscService:

  • searchAnalytics – Query search performance data with dimensions and filters
  • inspectUrls – Check URL indexing status and coverage issues
  • disconnect – Remove the stored grant and revoke server-side tokens

Low-Level API Client

The src/server/lib/gscClient.ts file builds the authenticated HTTP client that talks directly to Google's Search Console API. When constructing a client, it passes the provider ID to ensure the correct grant gets loaded:

// src/server/lib/gscClient.ts, line 96
const client = createGscClient({ 
  userId, 
  gscAccountId, 
  providerId: GSC_OAUTH_PROVIDER_ID 
});

This client handles request signing, quota management, and standardized error responses that GscService can interpret.

Server-Function API

The public interface for the UI lives in src/serverFunctions/gsc.ts. This file exposes functions that:

  • Return connection state (googleOAuthConfigured)
  • Allow property selection from available GSC sites
  • Trigger disconnect or reconnect flows

Key implementation details include provider selection at line 73 and disconnect event handling at line 124.

Querying Search Console Data

Once authenticated, your server functions can query analytics data through GscService:

import { GscService } from '@/server/features/gsc/services/GscService';
import { SearchAnalyticsRequest } from '@/server/lib/gscClient';

export async function getSearchPerformance(
  projectId: string, 
  request: SearchAnalyticsRequest
) {
  // GscService pulls the stored grant, refreshes tokens if needed
  const rows = await GscService.searchAnalytics({ projectId, request });
  return rows; // array of GscSearchAnalyticsRow
}

To disconnect a property:

import { GscService } from '@/server/features/gsc/services/GscService';

await GscService.disconnect({ userId: currentUser.id, projectId });

Error Handling

GSC-specific errors like GscNotConnectedError and token revocation scenarios are defined in src/server/lib/gscErrors.ts. The MCP tooling in src/server/mcp/tools/search-console-tools.ts translates these into friendly UI messages, with the specific reason code gsc_oauth_not_configured returned at line 86 when authentication is missing or invalid.

This layered error handling ensures users see actionable messages like "Reconnect Google Search Console" rather than cryptic OAuth failures.

Complete File Reference

File Purpose
src/shared/gsc.ts Provider ID and OAuth scope constants
src/lib/auth-config.ts Global OAuth provider registration
src/client/features/integrations/startGoogleLink.ts Client-side link initiation
src/server/lib/gscClient.ts Low-level authenticated HTTP client
src/server/features/gsc/services/GscService.ts Core service for connection management and API calls
src/serverFunctions/gsc.ts Public server-function API
src/server/lib/gscErrors.ts GSC-specific error definitions
src/server/mcp/tools/search-console-tools.ts Error translation for UI

Summary

  • Provider registration in src/shared/gsc.ts defines the OAuth identity and read-only scopes for Google Search Console
  • Client-side initiation via startGoogleLink redirects users through Google's consent flow
  • Grant storage persists tokens in gsc_grants with automatic refresh handled by GscService
  • Service layer in GscService.ts validates connections, detects revocation, and exposes searchAnalytics and inspectUrls methods
  • Error handling surfaces reconnect prompts rather than raw OAuth failures, maintaining UX quality

Frequently Asked Questions

What permissions does OpenSEO request from Google Search Console?

OpenSEO requests the https://www.googleapis.com/auth/webmasters.readonly scope, which provides read-only access to search analytics, URL inspection data, and site coverage information. The platform cannot modify your site configuration or submit URLs for indexing with this scope alone.

How does OpenSEO handle expired or revoked tokens?

The GscService class validates tokens before every API call and automatically detects expiration or revocation at lines 83 and 128 of src/server/features/gsc/services/GscService.ts. When detection occurs, it returns a state that triggers a reconnect UI rather than failing the request—users simply click to re-authenticate without losing their configuration.

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

Yes. The gsc_grants table stores grants per user, and GscService supports selecting from multiple available properties through the server-function API in src/serverFunctions/gsc.ts. The UI can present all properties the authenticated Google account has access to, letting users choose which to associate with each project.

Where is the OAuth client secret stored in OpenSEO?

The analysis shows provider configuration in src/shared/gsc.ts and src/lib/auth-config.ts, but client secrets for the OAuth application are handled at the infrastructure level within OpenSEO's deployment environment— they do not appear in the referenced source files. This follows security best practices of keeping secrets out of version control and using environment-specific secret management.

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 →