Skip to content

Docs / Run it yourself

Self-hosting

Run the OpenSEO app, API and site on your own machine with Postgres.

OpenSEO is open source under the MIT licence. The repository is a pnpm monorepo with the API, the app and this site. You need Node.js 22 or newer, pnpm and a Postgres database.

1. Clone the repository

Terminal
git clone <repository-url> openseo
cd openseo

The public repository link is not published yet. Replace <repository-url> with it once it is.

2. Create your .env file

Terminal
cp .env.example .env

Open .env and set at least these values:

.env
# .env
DATABASE_URL=postgres://localhost:5432/openseo

# 32+ random characters. Signs sessions.
AUTH_SECRET=change-me-to-a-long-random-string

# 32 bytes, base64. Encrypts stored YepAPI keys.
# Generate one with: openssl rand -base64 32
ENCRYPTION_KEY=

The defaults for API_URL, APP_URL and WEB_URL match the ports below, so you can leave them alone for local use.

3. Start Postgres

Point DATABASE_URL at any Postgres database you already run. If you do not have one, the repository includes a docker-compose.yml that starts Postgres on port 5433:

Terminal
docker compose up -d

# Then, in .env:
DATABASE_URL=postgres://openseo:openseo@localhost:5433/openseo

4. Install, migrate and run

Terminal
pnpm install
pnpm db:migrate
pnpm dev

pnpm db:migrate creates the database tables. pnpm dev starts everything:

  • API and MCP server on http://localhost:4100
  • App on http://localhost:3200
  • Marketing site on http://localhost:3101

5. Add your YepAPI key

Open http://localhost:3200, create an account and paste your YepAPI key. A self-hosted install uses YepAPI in the same way as the hosted version: you pay YepAPI per call and nothing else. If you do not have a key yet, create an account at yepapi.com. New accounts get $5 in free API credits.

Develop without a YepAPI key

The repository includes a stand-in for YepAPI that answers every endpoint OpenSEO uses with made-up data in the real shapes. Nothing it returns is real search data, but every screen works and nothing is billed.

Terminal
# Terminal 1: a stand-in for YepAPI with made-up data
pnpm --filter @openseo/api fake-yepapi

# Terminal 2: the API pointed at it; any key starting with yep_sk_ works
YEPAPI_BASE_URL=http://localhost:4199 pnpm dev:api

Run the checks

Terminal
pnpm typecheck
pnpm test

The tests need no database or network. The API's integration tests run the real app against an in-memory Postgres (PGlite) with the real migrations, and against stand-ins for YepAPI and Google, covering sign-in, prices, caching, spending limits, every background run, ownership checks, the Google connection, the free tools' guards and the MCP server.

Running it in production

Terminal
pnpm --filter @openseo/app build && pnpm --filter @openseo/web build
pnpm db:migrate
pnpm --filter @openseo/api start     # API, MCP and the background worker
pnpm --filter @openseo/app start     # dashboard on :3200
pnpm --filter @openseo/web start     # site on :3101
  • Set API_URL, APP_URL and WEB_URL to the public addresses, and NODE_ENV=production. The dashboard forwards /api to API_URL, so sign-in cookies stay on the dashboard's own domain. That address is fixed when the dashboard is built, so set API_URL before build.
  • Keep ENCRYPTION_KEY safe and stable: stored YepAPI keys cannot be read without it.
  • The background worker runs inside the API process by default. To run it separately, start one API process with RUN_WORKER=false for web traffic and another with the default (on a different API_PORT) for jobs; both use the same database.
  • Run pnpm db:migrate after every upgrade, before starting the new version.
  • Leave TRUST_PROXY_HOPS at 0 unless every request reaches the API through proxies you control that overwrite X-Forwarded-For. The dashboard's and site's /api forwarding passes on whatever a visitor sends in that header.

Optional features

Next

Your MCP endpoint is http://localhost:4100/mcp. See Connect an agent over MCP to use it from Claude, Cursor or Codex.