Installation
a production build you can keep.
From the unzipped folder to a production build served by one Node process, with a settings file, the owner account and, if you want it, the AI key. For Vercel, read this page, then Deployment → Vercel.
01Install and check
- Install packages Required
pnpm install - Run the testsAll test files should pass. They cover the engine, the backtest fill model, the lab, the server and the admin mapping.
pnpm test - Build RequiredType-checks, then writes the landing page, the desk and the admin console into
dist/.pnpm build
02Settings file
The server reads its settings from environment variables. Keep them in a .env file next to package.json; it is ignored by git.
cp .env.example .env
openssl rand -hex 32 # paste the answer after ADMIN_SECRET_KEY= in .env
Open .env and fill at least ADMIN_SECRET_KEY. Every variable is explained in Configuration.
It encrypts the secrets the admin stores (for example the Anthropic key) and signs Pro sessions. If you lose it, stored secrets cannot be read and must be entered again. Keep a copy in your password manager, never in git.
03Start the server
One Node process serves the landing page (/), the desk (/app), the admin (/admin) and the API. The start command is pnpm run server. It does not read .env by itself, so load the file into the shell first (macOS and Linux shells):
set -a && . ./.env && set +a # export every line of .env
pnpm run server
The first line of the output confirms the address, where the AI key comes from and where the admin is stored, for example THESIS on http://localhost:8787 · … · SQLite in …/data. Open http://localhost:8787.
pnpm has a built-in command called server that runs instead of the script, so the word run matters. On a server you keep running, let the process manager supply the variables (systemd EnvironmentFile, pm2, Docker --env-file) and start pnpm run server.
04Create the owner
Until an owner exists, every start prints a one-time setup code:
[admin] No owner account yet. Open /admin and create it with this one-time setup code:
XXXX-XXXX-XXXX-XXXX
- Find the codeIn the terminal, or in your process manager's log (
journalctl,pm2 logs,docker logs). Each start before the owner exists prints a new code; any printed code works. - Open /adminEnter the code, your email and a password of at least 12 characters. Press Create owner and sign in. The code is then spent.
- Secure the accountTurn on two-factor under Security & alerts. Add managers or viewers under Team (roles).
- Walk through Get startedThe admin's setup wizard asks for the product name, accent colour and support email.
05AI key (optional)
Chart reading needs an Anthropic API key. Two ways to set it:
- Create the keySign in at console.anthropic.com, add billing, then API keys → Create key. Copy it; Anthropic shows it once.
- Paste it in the admin Option ASign in as the owner, open Integrations, paste the key into Anthropic API key and press Save changes. Then press Test connection: it checks the key without spending tokens. The key is stored encrypted with
ADMIN_SECRET_KEYand is write-only: it can be replaced or tested, never read back. Only the owner can change it. No restart is needed; the server picks it up within about a minute. - Or put it on the server Option B
ANTHROPIC_API_KEY=in.env(Vercel: an environment variable), then restart or redeploy. It then wins and locks the admin field. - Check itStatus → Anthropic API key accepted turns green, and the desk's top bar shows AI instead of AI off after a reload.
Then look at AI chart reading in the admin: it is on by default (model claude-opus-5, effort high), with a per-visitor hourly limit (20) and a daily cap for the whole desk (500 requests) that protects your API bill. You pay Anthropic for every request.
Nothing breaks. Chart reading is off; templates, the rules editor, JSON rules, share links, the backtest, the lab, paper and live runs all work.
06Where data is stored
| What | Where |
|---|---|
| Admin: settings, owner and team, sessions, audit log, history | THESIS_DATA_DIR/admin.sqlite (default ./data), or Postgres when DATABASE_URL is set. Tables are named mk_admin_* and created on first use. |
| Aggregate counters (AI requests, tokens, config views; per day, 60 days) | THESIS_DATA_DIR/stats.json, or Vercel Blob. |
| User strategies, journal, alert settings, Telegram token | In each user's own browser (localStorage). Never on your server. |
| Agent (trading) key | In the user's browser tab only (memory, or sessionStorage for the life of the tab). |
The server never stores IP addresses, user agents, wallets or per-visitor IDs. Rate limits use salted IP hashes kept in memory.
07Optional checks
npx tsx scripts/smoke-runner.ts # one live decision on mainnet data with the paper broker, then the kill switch
npx tsx scripts/smoke-testnet-order.ts # a signed bracket order to testnet from an unfunded throwaway key
The first needs internet access to Hyperliquid. The second is expected to be rejected by the exchange because the throwaway account does not exist; the point is that Hyperliquid recovers the right signer. (The first script was re-run for these docs; the second was not.)