# What Is the Server Architecture of OpenSEO? A Deep Dive into the Cloudflare Workers Stack

> Discover OpenSEO's server architecture. Learn how Cloudflare Workers, Durable Objects, and MCP API power this edge-based SEO platform for superior performance and scalability.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: architecture
- Published: 2026-08-05

---

**OpenSEO runs as a Cloudflare Workers-based service that combines edge computing, Durable Objects, Workflows, and a type-safe MCP API to deliver a full-stack SEO platform.**

The `every-app/open-seo` repository implements a modern edge-native architecture designed for low-latency API responses and AI-agent integration. Understanding the server architecture of OpenSEO reveals how it balances stateless request handling with durable background processing while maintaining flexibility between SQLite and PostgreSQL backends.

## Edge Worker Entry Point and Request Routing

All HTTP traffic flows through a single Cloudflare Worker defined in [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts). The `fetch` handler serves as the central dispatcher, scoping a per-request PostgreSQL client (or a no-op when using D1) before delegating to the appropriate subsystem.

The entry point uses `withPgClient` to ensure database connections are properly managed across the request lifecycle:

```typescript
import { createStartHandler, defaultStreamHandler } from "@tanstack/react-start/server";
import { withPgClient } from "@/db";

const appFetch = createStartHandler(defaultStreamHandler);

export function fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
  // Give every request a scoped PG client (noop for D1)
  return withPgClient(() => {
    const url = new URL(request.url);
    if (url.pathname.startsWith("/agents/")) {
      // Forward to chat Durable Objects
      return routeChatAgents(request, env);
    }
    // UI / API routes
    return appFetch(request);
  });
}

```

*Source:* [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) defines this routing logic in the `fetch` function.

## Server-Side Rendering and Authentication

**TanStack React Start** powers the UI rendering layer. The Worker creates a start handler via `createStartHandler` that serves the React application while providing server-functions for API endpoints.

Authentication supports three distinct modes determined by the `getAuthMode` utility:

- **Hosted OAuth**: Full OAuth 2.0 flow for managed deployments
- **Cloudflare Access**: Enterprise identity provider integration
- **No-auth local mode**: Development and simple self-hosting

The `isHostedAuthMode` check in [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) wraps OAuth handling around the application when running in hosted mode, ensuring secure access control without impacting local development workflows.

## AI Integration via Model Context Protocol (MCP)

OpenSEO exposes a **type-safe RPC surface** through an MCP (Model Context Protocol) server, enabling AI agents like Claude Code and OpenClaw to interact directly with SEO data.

Tool registration happens explicitly in [`src/server/mcp/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts), where each tool (e.g., `getDomainOverview`, `runSiteAudit`) is registered with Zod schemas for input validation:

```typescript
import { registerOpenSeoMcpTools } from "@/server/mcp/server";

export async function handleSelfHostedOpenSeoMcpRequest(
  request: Request,
  authMode: AuthMode,
  env: Env,
  ctx: ExecutionContext,
) {
  const server = new McpServer({ request, env, authMode });
  registerOpenSeoMcpTools(server);
  return server.handleRequest();
}

```

Individual tool implementations reside in `src/server/mcp/tools/`, calling into repository classes like `ProjectRepository` and `AuditRepository` that abstract database interactions.

## Stateful Components: Durable Objects and Workflows

### Chat Agents via Durable Objects

Two **Cloudflare Durable Objects** host long-lived chat sessions with persistent state stored in internal SQLite databases:

- `OnboardingChatAgent`: Handles setup wizard conversations
- `SamChatAgent`: Powers the in-app AI assistant

These are configured in `wrangler.jsonc`:

```json
{
  "name": "open-seo",
  "durable_objects": {
    "bindings": [
      { "name": "ONBOARDING_CHAT", "class_name": "OnboardingChatAgent" },
      { "name": "SAM_CHAT",         "class_name": "SamChatAgent" }
    ]
  }
}

```

### Background Processing with Workflows

**Cloudflare Workflows** manage long-running background tasks that must survive intermittent failures. The `SiteAuditWorkflow` and `RankCheckWorkflow` classes extend `WorkflowEntrypoint` and use a `pgStep` helper to make PostgreSQL actions durable.

The `SiteAuditWorkflow` implementation includes error handling and PostHog telemetry:

```typescript
// From src/server/workflows/SiteAuditWorkflow.ts
export class SiteAuditWorkflow extends WorkflowEntrypoint<Env, Params> {
  async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
    await step.do("audit-step", async () => {
      // Durable step execution with automatic retry
      return await this.performAudit(event.payload);
    });
  }
}

```

These workflows are scheduled via Cron Triggers defined in `wrangler.jsonc`, ensuring reliable execution of site-audit crawling and rank-check scheduling regardless of transient network issues.

## Database Abstraction and Storage Options

OpenSEO implements a flexible **database layer** that supports both serverless and traditional deployment models. By default, the application uses **Cloudflare D1** (SQLite), but production-scale workloads can switch to **PostgreSQL via Hyperdrive**.

The abstraction lives in [`src/db/provider.ts`](https://github.com/every-app/open-seo/blob/main/src/db/provider.ts), which exports `withPgClient` for connection management. This wrapper is imported throughout the codebase—from MCP tools to Workflow steps—allowing seamless switching between storage backends without modifying business logic.

Environment variables (`DATABASE_PROVIDER`, `AUTH_MODE`) determine the runtime configuration, enabling the same source tree to power both simple Docker containers and full Cloudflare deployments with R2 and KV storage.

## Observability and Deployment Architecture

**PostHog** event capture and Cloudflare Observability (traces) provide full visibility into user actions and background processing. The `wrangler.jsonc` enables tracing configurations that correlate requests across Workers, Durable Objects, and Workflows.

Self-hosting supports two primary strategies:
1. **Docker container**: Runs the same Worker code locally for development
2. **Full Cloudflare deployment**: Leverages Hyperdrive, R2, and KV for production scale

Both paths share identical source code, differentiated only by environment configuration.

## Summary

- OpenSEO's server architecture centers on a Cloudflare Worker entry point ([`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts)) that routes traffic between UI rendering, MCP APIs, and Durable Objects.
- **TanStack React Start** handles server-side rendering while supporting three authentication modes via `getAuthMode`.
- The **MCP server** exposes type-safe tools in [`src/server/mcp/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts), enabling AI agents to read and write SEO data through Zod-validated schemas.
- **Durable Objects** (`OnboardingChatAgent`, `SamChatAgent`) maintain stateful chat sessions, while **Cloudflare Workflows** (`SiteAuditWorkflow`, `RankCheckWorkflow`) execute durable background jobs with `pgStep` guarantees.
- A database abstraction layer in [`src/db/provider.ts`](https://github.com/every-app/open-seo/blob/main/src/db/provider.ts) supports both Cloudflare D1 and PostgreSQL via Hyperdrive, configurable through environment variables.
- Built-in **PostHog** telemetry and Cloudflare Observability provide production monitoring across all components.

## Frequently Asked Questions

### How does OpenSEO handle database connections in a serverless environment?

OpenSEO uses the `withPgClient` wrapper from [`src/db/provider.ts`](https://github.com/every-app/open-seo/blob/main/src/db/provider.ts) to scope PostgreSQL connections per request. When running on D1, this becomes a no-op, but for Hyperdrive deployments, it ensures proper connection pooling and cleanup within the Cloudflare Worker execution context.

### What is the difference between Durable Objects and Workflows in OpenSEO?

**Durable Objects** (defined in `wrangler.jsonc`) maintain long-lived state for chat sessions using internal SQLite storage, while **Workflows** (like [`SiteAuditWorkflow.ts`](https://github.com/every-app/open-seo/blob/main/SiteAuditWorkflow.ts)) execute durable background jobs with automatic retry logic. Durable Objects respond to HTTP requests, whereas Workflows are triggered by Cron Triggers or programmatic events.

### Can OpenSEO run without Cloudflare?

Yes. While optimized for Cloudflare Workers, OpenSEO supports Docker-based self-hosting using the same [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) entry point. Set `DATABASE_PROVIDER` to use local PostgreSQL and `AUTH_MODE` to local/no-auth for standalone deployment.

### How do AI agents communicate with OpenSEO?

AI agents connect through the **Model Context Protocol (MCP)** endpoint exposed at `/mcp`. The server in [`src/server/mcp/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts) registers tools with explicit Zod schemas, allowing agents to call functions like `getDomainOverview` or `runSiteAudit` with type-safe parameters and receive structured JSON responses.