What Is the MCP Server in OpenSEO? Architecture and Implementation Guide

The MCP (Model Context Protocol) server in OpenSEO is a standards-compliant gateway that transforms the platform's internal SEO research capabilities—including keyword research, backlink analysis, and Google Analytics reporting—into a JSON-RPC API accessible to AI agents and external tools.

The every-app/open-seo repository implements this protocol layer to expose complex SEO operations through a unified, versioned interface. By abstracting database queries and third-party API integrations into discrete tool definitions, the MCP server enables AI systems to perform technical SEO audits, retrieve SERP data, and manage keyword projects without direct access to underlying infrastructure.

Core Architecture of the OpenSEO MCP Server

The MCP server operates as a thin orchestration layer between HTTP transport and domain-specific logic. It manages protocol compliance, authentication enforcement, and tool dispatch while delegating actual SEO computations to specialized modules under src/server/mcp/tools/.

Server Definition and Metadata

At initialization, the createOpenSeoMcpServer factory constructs a McpServer instance populated with OpenSEO-specific metadata. This includes the service name, version identifier, descriptive text, and UI icons that appear in MCP client interfaces.

import { createOpenSeoMcpServer } from '@/server/mcp/server';
import { McpProps } from '@/server/mcp/context';

// `authProps` are built from the authenticated user (OAuth, Cloudflare Access, etc.)
const mcpServer = createOpenSeoMcpServer(authProps);

See the factory implementation in [src/server/mcp/server.ts](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts#L28-L35).

Tool Registration System

The registerOpenSeoTool helper normalizes each SEO tool's Zod schemas for inputs and outputs, instruments handlers with logging, and attaches a per-request context before registration. This function wires up all domain tools—including keyword research, backlink profiling, rank tracking, Google Search Console integration, GA4 metrics, and site audit functionality—to the central server instance.

type KeywordTool = {
  name: 'list_saved_keywords';
  config: {
    title: 'List Saved Keywords';
    description: 'Returns every keyword a user has saved.';
    inputSchema: z.object({ projectId: z.string() });
    outputSchema: z.array(z.string());
  };
  handler: async (args, ctx) => ({
    result: await KeywordRepo.list(args.projectId),
  });
};

registerOpenSeoTool(server, KeywordTool, authProps);

The registration logic resides in [src/server/mcp/server.ts](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts#L99-L125).

Request Transport and Routing

The transport layer in src/server/mcp/transport.ts exposes the /mcp HTTP endpoint and handles protocol negotiation. It distinguishes between modern Streamable HTTP MCP connections and legacy JSON-RPC 2.0 requests, applying uniform CORS headers via the MCP_CORS_HEADERS constant to support browser-based agents.

For legacy clients, the handleLegacyJsonRequest function creates a temporary McpServer instance, streams the response through WebStandardStreamableHTTPServerTransport, and performs resource cleanup after request completion.

Authentication and Scope Enforcement

Every MCP request must carry the MCP OAuth scope (MCP_SCOPE) defined in src/server/mcp/oauth-provider.ts. The transport layer validates this scope in the JWT claims before processing:

  • Hosted deployments: Verify the MCP auth context from Cloudflare Access tokens and abort with 403 if the scope is missing
  • Self-hosted deployments: Resolve user identity via local authentication flows and synthesize an equivalent MCP auth payload

Validation logic appears in [src/server/mcp/transport.ts](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts#L45-L58).

Context Injection and Execution Flow

Before invoking any tool handler, the server builds a specialized execution context via createMcpToolContext. This function extracts the authenticated user's ID, email, organization, and client ID from the verified auth payload, attaching this ToolContext to every SEO operation.

Context creation is implemented in [src/server/mcp/context.ts](https://github.com/every-app/open-seo/blob/main/src/server/mcp/context.ts#L63-L85).

This design ensures that:

  • Database queries are automatically scoped to the requesting organization
  • Google Analytics and Search Console tokens are resolved per-user
  • Audit logs record the specific agent or user triggering each SEO analysis

Practical Implementation Examples

Handling Incoming Requests (Cloudflare Workers)

For hosted deployments, the Cloudflare Workers entry point forwards validated requests to the MCP transport layer:

// Cloudflare Workers entry point
export async function onRequest(request, env, ctx) {
  // `props` comes from the Cloudflare Access token validation step
  return handleAuthenticatedOpenSeoMcpRequest(request, props, env, ctx);
}

Implemented in [src/server/mcp/transport.ts](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts#L45-L58).

Client-Side JSON-RPC Integration

External applications interact with the MCP server via standard HTTP POST requests to /mcp:

fetch('https://app.openseo.so/mcp', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    // Include a valid Bearer token that contains the MCP scope
    Authorization: `Bearer ${MCP_ACCESS_TOKEN}`,
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    method: 'list_saved_keywords',
    params: { projectId: 'proj_123' },
    id: 1,
  }),
})
  .then(r => r.json())
  .then(console.log);

The request hits the handler built by createRequestHandler, which validates CORS, verifies the OAuth scope, and routes the call to the registered tool implementation in src/server/mcp/tools/.

Key Source Files and Their Roles

File Responsibility
src/server/mcp/server.ts Defines the McpServer factory, registers all SEO tools via registerOpenSeoTool, and configures service metadata.
src/server/mcp/transport.ts Implements the /mcp HTTP endpoint, CORS handling, legacy JSON fallback, and authentication scope enforcement for both hosted and self-hosted modes.
src/server/mcp/context.ts Declares the authentication context shape and builds the ToolContext injected into every tool handler.
src/server/mcp/oauth-provider.ts Declares the MCP_SCOPE constant and utilities for OAuth token validation.
src/server/mcp/tools/* Individual tool implementations including keyword research, SERP retrieval, backlink analysis, GA4 integration, and site audit functionality.
src/server/mcp/public-origin.ts Derives the public base URL for self-hosted deployments to ensure generated links in tool responses are correct.

Summary

  • The OpenSEO MCP server acts as a protocol gateway, exposing internal SEO tools through a standardized JSON-RPC interface at /mcp.
  • Authentication is mandatory via the MCP_SCOPE OAuth claim, with separate flows for hosted (Cloudflare Access) and self-hosted deployments.
  • Tool registration in src/server/mcp/server.ts normalizes Zod schemas and instruments handlers with logging and context injection.
  • The transport layer supports both modern Streamable HTTP and legacy JSON-RPC clients while enforcing strict CORS policies.
  • All SEO business logic resides in src/server/mcp/tools/*, keeping the core server implementation focused solely on protocol compliance and request routing.

Frequently Asked Questions

What does MCP stand for in OpenSEO?

MCP stands for Model Context Protocol, an open standard for exposing capabilities to AI systems. In OpenSEO, it refers to the specific implementation that allows AI agents to invoke SEO research functions through structured JSON-RPC calls rather than direct database or API access.

How does the OpenSEO MCP server handle authentication?

The server requires every request to include a valid OAuth token containing the MCP_SCOPE. In hosted environments, this is verified through Cloudflare Access tokens, while self-hosted installations can use Cloudflare Access or local no-auth flows that synthesize the required auth context. Requests lacking this scope receive a 403 Forbidden response.

Can I use the MCP server with self-hosted OpenSEO?

Yes. The transport layer in src/server/mcp/transport.ts distinguishes between hosted and self-hosted modes. Self-hosted deployments derive the public origin from the incoming request and resolve user identity through alternative authentication methods, bypassing the hosted OAuth flow while maintaining the same MCP auth context structure.

What SEO tools are exposed through the MCP API?

The server exposes tools for keyword research (saved keywords, SERP analysis), backlink profiling, rank tracking, Google Analytics 4 metrics, Google Search Console data, and technical site audits. Each tool is registered in src/server/mcp/server.ts with strict input/output schemas defined in the corresponding files under src/server/mcp/tools/.

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 →