How Google Search Console Integration Works in OpenSEO
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 (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
connectUrlpointing to/p/<projectId>/search-performancefor settings access
See 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 datesfilters: Dimension filters for refined queriesrowLimit: 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:
clicksimpressionsCTR(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 lines 81-102.
Automatic Pagination Handling
When the returned row count equals rowLimit, the response includes:
{
"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.
// 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 lines 25-57.
// 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 encapsulates all direct Google API interaction. Responsibilities include:
- Token acquisition and automatic refresh
- Request construction and parameter serialization
- Error classification into
GscNotConnectedError,GscTokenError, andGscApiError
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. 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 |
MCP tool definitions for get_search_console_performance and inspect_urls |
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 |
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 |
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_performanceprovides paginated, filterable search analytics with automatic error recovery viaconnectUrl.inspect_urlsenables batch URL inspection with inline error reporting for up to 10 URLs.GscServicecentralizes OAuth token management, request construction, and error classification.- Self-hosted deployments receive guided setup errors through
missingSelfHostedGoogleClientResponsewhen credentials are absent. - The front-end interface at
/marketing/google-search-console-mcprenders 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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →