THESIS docs
v1.1.0
Live demo Get help
● Ship · Hosting

Deployment
Vercel or your own server.

Two supported ways to put THESIS online. Vercel needs Postgres for the admin; your own server can use a local SQLite file. Either way, serve it over HTTPS.

01Vercel

Who pays: you, on your own Vercel account (commercial sites need a paid plan) and your own Postgres provider such as Neon, billed by them above their free tiers; the item price does not include hosting (Costs).

Which terminal

The commands on this page are written for the shell of macOS and Linux (bash or zsh). On Windows, run them in WSL (Windows Subsystem for Linux, Ubuntu) or Git Bash: commands such as cp, openssl, set -a && . ./.env and multi-line curl with \ do not work as written in PowerShell or cmd. The node and pnpm commands work in any of them.

  1. Import the projectPush the folder to your own Git repository and import it in Vercel. vercel.json already sets the build (pnpm build), output (dist), the /app and /admin rewrites, /api/* and /admin/api/* to the function api/[...path].ts (60 s limit) and the security headers.
  2. Postgres RequiredCreate a Postgres 14+ database (for example Neon from the Vercel marketplace) and set DATABASE_URL to its pooled connection string with sslmode=require. The admin creates its mk_admin_* tables on first use. There is no SQLite on Vercel.
  3. Blob RecommendedStorage → create a private Blob store and connect it; that sets BLOB_READ_WRITE_TOKEN. Without it the aggregate counters live in /tmp and reset on cold starts, and the Status page says so. A public store needs THESIS_BLOB_ACCESS=public.
  4. Environment variablesADMIN_SECRET_KEY (openssl rand -hex 32), ADMIN_SETUP_TOKEN (openssl rand -hex 24, the one-time secret that creates the owner), DATABASE_URL, optionally ANTHROPIC_API_KEY. Set them for every environment you deploy (Production, Preview), then redeploy. Where to click (labels as of October 2026): Vercel dashboard → your project → Settings → Environment Variables → enter Key and Value, tick the environments (Production, Preview) → Save; then Deployments → the latest deployment → Redeploy. Vercel's guide: Vercel docs → Managing environment variables.
  5. Deploy, then create the ownerOpen /admin and enter the value of ADMIN_SETUP_TOKEN with your email and a password, then remove the variable and redeploy. Without the token: open /admin once so a function starts, then open the deployment's Logs (or vercel logs <deployment-url>) and search for setup code. Every cold start before the owner exists prints its own code; any printed code works (next steps).
  6. DomainProject → Settings → Domains. Add your domain and follow the DNS instructions.

Vercel's Hobby plan is for personal, non-commercial use under Vercel's terms; check which plan fits how you run the desk (Costs and services).

Visitor country for blocking live modes comes from Vercel's x-vercel-ip-country header (or cf-ipcountry behind Cloudflare).

02Your own server

Who pays: you, to your server or VPS provider and for your domain; SQLite on the server has no service cost.

  1. Build on the server
    pnpm install
    pnpm build
  2. SettingsCreate .env (how). Without DATABASE_URL the admin uses SQLite in THESIS_DATA_DIR; back that folder up.
  3. Keep it runningUse a process manager. The command it should run, from the project folder:
    node dist-server/server/node.js
    The process manager must supply the variables from .env: with systemd, EnvironmentFile=/path/to/thesis/.env and ExecStart=/usr/bin/env node dist-server/server/node.js with WorkingDirectory=/path/to/thesis; pm2, pm2 start dist-server/server/node.js --name thesis; by hand, set -a && . ./.env && set +a && pnpm start. Run pnpm build again after every update.
  4. HTTPS in frontPut a reverse proxy (Caddy, nginx) in front of port 8787, set THESIS_HOST=127.0.0.1 so only the proxy can reach it, and set THESIS_TRUST_PROXY=1 so rate limits and the Secure cookie see the real client and scheme. THESIS then takes the right-most X-Forwarded-For entry (the one your proxy appends) as the client address and ignores entries further left, which a client could write. If the admin sign-in does not stick, see Troubleshooting → reverse proxy.
No country blocking without a header

On a bare server there is no country header, so nobody is geo-blocked. If you rely on blocked countries, run behind Cloudflare (which adds cf-ipcountry) or on Vercel.

Security headers

vercel.json sets a strict Content-Security-Policy (only Hyperliquid and api.telegram.org may be contacted by the browser), X-Frame-Options: DENY and more. The Node server applies its own policy from server/csp.ts. If you add another service the browser must reach, add it to both.

03Before you open it to users

  • Owner created, ADMIN_SETUP_TOKEN removed from the environment, two-factor on, ADMIN_SECRET_KEY backed up, a database backup tested (Backups).
  • Status page: no blockers.
  • Your own risk notice in Legal; your terms linked from the landing copy if you need them.
  • Blocked countries reviewed; mainnet left off until you have tested on testnet yourself.
  • AI daily cap set to a budget you accept.