How to Connect Google Search Console to OpenSEO: Complete Integration Guide

Connect Google Search Console to OpenSEO via OAuth, select a property, and unlock the Search Performance and URL Inspection MCP tools.

OpenSEO integrates Google Search Console (GSC) as an optional data source that powers the Search Performance and URL Inspection tools. This guide explains how to connect Google Search Console to OpenSEO based on the source code in every-app/open-seo, covering both hosted deployments and self-hosted installations.

Architecture Overview

The GSC integration consists of several coordinated components defined in the OpenSEO source code:

Component Responsibility Source Location
OAuth Provider Identifies the GSC OAuth client and required scopes (openid, email, profile, https://www.googleapis.com/auth/webmasters.readonly) src/shared/gsc.ts
Self-hosted OAuth Config Reads GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and BETTER_AUTH_SECRET from environment variables src/server/features/google/oauth-config
GscService Handles all GSC API calls including token management, request building, and error translation src/server/features/gsc/services/GscService.ts
Server Functions TanStack Server Functions exposed to the frontend for connection management src/serverFunctions/gsc.ts
MCP Tools Implements get_search_console_performance and inspect_urls commands for the OpenSEO command palette src/server/mcp/tools/search-console-tools.ts

When any GSC-related MCP tool is invoked, the handler first checks missingSelfHostedGoogleClientResponse. For self-hosted deployments missing OAuth configuration, the user receives a message containing GSC_SELF_HOSTED_SETUP_DOCS_URL from src/shared/gsc.ts.

Connection Methods: Hosted vs. Self-Hosted

Hosted Version (Every App Managed)

Users on the hosted version require no environment configuration. The OAuth provider is pre-configured by Every App.

To connect Google Search Console to OpenSEO:

  1. Navigate to your project's Integrations settings
  2. Click Connect Search Console
  3. Authenticate with Google and authorize the Webmasters Read-only scope
  4. Select a property from your available GSC sites

Self-Hosted Version

Self-hosted deployments require manual OAuth configuration before users can connect.

Step 1: Configure Environment Variables

Set these variables in your OpenSEO instance:

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
BETTER_AUTH_SECRET=your-better-auth-secret

The hasSelfHostedGoogleOAuthConfig helper in src/server/features/google/oauth-config validates these values. If missing, the UI displays setup nudges pointing to GSC_SELF_HOSTED_SETUP_DOCS_URL.

Step 2: Initiate OAuth Flow

From a client component, call startSelfHostedGscLink:

// Called when the user clicks "Connect Search Console"
await startSelfHostedGscLink({
  callbackURL: `${window.location.origin}/auth/callback`,
}).then((resp) => {
  // Redirect the user to the Google consent screen
  window.location.href = resp.url;
});

Step 3: Complete Authentication

After Google redirects to your callback URL, the server stores the access and refresh tokens linked to the user's Better Auth account. The GscService class manages token refresh automatically.

Selecting and Binding a GSC Property

Once authenticated, users must bind a specific GSC property to their OpenSEO project.

List Available Sites

Call listGscSites to retrieve accessible properties:

const { accounts } = await listGscSites({ projectId });

accounts.forEach((grant) => {
  console.log(`Account ${grant.email} – sites:`);
  grant.sites.forEach((site) => {
    const status = site.isSelected ? '[selected]' : '';
    console.log(` • ${site.siteUrl} (${site.permissionLevel}) ${status}`);
  });
});

Bind a Site to the Project

Use setGscSite to create the connection:

await setGscSite({
  projectId,
  accountId: "<selected-account-id>",
  siteUrl: "https://example.com",
});

This creates a row in the gsc table defined in src/db/gsc.schema.ts, storing the accountId, siteUrl, and linking metadata.

Verify Connection Status

Call getGscConnection to confirm the link:

const connection = await getGscConnection({ projectId });
// Returns: { connected: true, siteUrl, connectedByEmail, createdAt, updatedAt }

The Integrations page displays this status to users.

Using GSC Data: MCP Tools

With an active connection, two MCP tools become available in the OpenSEO command palette.

Search Performance Tool

The get_search_console_performance tool queries GSC analytics data:

await getSearchConsolePerformanceTool.handler({
  projectId,
  dimensions: ["query", "page"],
  dateRange: "last_28_days",
});

Response includes:

  • rows — array of performance data with clicks, impressions, CTR, and position
  • hasMore — pagination flag
  • text — human-readable summary for UI display

Valid dimensions: query, page, country, device, searchAppearance. Valid date ranges: last_7_days, last_28_days, last_3_months, last_6_months, last_year, last_12_months.

URL Inspection Tool

The inspect_urls tool checks indexing status for specific URLs:

await inspectUrlsTool.handler({
  projectId,
  urls: ["https://example.com/blog/post"],
});

Response includes per URL:

  • verdict — overall status
  • coverageState — indexing state
  • canonical — canonical URL information

Error Handling

The describeGscError function in GscService.ts normalizes errors into user-friendly messages:

Error Type Cause User Action
GscNotConnectedError No property bound to project Visit /p/:projectId/search-performance to connect
GscTokenError Expired or revoked token Re-authenticate via OAuth flow
GscApiError GSC API failure Retry or check Google status

All errors include a Connect URL redirecting to the project's Search Performance dashboard.

Key Source Files

Reference these files when extending or debugging the GSC integration:

Summary

  • Hosted deployments require zero configuration—users connect directly via OAuth
  • Self-hosted deployments need GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and BETTER_AUTH_SECRET environment variables
  • The connection flow follows: OAuth grant → token storage → site selection → project binding
  • GscService.ts abstracts all GSC API interactions with automatic token refresh
  • Two MCP tools expose GSC data: get_search_console_performance and inspect_urls
  • Error states redirect users to /p/:projectId/search-performance for reconnection

Frequently Asked Questions

What's the difference between hosted and self-hosted GSC connection?

Hosted OpenSEO (managed by Every App) includes pre-configured OAuth credentials. Self-hosted instances require you to create a Google OAuth client and set GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and BETTER_AUTH_SECRET environment variables. The hasSelfHostedGoogleOAuthConfig check in src/server/features/google/oauth-config determines which flow executes.

What Google OAuth scopes does OpenSEO require?

OpenSEO requests openid, email, profile, and https://www.googleapis.com/auth/webmasters.readonly. The read-only Webmasters scope is defined in src/shared/gsc.ts as GSC_OAUTH_PROVIDER_ID. No write access to your Search Console properties is requested.

Can users connect multiple GSC properties to one OpenSEO project?

No—each OpenSEO project binds to exactly one GSC property via the setGscSite function, which creates a single row in the gsc table. Users with access to multiple GSC accounts can view all available sites through listGscSites, but must select one per project.

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 →