Skip to main content
Glama

OLTestStack — AI Browser Testing Framework

openlearnia

MCP server that exposes high-level browser automation tools for AI agents. Internally drives Chromium via Puppeteer/CDP; externally presents flat, stateless MCP command payloads.

git clone https://github.com/openlearnia/OLTestStack.git
cd OLTestStack

Requirements

  • Bun 1.0+ (or Node.js 20+)

  • Chromium (bundled with Puppeteer, or set CHROMIUM_EXECUTABLE_PATH)

  • Docker (optional, for PostgreSQL persistence)

Related MCP server: BrowserGenie MCP Server

Ports

Service

Host port

Container port

Notes

PostgreSQL

5433

5432

Non-default; avoids local Postgres conflicts

App health HTTP (Docker)

8091

8081

APP_HOST_PORTHEALTH_PORT; dashboard at /dashboard

MCP HTTP (Docker)

8092

8082

MCP_HOST_PORTMCP_HTTP_PORT; local dev:http uses 8082

Local MCP uses stdio by default (no TCP port). bun run dev:http listens on 8081 / 8082 on the host (dashboard at http://localhost:8081/dashboard).

Quick start (local MCP)

bun install
bun run typecheck
bun run dev

Docker + PostgreSQL quickstart

Persistence is optional. Active browser/page sessions stay in-memory for speed; recordings and test reports flush to Postgres on browser close when enabled.

# 1. Start Postgres (host port 5433)
cp .env.example .env
bun run docker:up

# 2. Apply migrations
bun run db:migrate

# 3. Enable persistence and start MCP server
export DATABASE_URL=postgresql://oltest:oltest@localhost:5433/olteststack
bun run dev

Sessions persist automatically when DATABASE_URL is set. Unsaved sessions expire after SESSION_TTL_HOURS (default 24h); call save_session or use the dashboard to keep them.

Stop infrastructure:

bun run docker:down

Optional: run the app container (health on host 8091, MCP on 8092). Run migrations first, then start the full stack:

docker compose run --rm migrate
bun run docker:app
curl http://localhost:8091/health
open http://localhost:8091/dashboard

If the app container restarts in a loop with column "saved" does not exist, apply pending migrations to the existing Postgres volume:

docker compose run --rm migrate
docker compose up -d --build

Override host ports in .env via APP_HOST_PORT and MCP_HOST_PORT if 8091/8092 are taken.

Run migrations inside Docker:

docker compose run --rm migrate

Production warning: Default credentials in .env.example (oltest/oltest) are for local development only. Change POSTGRES_USER, POSTGRES_PASSWORD, and DATABASE_URL before deploying.

Run the MCP server

bun run dev

Or after building:

bun run build
bun run start

The server communicates over stdio — do not pipe logs to stdout (stderr only for diagnostics).

When DATABASE_URL is set, the server validates the connection at startup and writes reports/events to PostgreSQL on browser_close unless PERSIST_RECORDING=false. Ephemeral sessions auto-delete after SESSION_TTL_HOURS unless promoted via save_session.

Cursor MCP configuration

Add to your Cursor MCP settings (.cursor/mcp.json or Cursor Settings → MCP):

{
  "mcpServers": {
    "olteststack": {
      "command": "bun",
      "args": ["run", "dev"],
      "cwd": "/Users/kartikbazzad/OLTestStack",
      "env": {
        "PERSIST_RECORDING": "false"
      }
    }
  }
}

Replace cwd with the absolute path to this project on your machine. Set DATABASE_URL for Postgres persistence (default on when set). Use PERSIST_RECORDING=false to disable writes.

Available tools (V1.3 — 35)

Category

Tools

Browser

browser_launch, browser_close

Page

page_create, page_navigate, page_reload, page_close

Elements

page_elements, page_find

Actions

page_click, page_click_query, page_type, page_type_query, page_select, page_upload, page_press, page_scroll

Inspection

page_screenshot, page_snapshot, page_text, page_html

Monitoring

page_network, page_console

Waiting

page_wait

Assertions

assert_exists, assert_text, assert_url, assert_network

Session

session_status, session_get, session_list, session_export, save_session, script_lint, test_run

Debug

send_report

Example flow

browser_launch  →  page_create  →  page_navigate  →  page_find  →  page_type  →  page_click  →  page_wait  →  page_screenshot  →  browser_close

Environment variables

Variable

Default

Description

BROWSER_HEADLESS

true

Default headless mode

CHROMIUM_EXECUTABLE_PATH

auto

Custom Chromium binary

DEFAULT_TIMEOUT_MS

30000

General operation timeout

DEFAULT_NAVIGATION_TIMEOUT_MS

30000

Navigation/reload timeout

SCREENSHOT_DIR

./screenshots

Screenshot output directory

UPLOAD_DIR

./uploads

Allowed server-local paths for page_upload

DATABASE_URL

PostgreSQL connection string (localhost:5433 in dev)

PERSIST_RECORDING

true when DATABASE_URL set

Set false to opt out of persisting reports

SESSION_TTL_HOURS

24

Hours until unsaved sessions are auto-deleted

DB_PORT

5433

Documented default host port for local Docker Postgres

HEALTH_PORT

App listen port for health + dashboard (8081; container side in Docker)

DASHBOARD_ENABLED

true when HEALTH_PORT or HTTP MCP

Session dashboard at /dashboard

APP_HOST_PORT

8091

Docker host port mapped to HEALTH_PORT

MCP_HTTP_PORT

8082

App listen port for MCP HTTP

MCP_HOST_PORT

8092

Docker host port mapped to MCP_HTTP_PORT

POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB

oltest / oltest / olteststack

Docker Compose Postgres credentials

Project structure

src/
├── core/          # Types, errors, registry, config, recording
├── cdp/           # Puppeteer CDP adapter
├── db/            # Drizzle schema, migrations runner, persistence
├── dashboard/     # Session dashboard UI + REST API
├── domain/        # Business logic (browser, page, elements)
├── health/        # Optional HTTP health endpoint
└── mcp/           # MCP server, tool registration

Scripts

Script

Description

bun run dev:http

Start MCP server (HTTP) + dashboard on 8081

bun run dashboard

Dashboard + health only (no MCP) on 8081

bun run dev

Start MCP server (stdio)

bun run build

Compile TypeScript to dist/

bun run typecheck

Type-check without emit

bun run test

Run tests

bun run smoke

End-to-end MCP smoke test (HTTP transport)

bun run test:mcp

Full MCP tool-flow test via SDK client (no curl)

bun run test:mcp:docker

Same as test:mcp against Docker on port 8092

bun run docker:up

Start Postgres via Docker Compose

bun run docker:app

Build and start MCP app container (HTTP on host 8091/8092)

bun run docker:down

Stop Docker Compose services

bun run db:migrate

Apply Drizzle SQL migrations

bun run db:generate

Generate migrations from schema

bun run db:studio

Open Drizzle Studio (DB GUI)

Documentation

Agent-focused guides for MCP setup, tool reference, workflows, and Cursor skills:

Cursor setup: project skills (.cursor/skills/) and subagents (.cursor/agents/) ship with the repo; OLTestStack rules live at user level (~/.cursor/rules/olteststack-mcp-usage.mdc, olteststack-typescript.mdc) — see Guides index.

Smoke test

Verify MCP connectivity and core browser flow:

bun run smoke          # quick: launch → navigate → elements → close
bun run test:mcp       # full tool flow via MCP SDK (no curl)

Uses HTTP transport (spawns a local server if none is running). Set CHROMIUM_EXECUTABLE_PATH if Puppeteer's bundled Chromium is unavailable.

What's next

V1 is feature-complete (26 MCP tools, dashboard, session TTL, script export/playback). CI runs on push/PR via .github/workflows/ci.yml. Remaining: push uncommitted work to GitHub, Docker image publish, and V1.2 enhancements (query capture at record time, variable substitution). See docs/plans/v1-implementation-plan.md and docs/plans/session-script-playback.md.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers