Main Modules and Components of the OpenSEO Project: Architecture Guide

OpenSEO is a full-stack SEO platform built on Cloudflare Workers that combines a React-based client UI, an MCP (Model-Context-Protocol) server for AI agents, background workflow processing, and modular feature services for projects, Google Search Console integration, and billing.

OpenSEO is an open-source SEO platform hosted in the every-app/open-seo repository that provides keyword research, rank tracking, and site auditing capabilities. Understanding the main modules and components within the OpenSEO project is essential for developers looking to extend the platform, integrate new data sources, or deploy self-hosted instances. The codebase follows a clean architecture that strictly separates presentation logic, API endpoints, agent interfaces, and asynchronous background processing.

Client UI Layer

The Client UI is a React + Vite application compiled into a Cloudflare Worker static asset. Routes live under src/routes/*.tsx and layout components reside in src/client/layout. The entry point is src/client/layout/AppShell.tsx, which assembles navigation, authentication guards, and the main content view.

This module handles rendering for keyword research, rank tracking, and site audit dashboards. It communicates with the server through /api/* endpoints and provides authentication UI components such as src/routes/_auth.sign-in.tsx and src/routes/_auth.sign-up.tsx.

// src/routes/_authenticated.onboarding.chat.tsx
import { useAuth } from '@/lib/auth';
import Chat from '@/components/Chat';

export default function OnboardingChatPage() {
  const { user } = useAuth(); // redirects to sign-in if not authenticated
  return <Chat userId={user.id} />;
}

Server Entry Point and Routing

The Server Entry Point at src/server.ts exports a Cloudflare Workers handler that bootstraps all API routes, middleware, and the MCP endpoint. It wires together the router and error handling middleware to process incoming requests.

// src/server.ts
import { router } from './router';
import { errorHandling } from './middleware/errorHandling';

export default {
  fetch: errorHandling(async (request, env, ctx) => router.handle(request, env, ctx)),
};

MCP (Model-Context-Protocol) Integration

The MCP module enables AI agents to call OpenSEO functions through a standardized protocol. Located in src/server/mcp/, this component exposes domain operations as tools that Claude, OpenClaw, and other compatible agents can invoke.

  • Transportsrc/server/mcp/transport.ts validates authentication, instantiates an McpServer, and wires requests through createMcpHandler.
  • Contextsrc/server/mcp/context.ts creates an OAuth-aware context for tool execution.
  • Tools – Individual implementations in src/server/mcp/tools/*.ts expose operations like get-domain-overview, list-projects, and search-keywords.
// src/server/mcp/server.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { registerOpenSeoMcpTools } from '@/server/mcp/server';

function createOpenSeoMcpServer() {
  const server = new McpServer({ /* metadata */ });
  registerOpenSeoMcpTools(server);   // adds all tool handlers
  return server;
}

Background Workflow Processing

OpenSEO executes long-running jobs—such as site audit crawls and rank-check updates—using Cloudflare Workflows. These background processes are defined in src/server/workflows/ and orchestrate complex multi-phase operations without blocking API requests.

Both workflows utilize helper functions from src/server/workflows/siteAuditWorkflowPhases.ts and src/server/workflows/site-audit-workflow-helpers.ts.

// src/server/workflows/SiteAuditWorkflow.ts
export class SiteAuditWorkflow extends WorkflowEntrypoint<Env, AuditParams> {
  async run(event, step) {
    const { auditId, startUrl, config } = event.payload;
    // retrieve audit record, then delegate to phases
    await runAuditPhases(step, { auditId, startUrl, config });
  }
}

Domain Feature Services

The Feature Services module in src/server/features/* encapsulates business logic for specific SEO domains. Each feature combines service layers and repositories to enforce data validation and permissions.

Project Management

The Projects service manages user-defined SEO campaigns. ProjectService.ts handles CRUD operations and validation, while ProjectRepository.ts manages low-level database queries.

import { ProjectService } from '@/server/features/projects/services/ProjectService';

await ProjectService.createProject({
  name: 'My Blog',
  domain: 'example.com',
  ownerId: user.id,
});

Google Search Console Integration

The GSC service provides analytics via a DataForSEO wrapper. GscService.ts fetches search-analytics data, caches results, and normalizes the schema for consumption by the UI and MCP tools.

import { GscService } from '@/server/features/gsc/services/GscService';

const analytics = await GscService.getSearchAnalytics({
  projectId,
  startDate: '2024-01-01',
  endDate: '2024-01-31',
});

Onboarding Flow

The Onboarding module guides new users through conversational setup using AI agents. The tools in onboardingChatTools.ts implement chat interactions and pull project suggestions based on user input.

import { sendWelcomeMessage } from '@/server/features/onboarding/onboardingChatTools';

await sendWelcomeMessage(user.id, project.id);

Authentication System

Authentication is split between low-level helpers and route middleware. Core logic resides in src/lib/auth.ts, while src/middleware/ensureUser.ts injects user context into protected routes. The system supports Cloudflare Access, delegated local development, and hosted-only modes, with session handling managed by auth-session.ts and redirects handled by auth-redirect.ts.

import { ensureUser } from '@/middleware/ensureUser';

export const GET = ensureUser(async (request, ctx, user) => {
  return new Response(JSON.stringify({ id: user.id, email: user.email }));
});

Billing and Subscription Management

The Billing module uses the Svix webhook service to synchronize Stripe subscription data. Core logic lives in src/server/billing/subscription.ts, while event handlers in svix.ts verify signatures and update internal subscription states.

import { updateSubscriptionStatus } from '@/server/billing/subscription';

await updateSubscriptionStatus(userId, 'active');

Database Layer

OpenSEO uses Drizzle (a TypeScript-first ORM) with SQLite/D1. Schema definitions are modularized under src/db/, with schema.ts containing the main tables for projects, audits, keywords, backlinks, and billing. Separate files like gsc.schema.ts and billing.schema.ts maintain separation of concerns.

import { db } from '@/db';
import { projects } from '@/db/schema';

const proj = await db.select().from(projects).where(eq(projects.id, 42));

Shared Utilities

The Shared Utilities module in src/shared/ provides isomorphic code reused across client and server boundaries:

  • keyword-locations.ts – Parses and deduplicates keyword positions in SERP results.
  • targetDetection.ts – Detects if a request originates from a browser, worker, or test harness.
  • json.ts – Provides safe JSON parsing with error handling.
import { safeParse } from '@/shared/json';

const result = safeParse('{ "foo": "bar" }');
if (result.success) console.log(result.data.foo);

Build Configuration and Deployment

The Build and Deployment configuration leverages Vite for the React UI (vite.config.ts) and Wrangler for Cloudflare Worker deployment (wrangler.jsonc). D1 database bindings and environment variables are configured in wrangler.jsonc, while Dockerfile.selfhost and compose.yaml enable local Docker deployment.

cp .env.example .env

# set DATAFORSEO_API_KEY in .env

docker compose up -d

Summary

The OpenSEO codebase organizes functionality into ten distinct architectural layers:

  • Client UI – React/Vite frontend in src/client and src/routes with AppShell.tsx as the layout root.
  • Server Entry – Cloudflare Worker bootstrap in src/server.ts combining routing and middleware.
  • MCP Server – AI agent interface in src/server/mcp/ with transport, context, and tool definitions.
  • Workflows – Background job orchestration via SiteAuditWorkflow.ts and RankCheckWorkflow.ts.
  • Feature Services – Domain logic for Projects, GSC, and Onboarding under src/server/features/.
  • Authentication – OAuth and session management spanning src/lib/auth.ts and src/middleware/ensureUser.ts.
  • Billing – Subscription lifecycle management in src/server/billing/subscription.ts.
  • Database – Drizzle ORM schemas in src/db/schema.ts with D1 as the persistence layer.
  • Shared Utilities – Common helpers in src/shared/ for data transformation and environment detection.
  • Build System – Vite and Wrangler configurations supporting both edge deployment and Docker self-hosting.

Frequently Asked Questions

What is the MCP module in OpenSEO and how does it work?

The MCP (Model-Context-Protocol) module in src/server/mcp/ exposes OpenSEO functionality to AI agents like Claude. It consists of a transport layer (transport.ts) that handles authentication and request routing, a context builder (context.ts) that provides OAuth-aware execution environments, and individual tool files in src/server/mcp/tools/ that implement specific operations such as get-domain-overview.ts and list-projects.ts. Agents communicate with these tools through a standardized JSON-RPC interface, allowing them to query SEO data and trigger workflows directly.

How does OpenSEO handle long-running SEO audit tasks?

OpenSEO delegates long-running operations to Cloudflare Workflows defined in src/server/workflows/. The SiteAuditWorkflow.ts entry point extends WorkflowEntrypoint and orchestrates multi-phase crawl and analysis jobs using helper functions from siteAuditWorkflowPhases.ts. These workflows run asynchronously outside the request-response cycle, preventing API timeouts while processing large site audits or batch rank checks.

What database technology does OpenSEO use and where is the schema defined?

OpenSEO uses Drizzle ORM with Cloudflare D1 (SQLite) as its database layer. The schema is defined in src/db/schema.ts, which exports table definitions for projects, audits, keywords, backlinks, and billing records. Modular schema files like gsc.schema.ts and billing.schema.ts keep domain-specific database structures isolated and maintainable.

How does authentication work in the OpenSEO project?

Authentication is implemented through a combination of library functions and middleware. src/lib/auth.ts provides core OAuth flows supporting Cloudflare Access and local development modes, while src/middleware/ensureUser.ts wraps API routes to enforce authentication guards. The system uses signed cookies managed by auth-session.ts to maintain sessions, automatically redirecting unauthenticated requests to the sign-in page at src/routes/_auth.sign-in.tsx.

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 →