# teach-server A self-hosted page hosting platform for single-HTML pages produced by an HTTP-capable agent (recommended: Claude Code desktop or CLI; Claude Cowork lacks the tools to complete the bootstrap). Accounts are invite-only. Pages are public. ## Authentication - GET /auth/salt?email= → { salt } | 401 not-invited | 403 invite-not-redeemed - POST /auth/login { email, hash } → { api_key, username } hash = SHA256(password + salt) (lowercase hex, 64 chars) - All authenticated non-hosted endpoints accept: - Authorization: Bearer (recommended for agents) - Cookie: sid= (browsers) Store the api_key under /.teach-server/credentials.json with chmod 600: { "base_url": "", "username": "", "api_key": "tk_..." } ## Uploading a page POST /api/pages Authorization: Bearer Content-Type: application/json { "slug": "", "title": "page title — REQUIRED, ≤ 200 chars", "html": "… (single file, ≤ 10 MB, inline CSS/JS)", "category": "optional — one of the keys below; omit and the server auto-classifies" } → { "url": "/u///", "category": "", "has_thumbnail": true|false, "updated_at": "..." } title is REQUIRED. category is OPTIONAL — pass one key if you know it, otherwise omit it and the server classifies the page automatically: health-edu=衛教 · teaching=教學・工作坊 · schedule-form=排班・表單 · tool=工具・儀表板 · presentation=簡報・作品 · other=其他 Thumbnails are generated automatically server-side (a screenshot of your page) — you do NOT need to provide one. Optional override: include a "thumbnail" field (base64 PNG, data:image/png;base64,... or raw, ≤ 500 KB decoded) to supply your own instead. The thumbnail is shown on the homepage / /demo cards. Re-uploading the same slug overwrites the page. Only one HTML file per page; embed assets as data URIs or reference HTTPS CDNs. ## HTML format rules (CSP — silent failure if ignored) Served CSP: default-src 'self' https:; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; media-src 'self' data: https: - Inline