# How Google Search Console Integration Works in OpenSEO

> Discover how OpenSEO integrates Google Search Console using server-side MCP tools for authenticated performance queries and automatic data handling. Learn more today.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-08-14

---

**OpenSEO integrates Google Search Console (GSC) through server-side MCP (Managed Control Panel) tools that authenticate via OAuth, execute performance queries via `GscService`, and return formatted results with automatic pagination and error recovery.**

OpenSEO's Google Search Console integration enables users to query search performance data and inspect URLs directly from the MCP interface. The system is implemented in `every-app/open-seo` as a set of authenticated server tools backed by a dedicated service layer. This guide explains the complete flow from authentication to data retrieval.

## Authentication and Project Context

All GSC operations begin with credential validation and project authorization.

### OAuth and Environment Configuration

The integration requires a Google OAuth client (client ID and secret) plus the `BETTER_AUTH_SECRET`. In hosted deployments, these are pre-configured. For self-hosted deployments, the helper `missingSelfHostedGoogleClientResponse` in [`src/server/mcp/tools/search-console-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/search-console-tools.ts) (lines 70-88) verifies credentials at runtime. If credentials are missing, it returns a structured error containing a link to `GSC_SELF_HOSTED_SETUP_DOCS_URL` for guided setup.

### Project Authorization Wrapper

Every request passes through `withMcpProjectAuth`, which validates that the caller has access to the specified project. This middleware injects a `ProjectAuthContext` containing the organization ID and base URL. The context is used to:

- Build meta-information for MCP responses
- Generate a `connectUrl` pointing to `/p/<projectId>/search-performance` for settings access

See [`src/server/mcp/tools/search-console-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/search-console-tools.ts) lines 61-66 for the context injection logic.

## Performance Data Queries with `get_search_console_performance`

The `get_search_console_performance` MCP command retrieves search analytics data through a fully typed, validated pipeline.

### Input Validation and Parameter Mapping

The tool accepts input validated by Zod through `perfInputSchema` (typed as `PerfArgs`). Parameters mirror the GSC Search Analytics API:

- `dimensions`: Array of grouping dimensions (`"query"`, `"page"`, `"country"`, `"device"`, `"searchAppearance"`, `"date"`)
- `dateRange`: Predefined ranges or custom start/end dates
- `filters`: Dimension filters for refined queries
- `rowLimit`: Maximum rows per request (affects pagination)
- `startRow`: Offset for paginated retrieval

### Service Execution and Response Formatting

After authorization, the handler calls `GscService.getPerformance` with a `GscPerformanceInput` object. The service returns rows containing:

- `clicks`
- `impressions`
- `CTR` (click-through rate)
- `position` (average position)

Results are formatted into a markdown table via `formatMcpTable` with a human-readable summary. The implementation resides in `getSearchConsolePerformanceTool` at [`src/server/mcp/tools/search-console-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/search-console-tools.ts) lines 81-102.

### Automatic Pagination Handling

When the returned row count equals `rowLimit`, the response includes:

```json
{
  "hasMore": true,
  "nextStartRow": 101
}

```

Clients can use `nextStartRow` to request subsequent pages without manual offset calculation.

### Error Recovery and Reconnection

Errors such as *not connected* or *token revoked* are caught and transformed via `describeGscError`. The response always includes a `connectUrl` for immediate reconnection, minimizing user friction.

```tsx
// Example: Fetch top queries for the last 28 days
await openSeo.mcp.runTool(
  "get_search_console_performance",
  {
    projectId: "proj_ABC123",
    dimensions: ["query"],
    dateRange: "last_28_days",
    rowLimit: 100,
  },
);

```

## URL Inspection with `inspect_urls`

The `inspect_urls` command provides direct access to GSC's URL Inspection API for up to 10 URLs per request.

### Input Schema and Validation

The tool validates:

- `urls`: Array of absolute URLs (maximum 10)
- `languageCode`: Optional BCP-47 language code for localized results

### Batch Inspection and Result Summarization

The handler forwards to `GscService.inspectUrls`, which calls the GSC URL Inspection endpoint for each URL. Results are summarized as:

- First 15 rows displayed with verdict, coverage state, and Google-selected canonical
- Per-URL errors displayed inline without failing the entire batch

The implementation is contained in `inspectUrlsTool` at [`src/server/mcp/tools/search-console-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/search-console-tools.ts) lines 25-57.

```tsx
// Example: Inspect a list of URLs
await openSeo.mcp.runTool(
  "inspect_urls",
  {
    projectId: "proj_ABC123",
    urls: [
      "https://example.com/blog/how-to-use-open-seo",
      "https://example.com/about",
    ],
    languageCode: "en-US",
  },
);

```

## The GscService Abstraction Layer

`GscService` in [`src/server/features/gsc/services/GscService.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/gsc/services/GscService.ts) encapsulates all direct Google API interaction. Responsibilities include:

- Token acquisition and automatic refresh
- Request construction and parameter serialization
- Error classification into `GscNotConnectedError`, `GscTokenError`, and `GscApiError`

This separation allows MCP tools to remain focused on request handling and response formatting while the service manages API complexity.

## Front-End MCP Interface

Users interact with GSC tools through the dedicated route `/marketing/google-search-console-mcp`, implemented in [`web/src/routes/_marketing/google-search-console-mcp.tsx`](https://github.com/every-app/open-seo/blob/main/web/src/routes/_marketing/google-search-console-mcp.tsx). This page:

- Loads tool definitions dynamically
- Generates forms from Zod schemas for type-safe input
- Streams MCP responses with formatted tables and status indicators

Documentation is maintained in `web/content/marketing/google-search-console-mcp.mdx` for in-context help.

## Key Files in the Integration

| File | Purpose |
|------|---------|
| [`src/server/mcp/tools/search-console-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/search-console-tools.ts) | MCP tool definitions for `get_search_console_performance` and `inspect_urls` |
| [`src/server/features/gsc/services/GscService.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/gsc/services/GscService.ts) | Google API wrapper with token management and error mapping |
| [`web/src/routes/_marketing/google-search-console-mcp.tsx`](https://github.com/every-app/open-seo/blob/main/web/src/routes/_marketing/google-search-console-mcp.tsx) | Browser-based MCP interface for GSC tools |
| `web/content/marketing/google-search-console-mcp.mdx` | UI documentation and usage guidance |
| [`specs/0003-google-search-console-integration.md`](https://github.com/every-app/open-seo/blob/main/specs/0003-google-search-console-integration.md) | Architectural specification for the integration |

## Summary

- **Google Search Console integration in OpenSEO** operates through authenticated MCP server tools, not direct browser API calls.
- **`get_search_console_performance`** provides paginated, filterable search analytics with automatic error recovery via `connectUrl`.
- **`inspect_urls`** enables batch URL inspection with inline error reporting for up to 10 URLs.
- **`GscService`** centralizes OAuth token management, request construction, and error classification.
- **Self-hosted deployments** receive guided setup errors through `missingSelfHostedGoogleClientResponse` when credentials are absent.
- **The front-end interface** at `/marketing/google-search-console-mcp` renders schema-generated forms for tool execution.

## Frequently Asked Questions

### How does OpenSEO authenticate with Google Search Console?

OpenSEO uses OAuth 2.0 with a Google client ID and secret, combined with `BETTER_AUTH_SECRET`. The `GscService` handles token acquisition, storage, and automatic refresh. For self-hosted instances, the system validates credentials at request time and returns a setup guide link if configuration is incomplete.

### What happens if my GSC connection expires or is revoked?

The error handler `describeGscError` classifies token and connection errors, returning a friendly message alongside a `connectUrl` pointing to your project's Search Console settings. The MCP response includes both the error description and a direct path to reconnection.

### Can I query more than 100 rows of performance data?

Yes. Specify your desired `rowLimit` (up to Google API maximums). When results reach this limit, the response includes `hasMore: true` and `nextStartRow`. Submit a follow-up request with `startRow` set to this value to retrieve subsequent pages.

### Which dimensions can I group by in performance queries?

The `dimensions` parameter accepts any combination of: `query`, `page`, `country`, `device`, `searchAppearance`, and `date`. These map directly to GSC Search Analytics API dimensions, allowing flexible aggregation of clicks, impressions, CTR, and position data.