An AI agent for university students. It reads Canvas, keeps a private workspace of files, searches the web, runs code and drives a browser in a per-user sandbox, and can use the student's school account (Outlook, Degree Works). It explains and guides; it does not hand in graded work as if it were the student's.
- Website: studyhawk.app
- Discord: StudyHawk Discord
- Security: SECURITY.md
| Folder | What it is |
|---|---|
frontend/ |
The web app: React 19, Vite, TypeScript. Installable as a PWA with push notifications. |
backend/ |
Express API on port 4000, the job worker, and the adapters that connect the engine to Postgres, disk and Docker. |
pixlai-engine/ |
The agent engine, a separate package with no StudyHawk code in it. See pixlai-engine/README.md. |
sandbox/ |
Image of the per-user container: Python with document and data libraries, Chromium, and the runner. |
locales/ |
Translations shared by the frontend and the backend. |
StudyHawkWorkflow.html |
Interactive map of the whole system: every component, how they connect, and step-by-step flows. Open it in a browser. |
browser ──HTTPS──▶ nginx :80 ──/api/──▶ backend :4000 ──INSERT job──▶ PostgreSQL
│
SSE (job_events) ◀── JobWorker ◀──claim─────────┘
│
PixlAI-Engine ──▶ model (Ollama, OpenAI-compatible, Anthropic, ChatGPT)
│
tools: Canvas · files · RAG · web · code · browser · school email
│
sandbox container per user (via docker.sock)
A request only queues the work. A worker on any replica runs the agent and writes every event to the database, and the browser reads them live over SSE. Closing the tab, reconnecting or running several replicas loses nothing.
Everything the replicas share lives in PostgreSQL (data, job queue, LISTEN/NOTIFY bus, leader locks) and in a shared
/data folder (workspaces, TEMP, avatars).
For the full picture, open StudyHawkWorkflow.html in a browser. It maps every component and connection, with file paths, and walks through flows such as a chat message, approvals, the sandbox, school sign-in, scheduled tasks, MCP apps and billing.
- Node.js 20.3 or newer (the images use Node 26).
- Docker, for the sandbox (code, browser and school account) and for the container setup.
- PostgreSQL 14 or newer in production, with
UTF8encoding. Development starts an embedded one.
# 1. Sandbox image (once; without it, code, browser and school tools are off)
docker build -t studyhawk-sandbox:dev sandbox
# 2. Backend: embedded Postgres in data/dev-postgres, generated MASTER_KEY,
# seed accounts admin/admin and user/user
cd backend && npm install && npm run dev
# 3. Frontend (another terminal)
cd frontend && npm install && npm run devnpm run dev:mock in frontend/ runs the UI with a fake backend, no database needed.
To try two replicas behind a balancer, with Postgres and SearXNG:
MASTER_KEY=$(openssl rand -base64 32) docker compose -f docker-compose.dev.yml up --build
# http://localhost:8080 (admin / change-me-now; production refuses that password outside localhost)One container per machine from ghcr.io/pixlgalaxy/studyhawk, behind your own TLS proxy (for example Cloudflare
Tunnel → Nginx Proxy Manager). Postgres and the shared /data storage are external.
cp .env.example .env # fill in DATABASE_URL, MASTER_KEY, PUBLIC_URL, ADMIN_*
docker network create edge # StudyHawk, Nginx Proxy Manager and cloudflared share it; no port is published
docker run -d --name studyhawk --network edge --env-file .env -e NODE_ID=node-1 \
-v /mnt/studyhawk/data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
-e SANDBOX_DATA_HOST_PATH=/mnt/studyhawk/data \
ghcr.io/pixlgalaxy/studyhawk:<version>MASTER_KEYmust be identical on every replica. Losing it means every stored secret has to be entered again.SANDBOX_DATA_HOST_PATHis where/datalives on the host, so Docker can mount each user's folder into their sandbox.- A
httpsPUBLIC_URLmakes the session cookiesSecure. SetTRUST_PROXYto the address of the proxy in front only, andCLIENT_IP_HEADER=cf-connecting-ipbehind Cloudflare. - The Docker socket gives the container control of the host's Docker; see the open items in SECURITY.md.
- The backend runs as uid 1000, like the sandboxes, and the entrypoint gives it
/dataon start. Data written by an older image (which ran the backend as root) can hold root-owned files inside the users' folders; the container log says so. Fix them once, with every StudyHawk container and sandbox stopped:chown -R 1000:1000 /mnt/studyhawk/data. - SMTP, models, institutions, plans, Stripe and web push are set in the admin panel after the first login.
- Read "Deploying safely" (with the Nginx Proxy Manager and Cloudflare settings) and "Open items" in SECURITY.md before opening it to students.
Every variable is documented in .env.example. The ones you usually change:
| Variable | Default | Purpose |
|---|---|---|
DATABASE_URL |
required | PostgreSQL |
MASTER_KEY |
required | 32 bytes, base64: openssl rand -base64 32 |
PUBLIC_URL |
Public address, used in email links and OAuth | |
NODE_ID |
hostname | Replica name in the admin panel |
JOB_WORKERS |
4 | Jobs run at the same time per replica |
SANDBOX_ENABLED |
true | false turns off code, browser and school tools |
SANDBOX_IMAGE |
ghcr.io/pixlgalaxy/studyhawk-sandbox:latest |
Per-user container image |
SEARXNG_URL |
Web search without API keys; empty uses DuckDuckGo |
cd pixlai-engine && npm test # engine
cd backend && npm test # backend unit tests
cd frontend && npm run lint && npm run buildEnd-to-end suites drive a running server with fake Canvas, model and school services. See backend/test/e2e/README.md.
- The school account feature stores the student's password (encrypted) and signs in through Microsoft and Duo with an automated browser. Schools may not allow this; check the institution's IT policy before enabling it.
- The sandbox can reach the internet without a filter. See "Open items" in SECURITY.md.
StudyHawk is source-available, not open source. Copyright (c) 2025-2026 Fabrizio Gamboa (PixlGalaxy).
- StudyHawk (everything except
pixlai-engine/): StudyHawk Source-Available License. You may read the code and run and modify it on your own devices to learn, evaluate or contribute. You may not use it commercially, host it for others, redistribute it, promote it, or remove or change its branding. Only the author may profit from it. It covers every version since the first commit, including the EagleDocs name. - PixlAI-Engine (
pixlai-engine/): PixlAI-Engine License, MIT with attribution. Free for any use, including commercial, as long as the product credits "Built with PixlAI-Engine by Fabrizio Gamboa (PixlGalaxy) - fabriziogamboa.com" in its documentation and in its user interface. - StudyHawk, EagleDocs and their logos belong to the author and are not licensed for any other use.
For a commercial license or any other permission, write to support@studyhawk.app.
Pull requests are welcome. Accepted contributors are listed on the StudyHawk website; contributing does not come with payment or ownership. See CONTRIBUTING.md.
- Fabrizio Gamboa (PixlGalaxy), creator and owner · GitHub