No description
  • HTML 57.5%
  • JavaScript 42.3%
  • Dockerfile 0.2%
Find a file
Brian 97f6feb53a
All checks were successful
Build and Deploy / build (push) Successful in 9s
Build and Deploy / deploy (push) Successful in 14s
CI: move Portainer stack/endpoint IDs to secrets
Replace the hardcoded STACK_ID "15" / ENDPOINT_ID "3" with
secrets.PORTAINER_STACK_ID / secrets.PORTAINER_ENDPOINT_ID, so the deploy
target isn't baked into the workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 02:06:23 -06:00
.forgejo/workflows CI: move Portainer stack/endpoint IDs to secrets 2026-06-03 02:06:23 -06:00
public Drop the mediator prompt; group chats use the default prompt + a group note 2026-06-03 01:51:16 -06:00
server Drop the mediator prompt; group chats use the default prompt + a group note 2026-06-03 01:51:16 -06:00
.dockerignore Initial commit 2026-05-27 11:20:49 -06:00
.env.example Add admin page; move runtime config from env vars to the database 2026-06-01 10:58:13 -06:00
.gitignore Complete PDF knowledge extraction with rules condensing and prompt caching 2026-06-01 22:42:14 +00:00
docker-compose.yml CI: deploy by passing docker-compose.yml instead of an inline heredoc 2026-06-03 02:03:21 -06:00
Dockerfile Move users into database 2026-05-31 21:32:19 -06:00
package-lock.json Extract PDF text locally with MuPDF; add text/image upload choice 2026-06-02 10:31:02 -06:00
package.json Extract PDF text locally with MuPDF; add text/image upload choice 2026-06-02 10:31:02 -06:00
README.md Add admin page; move runtime config from env vars to the database 2026-06-01 10:58:13 -06:00

Claude Family Chat

A self-hosted chat app that lets your family share access to Claude — each person gets their own private conversation history. Your API key stays on the server.

Quick Start

1. Get an API key

Sign up at console.anthropic.com and create an API key.

2. Edit docker-compose.yml

Open docker-compose.yml and fill in:

ANTHROPIC_API_KEY: "sk-ant-your-actual-key"
USERS: '{"alice":"password1","bob":"password2"}'
SESSION_SECRET: "any-long-random-string"

3. Run it

docker compose up -d

The app is now running at http://localhost:3000

On your home network, other devices can reach it at http://YOUR-LOCAL-IP:3000 (Find your IP with ipconfig on Windows or ifconfig / ip addr on Mac/Linux)


The Admin Page

Admins get a dedicated page at /admin (a ⚙ Admin link appears in the sidebar). From there you can, without ever editing the deploy or restarting:

  • Manage users — add a user directly (username + temporary password), or generate a one-time invite link (/join?token=…) the new person opens to set their own password. Delete users and grant/revoke admin.
  • View usage & cost — per-user token usage and pergroup-chat usage (group chats are tracked separately), with period filters and cost estimates.
  • Manage shared chats — create, edit (title / members / prompt), and delete.
  • Edit configuration — the default system prompt, model, max-history, and the Anthropic & Brave API keys (masked, with reveal). Changes take effect immediately.

Everything here is stored in the SQLite database (/data/app.db).


Managing Users

Users and the admin flag are stored in a small SQLite database (/data/app.db), with passwords hashed (scrypt) — they're never stored in plaintext. Day-to-day user management happens on the Admin Page; the environment variables below are only used to bootstrap an empty database on first run.

First run: set USERS and ADMIN_USER so the first accounts (including your admin) exist. On the very first boot with an empty database, these are imported automatically:

USERS: '{"mom":"secure-pass","dad":"another-pass","kid1":"their-pass"}'
ADMIN_USER: 'mom'

After the first boot the database is the source of truth — changes to USERS / ADMIN_USER are ignored once any user exists. Manage users from the Admin Page instead. (To re-seed from scratch, wipe the data volume with docker compose down -v.)


Environment Variables

Most settings now live in the database and are edited on the Admin Page. The variables below seed the database on first boot only (when their value isn't set in the DB yet); afterward the DB wins and the admin page is where you change them. Only the infrastructure variables (SESSION_SECRET, DB_FILE, PORT) are read from the environment on every boot.

Variable Default Description
ANTHROPIC_API_KEY (required first boot) Your Anthropic API key. Seeds the DB, then editable on the Admin Page
USERS {} JSON object of username→password pairs. First boot only — ignored once any user exists
ADMIN_USER (none) Username to mark as admin when seeding. First boot only
BRAVE_API_KEY (none) Brave Search API key (enables web search). Seeds the DB, then editable on the Admin Page
CLAUDE_MODEL claude-sonnet-4-6 Default model. Seeds the DB, then editable on the Admin Page
MAX_HISTORY 100 Max messages kept per chat. Seeds the DB, then editable on the Admin Page
SYSTEM_PROMPT (helpful-assistant prompt with tool guidance) Default system prompt. Seeds the DB, then editable on the Admin Page
SESSION_SECRET change-me-in-production Secret for signing session cookies — change this! Read from env every boot
DB_FILE /data/app.db Path to the SQLite database. Read from env every boot
PORT 3000 Port the server listens on. Read from env every boot

Data & Privacy

  • Conversation histories are saved in a Docker volume (chat-data) — they persist across restarts
  • User accounts and runtime config (API keys, system prompt, model) live in a SQLite database (/data/app.db) on the same volume; passwords are hashed (scrypt), never stored in plaintext
  • Each user's history is completely isolated from other users
  • Your API key is only on the server; it's never sent to the browser (admins can reveal it on the Admin Page)
  • To wipe all history and accounts: docker compose down -v (deletes the volume)

Monitoring Costs

Keep an eye on your API usage at console.anthropic.com/usage. Set a spending limit under Settings → Limits to avoid surprises.


Updating

docker compose pull   # if using a registry image
docker compose up -d --build

Running on a Raspberry Pi or Home Server

Works great on any always-on machine. Just open port 3000 in your firewall/router if you want access outside your home network (consider adding HTTPS via a reverse proxy like Caddy or nginx in that case).