How the MCP Server Works in Open-SEO: Architecture and Implementation Guide
The Open-SEO MCP server is a Model-Context-Protocol implementation built on the Agents SDK that exposes SEO-focused tools to AI agents through a layered architecture involving tool definitions, authentication context, and HTTP transport handling.
The every-app/open-seo repository implements a standards-compliant MCP server that transforms SEO research capabilities into callable tools for AI agents. Built on the @modelcontextprotocol/server SDK, this server handles keyword research, SERP analysis, backlink tracking, and Google Search Console integration through a secure, extensible protocol layer.
Architecture Overview
The Open-SEO MCP server follows a five-layer architecture that separates concerns between tool definitions, registration, authentication, transport, and request handling.
Tool Definitions Layer — Located in src/server/mcp/tools/*, each tool (such as getDomainOverviewTool and searchLocalBusinessesTool) declares a Zod input schema and a handler returning CallToolResult.
Tool Registration Layer — The createOpenSeoMcpServer function in src/server/mcp/server.ts (lines 28-55, 99-102) instantiates an McpServer, then iterates over tool definitions to register each via registerOpenSeoTool, normalizing schemas and wrapping handlers with instrumentation.
Authentication & Context Layer — MCP requests carry an openSeoAuth payload containing user, organization, scopes, and base URL. The createMcpToolContext function in src/server/mcp/context.ts (lines 63-86) merges this with Cloudflare authInfo to produce a ToolContext passed to tools.
Transport & Routing Layer — src/server/mcp/transport.ts provides the HTTP entry point, validating CORS, handling legacy JSON-RPC requests, and forwarding modern requests to createMcpHandler. It enforces the MCP_SCOPE requirement.
Request Handling Layer — Two entry functions handle different deployment modes: handleAuthenticatedOpenSeoMcpRequest for hosted workers and handleSelfHostedOpenSeoMcpRequest for self-hosted flows.
Request Flow Step-by-Step
-
Incoming Request — Cloudflare Workers route requests to
/mcp. -
Authentication Verification —
handleAuthenticatedOpenSeoMcpRequestparses OAuth-derived props usinghostedWorkersOAuthMcpPropsSchema. If the payload lacksMCP_SCOPE, the server returns 403 Forbidden. -
Handler Creation —
createRequestHandlerbuilds a moderncreateMcpHandler(SDK) while preparing legacy validation throughvalidateLegacyRequest. -
CORS Handling — Static
MCP_CORS_HEADERSconstants (mirroring Agents SDK defaults) handle OPTIONS preflight and response headers. -
Tool Invocation — The SDK deserializes the JSON-RPC payload, looks up the registered tool, validates input against its Zod schema, and calls the wrapped handler.
-
Context Enrichment —
createMcpToolContextinjects merged auth information (clientId,scopes) intoToolContext. Tools access user-specific resources through helpers likebuildBillingCustomerandbuildProjectMeta. -
Response Marshaling — Results flow back through
WebStandardStreamableHTTPServerTransportwith CORS headers attached.
Core Implementation Files
Server Initialization (src/server/mcp/server.ts)
The server instantiation happens in createOpenSeoMcpServer, which configures the MCP server metadata and registers all available SEO tools:
// src/server/mcp/server.ts
export function createOpenSeoMcpServer(authProps: McpProps) {
const server = new McpServer({
name: "OpenSEO MCP",
title: "OpenSEO",
version: "0.0.12",
description:
"SEO research tools for AI agents …",
websiteUrl: "https://openseo.so",
icons: [{ src: "https://openseo.so/android-chrome-512x512.png", mimeType: "image/png", sizes: ["512x512"] }],
}, {
instructions:
"OpenSEO research tools use credits …",
});
const register = <I extends ToolSchema>(tool: OpenSeoToolDefinition<I>) =>
registerOpenSeoTool(server, tool, authProps);
// Example registrations
register(whoamiTool);
register(listProjectsTool);
register(getDomainOverviewTool);
// … many more …
return server;
}
Transport and Authentication (src/server/mcp/transport.ts)
The transport layer exports two key functions for handling authenticated requests. The hosted workers flow validates OAuth props and enforces scope requirements:
// src/server/mcp/transport.ts
export async function handleAuthenticatedOpenSeoMcpRequest(
request: Request,
props: unknown,
env: unknown,
ctx: ExecutionContext,
) {
const result = hostedWorkersOAuthMcpPropsSchema.safeParse(props);
if (!result.success) return new Response("MCP auth context required", { status: 403 });
if (!result.data[MCP_AUTH_CONTEXT_PROP].scopes.includes(MCP_SCOPE))
return new Response("MCP scope required", { status: 403 });
return createRequestHandler(result.data, [new URL(getHostedBaseUrl()).hostname])(
request, env, ctx);
}
Context Building (src/server/mcp/context.ts)
Tool context creation merges authentication payloads to provide secure access to organizational data. The createMcpToolContext function handles the intersection of openSeoAuth and Cloudflare's authInfo, producing a context object that tools use to resolve billing and project metadata.
Legacy Support and CORS
The transport layer maintains backward compatibility with older MCP clients through legacy JSON-RPC handling while supporting modern streaming transport.
Legacy Request Handling — The system accepts legacy JSON-RPC requests for compatibility:
// src/server/mcp/transport.ts
async function handleLegacyJsonRequest(request: Request, props: McpProps) {
if (request.method !== "POST") {
return withMcpCors(Response.json({ jsonrpc: "2.0", error: { code: -32000, message: "Method not allowed." }, id: null }, { status: 405 }));
}
const server = createOpenSeoMcpServer(props);
const transport = new WebStandardStreamableHTTPServerTransport({ enableJsonResponse: true });
await server.connect(transport);
return withMcpCors(await transport.handleRequest(request));
}
CORS Configuration — Static MCP_CORS_HEADERS constants defined in src/server/mcp/transport.ts (lines 24-33) mirror the Agents SDK defaults and apply to all responses.
Tool Registration Pattern
Tools follow a consistent definition pattern using Zod for input validation. Each tool in src/server/mcp/tools/* exports a definition object containing:
- Input Schema — Zod validation schema for parameters
- Handler Function — Async function receiving validated input and
ToolContext - Output Schema — Structure for
CallToolResult
The registerOpenSeoTool wrapper instruments each handler with logging and error handling before attaching it to the MCP server instance.
Summary
- The Open-SEO MCP server uses the Agents SDK to expose SEO tools via the Model-Context-Protocol standard.
- Authentication relies on OAuth-derived scopes (
MCP_SCOPE) enforced in the transport layer (src/server/mcp/transport.ts). - Tool registration occurs in
createOpenSeoMcpServer(src/server/mcp/server.ts), which normalizes Zod schemas and wraps handlers. - Context enrichment through
createMcpToolContextprovides tools with access to billing and project metadata. - Legacy compatibility is maintained through JSON-RPC handling while modern requests use streaming HTTP transport.
- All components reside in
src/server/mcp/, with individual tools organized undersrc/server/mcp/tools/.
Frequently Asked Questions
What is the Model-Context-Protocol (MCP) in Open-SEO?
The Model-Context-Protocol is a standardized protocol that allows AI agents to discover and invoke external tools. In Open-SEO, the MCP server exposes SEO research capabilities—such as keyword analysis and backlink profiling—as callable functions that AI models can execute with proper authentication.
How does authentication work for the Open-SEO MCP server?
Authentication uses OAuth-derived properties passed via the openSeoAuth payload. The handleAuthenticatedOpenSeoMcpRequest function validates these properties against hostedWorkersOAuthMcpPropsSchema and verifies the MCP_SCOPE is present in the user's scopes. Without this scope, the server returns a 403 Forbidden response.
Can I self-host the Open-SEO MCP server?
Yes. The repository provides handleSelfHostedOpenSeoMcpRequest (src/server/mcp/transport.ts lines 145-187) as an alternative entry point for self-hosted deployments. This function handles authentication for non-Cloudflare hosted environments while maintaining the same tool registration and context enrichment logic.
How are tools added to the MCP server?
Tools are added by defining them in src/server/mcp/tools/ with Zod input schemas, then registering them in createOpenSeoMcpServer using the register helper function. This pattern ensures type safety through Zod validation and consistent instrumentation across all SEO 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →