Building a Google Search Console MCP server
How I designed a production MCP service that connects AI assistants to Google Search Console while keeping OAuth, data access, persistence and tool boundaries explicit.
The problem
Search Console contains useful first-party search data, but working with it normally means moving between the Google UI, exports and separate analysis tools. I wanted an interface an AI assistant could use directly without turning Search Console access into an unrestricted API proxy.
The result is Search Console Insights: a dedicated MCP service that exposes a deliberately small set of Search Console operations and keeps the authentication, limits and workflow state on the server side.
A constrained MCP tool surface
The service exposes tools for connected-account discovery, property listing, Search Analytics queries, period comparisons, opportunity discovery, URL indexing inspection and sitemap inspection. Inputs are validated and bounded instead of allowing arbitrary Google API calls.
This makes the MCP layer an application boundary rather than a thin transport wrapper. The assistant gets the operations it needs for SEO analysis while the server retains control over date ranges, row counts and accessible resources.
OAuth as part of the product architecture
The service implements the OAuth flow required for a remote MCP integration: protected-resource metadata, authorization-server metadata, client registration, Google authorization, token exchange and bearer-token authentication.
Google refresh tokens stay server-side and are associated with the authenticated MCP identity. The client never receives Google credentials directly, which keeps the AI tool surface separate from the upstream authentication mechanism.
Persistent SEO workflow state
Search Console performance responses are read from Google and kept only in a short-lived in-memory cache. They are not copied into the application database.
Persistent storage is reserved for user-created SEO workflow state: planned actions and implemented change records. Those records are isolated by authenticated Google subject and Search Console property, so one connected account cannot read another account's workflow history.
Security and failure boundaries
OAuth secrets and database credentials are environment-only. The service does not provide arbitrary outbound URL fetching, and generic HTTP or storage failures avoid leaking upstream credentials or connection details.
The code also keeps request ranges and result sizes bounded, validates tool inputs with Zod and separates Search Console access from PostgreSQL persistence. These constraints are important because an MCP server is both an integration layer and an execution boundary for an AI client.
Production delivery
The service runs on Node.js with a streamable HTTP MCP transport, health checks and a small web surface for product, support, privacy and terms pages. TypeScript type checking, Vitest tests and MCP smoke tests are part of the development workflow.
It is deployed as an independent service on Render, with PostgreSQL used only when persistent SEO workflow state is enabled. This keeps the Search Console integration deployable and operable as its own backend rather than coupling it to a portfolio or dashboard application.
What this project demonstrates
This project sits at the intersection of backend engineering, AI tooling and API integration. The interesting part is not simply calling Google Search Console; it is designing the contract that an AI system is allowed to use and making authentication, state, isolation and failure behavior explicit.
It reflects how I approach agentic engineering in production: give agents useful capabilities, but put those capabilities behind clear interfaces, validation and operational boundaries.
Related technical writing
Technical deep dives into architecture and implementation decisions used in this project.