# What is OpenSEO? An Open-Source, Pay-As-You-Go SEO Platform

> Discover OpenSEO, an open-source, pay-as-you-go SEO platform. Gain control with commercial-grade features and flexible pricing instead of subscriptions. Explore the every-app/open-seo repository.

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

---

**OpenSEO is an open-source SEO platform that provides commercial-grade features like rank tracking and site audits through a Cloudflare Workers-based architecture, offering full code control and pay-per-use pricing instead of subscriptions.**

OpenSEO is an open-source alternative to premium SEO tools like Semrush and Ahrefs, developed by the `every-app/open-seo` repository. Built on a modern TypeScript stack with TanStack React Start, it enables developers to self-host their SEO infrastructure while only paying for the DataForSEO API calls they consume.

## Core Architecture

### Cloudflare Workers Entry Point

The application boots from [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts), which configures the Cloudflare Workers fetch handler. This file routes `/agents/*` paths to durable-object chat agents, handles OAuth authentication via [`src/server/mcp/oauth-provider.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-provider.ts), manages self-hosted MCP endpoints, and executes scheduled cron jobs including the `MCP_OAUTH_PURGE_CRON` for cleaning expired tokens.

### Dual-Dialect Database Layer

OpenSEO uses a unified schema defined in [`src/db/schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/schema.ts) that maintains parity between **SQLite/D1** (for free tier) and **Postgres** (for production) implementations. The runtime selects the appropriate dialect via `getDatabaseProvider()`, allowing the same repository code to work against both backends through Drizzle ORM without modification.

### MCP Protocol for AI Agents

The **Multi-Client Protocol (MCP)** exposed in `src/server/mcp/*` allows AI agents like Claude Code and Hermes to interact directly with your SEO data. This server-side API validates callers, applies rate limits, and executes workflows such as rank checking and site audits, requiring only an OpenRouter API key for AI functionality.

### Authentication Modes

OpenSEO supports multiple authentication strategies depending on your hosting choice. Hosted deployments use OAuth and Cloudflare Access handled in `src/lib/auth-*.ts`, while Docker self-hosting utilizes `local_noauth` mode set via the `AUTH_MODE` environment variable as documented in [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md).

### Type-Safe Server Functions

API endpoints are built using `createServerFn` from `@tanstack/react-start`, located in `src/serverFunctions/*`. These functions provide validated, type-safe access to SEO data like search performance reports and ranking metrics.

## How OpenSEO Works

### Request Handling Pipeline

When a request hits the Worker, [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) scopes a per-request Postgres client via `withPgClient` and delegates to `handleFetch`. Static UI requests route through `appFetch`, while agent requests dispatch to durable objects via `routeChatAgents` using authorization checks from `authorizeChatAgent`.

### MCP Workflow Execution

AI agents invoke endpoints under `/mcp`, processed by `handleSelfHostedOpenSeoMcpRequest`. This layer validates the caller identity, enforces rate limits, and executes the requested workflow against your SEO data.

### Data Access Pattern

Server functions retrieve data through typed repositories importing from the unified [`schema.ts`](https://github.com/every-app/open-seo/blob/main/schema.ts). Whether running against SQLite/D1 or Postgres, the same repository logic applies, ensuring consistent behavior across hosting tiers.

### Scheduled Background Jobs

A nightly cron job (`MCP_OAUTH_PURGE_CRON`) cleans expired OAuth tokens as defined in the server entry point, while additional scheduled handlers reconcile stale audits and trigger rank-tracking updates.

## Self-Hosting Deployments

### Docker Local Development

For local development, OpenSEO runs in Docker with `AUTH_MODE=local_noauth`, bypassing OAuth requirements. Telemetry sends anonymized heartbeats every five minutes for the first two hours, then daily, but can be disabled by setting `OPENSEO_TELEMETRY_DISABLED=1` according to [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md).

### Cloudflare Production Hosting

The recommended production deployment uses Cloudflare Workers with the free Cloudflare plan. This configuration leverages D1 for the database tier and Cloudflare Access for authentication, sharing the same codebase as the Docker deployment.

## Practical Code Examples

### Creating a Server Function

The following pattern from [`src/serverFunctions/searchPerformance.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/searchPerformance.ts) demonstrates how to build type-safe endpoints:

```typescript
export const getSearchPerformanceReport = createServerFn({ method: "POST" })
  .middleware(requireProjectContext)
  .validator(searchPerformanceInputSchema)
  .handler(async ({ data, context }) => {
    const { startDate, endDate } = resolveDateRange({ dateRange: data.dateRange });
    const { deviceFilters, filters } = buildGscFilters(data);
    const [current, previous] = await Promise.all([
      GscService.getPerformance({ projectId: context.projectId, startDate, endDate, dimensions: ["date"], filters, rowLimit: 200 }),
      GscService.getPerformance({ projectId: context.projectId, startDate: prev.startDate, endDate: prev.endDate, dimensions: ["date"], filters, rowLimit: 200 })
    ]);
    return { /* …computed totals… */ };
  });

```

### Routing Agent Chat Durable Objects

Handle AI agent connections through durable objects as implemented in [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts):

```typescript
async function routeChatAgents(request: Request, env: Env): Promise<Response> {
  const response = await routeAgentRequest(request, env, {
    onBeforeConnect: (req, lobby) => authorizeChatAgent(req, lobby),
    onBeforeRequest: (req, lobby) => authorizeChatAgent(req, lobby),
  });
  return response ?? new Response("Not found", { status: 404 });
}

```

### Switching Database Providers

The runtime database selection in [`src/db/schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/schema.ts) enables dual-dialect support:

```typescript
const runtimeSchema = getDatabaseProvider() === "postgres"
  ? { ...pgApp, ...pgProjectContext, /* … */ }
  : { ...sqliteApp, ...sqliteProjectContext, /* … */ };
export const { projects, audits, user, ... } = runtimeSchema as AppSchema;

```

## Summary

- **OpenSEO** provides commercial-grade SEO tools through an open-source, pay-as-you-go model hosted on Cloudflare Workers or Docker.
- The architecture centers on [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) for request routing, a dual-dialect database layer in [`src/db/schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/schema.ts), and AI agent integration via the MCP protocol.
- **TanStack React Start** powers type-safe server functions, while the unified schema ensures compatibility between SQLite/D1 and Postgres backends.
- Self-hosting options range from local Docker development with `local_noauth` mode to production Cloudflare deployments with OAuth and D1.
- Built-in telemetry can be completely disabled, and the MCP layer enables AI agents to execute SEO workflows directly against your data.

## Frequently Asked Questions

### What technology stack does OpenSEO use?

OpenSEO is built on TypeScript using **TanStack React Start** for the frontend and API layer, **Drizzle ORM** for database management, and **Cloudflare Workers** for the runtime environment. It supports both SQLite/D1 and PostgreSQL databases through a unified schema abstraction in [`src/db/schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/schema.ts), and integrates with AI services via OpenRouter API keys.

### How does OpenSEO pricing work?

Unlike subscription-based SEO tools, OpenSEO operates on a **pay-as-you-go** model where you only pay for the DataForSEO API calls you consume. The platform itself is free and open-source, allowing you to self-host without licensing fees. You control costs by managing your own API usage and infrastructure on Cloudflare's free tier or your own Docker servers.

### Can I disable telemetry and use OpenSEO offline?

Yes. While OpenSEO sends anonymized usage heartbeats every five minutes initially (then daily), you can completely disable telemetry by setting the environment variable `OPENSEO_TELEMETRY_DISABLED=1`. For offline or fully private deployments, use the **Docker self-hosting** option with `AUTH_MODE=local_noauth`, which requires no external authentication providers.

### What is the MCP protocol in OpenSEO?

The **Multi-Client Protocol (MCP)** is an extensible server-side API exposed in `src/server/mcp/*` that allows AI agents like Claude Code and Hermes to programmatically interact with your SEO data. MCP endpoints handle authentication, rate limiting, and workflow execution through `handleSelfHostedOpenSeoMcpRequest`, enabling autonomous agents to perform rank checks, run audits, and analyze search performance without manual intervention.