Quick start
One command. The installer detects your OS, writes a single .env, generates secrets, seeds an admin account and starts the terminal — in Docker if you have it, otherwise with local Python and Node.
$ git clone https://github.com/Hitheshkaranth/OpenTerminalUI.git $ cd OpenTerminalUI $ ./install.sh # Windows: ./install.ps1 ✓ OpenTerminalUI is ready → http://localhost:8000 email: admin@openterminal.local password: <generated>
The credentials are also saved in .env. Change the password after first login. Force a mode with OTUI_MODE=docker or OTUI_MODE=local.
Prerequisites
Either Docker, or Python and Node for the local path. Nothing else to configure.
| Software | Version | Needed for |
|---|---|---|
| Docker | 20.10+ with Compose v2 | Recommended — full stack in containers |
| Python | 3.11+ | Local backend |
| Node.js | 20+ | Local frontend |
| Hardware | 2 cores · 4 GB RAM · 2 GB disk | Minimum; 4 cores / 8 GB recommended |
Docker image
Every release publishes a multi-arch image (linux/amd64 and linux/arm64) to GitHub Container Registry, tagged X.Y.Z, X.Y and latest. No clone needed.
$ docker run -p 8000:8000 -v otui-data:/app/data \ ghcr.io/hitheshkaranth/openterminalui:latest ✓ http://localhost:8000
Pass keys with -e FMP_API_KEY=… or --env-file .env. The volume keeps the SQLite database across upgrades; without Redis the quote bus falls back to in-memory automatically.
Docker Compose
$ cp .env.example .env # add API keys if you have them $ docker compose up --build # backend + Redis, SQLite $ docker compose --profile postgres up --build # with PostgreSQL 16 $ docker compose down -v # stop and wipe the database
The UI and API are served from the backend container at http://127.0.0.1:8000. Compose maps host.docker.internal so the container can reach LM Studio on your host.
Local development
$ python3.11 -m venv .venv $ source .venv/bin/activate $ pip install -r backend/requirements.txt $ PYTHONPATH=. uvicorn backend.main:app --reload
$ cd frontend $ npm ci $ npm run dev → http://127.0.0.1:5173
Run every check before a PR with make gate.
API keys & providers
All keys are optional — the terminal runs on free sources out of the box. Add keys from the terminal or in the browser.
In the browser (admins)
Settings → Data Providers shows what each provider unlocks, its live status and last error. Set keys writes the same .env the installer uses, applies values live where possible and lists what needs a restart; Test runs the real probe. Placeholder values such as your-api-key are not treated as configured.
From the terminal
$ make keys # or ./scripts/setup-keys.sh — guided, shows what each key unlocks
Provider waterfall
| Provider | Market | Provides |
|---|---|---|
| Zerodha Kite | India | Live ticks, OHLCV at all intervals, holdings/positions import |
| NSEPython | India | F&O chains, OI, PCR, corporate actions |
| FMP | US | OHLCV, fundamentals, earnings, news |
| Finnhub | US | WebSocket ticks, OHLCV, news |
| Alpaca | US | Quotes |
| Yahoo Finance | Global | Fallback OHLCV and quotes — no key |
| FRED · FXMacroData | Macro | Policy rates, CPI, GDP, release calendar — FXMacroData needs no key |
Environment
| Variable | Purpose |
|---|---|
| FMP_API_KEY | US equities, fundamentals, earnings |
| FINNHUB_API_KEY | US real-time WebSocket ticks |
| KITE_API_KEY · _SECRET · _ACCESS_TOKEN | Zerodha Kite — India live + historical (access token is daily) |
| OPENROUTER_API_KEY | AI research agent — free :free models work |
| LM_STUDIO_BASE_URL · _MODEL | Local model for news sentiment and the agent |
| DATABASE_URL · REDIS_URL | SQLite by default; PostgreSQL and Redis optional |
| JWT_SECRET_KEY · CACHE_SIGNING_KEY | Generated by the installer |
| BOOTSTRAP_ADMIN_EMAIL · _PASSWORD | First-run admin; skipped once any user exists |
The full list is in the README.
Provenance
Every security snapshot carries {source, quality, as_of, latency_ms, note}. The UI renders it as a chip next to the value:
Provider health comes from GET /api/providers/status, which runs real probes — an expired Kite token reads down.
MCP & agents
The agent's tool registry is exposed over the Model Context Protocol, so Claude Code, Claude Desktop or any MCP client can use the terminal.
1 · Create an API key
In Settings → API Keys, create an otui_ key with read (38 read-only tools) or read_write permission (adds 7 propose_* tools). The key maps to your user, so tools see your portfolio, watchlists and alerts.
2 · Connect
GET /api/mcp/manifest # tools, resources, prompts GET /api/mcp/tools POST /api/mcp/tools/{{name}} X-API-Key: otui_…
For a local stdio session run python -m backend.mcp from the repo root (anonymous — market-data tools only).
propose_* call creates a pending row that a human confirms in the app. Nothing places real orders — trading is paper only.Every result is returned as {ok, data, provenance}, and five prompts ship with the server: morning_brief, position_review, screen_to_thesis, risk_check, idea_to_backtest.
Caching & failover
| Layer | Behaviour |
|---|---|
| L1 SQLite | Per symbol and interval, default TTL 900 s |
| L2 Redis | Optional via REDIS_URL; also quote pub/sub fan-out |
| Live candles | WebSocket ticks update bars in memory without touching the cache |
| Prefetch | OPENTERMINALUI_PREFETCH_ENABLED=1 warms the cache |