Quick start
For the terminal-comfortable: install, start, choose a password.
You need
- A Mac with Apple silicon that can stay on (a Mac mini makes a good host)
- The Xcode command-line tools (
xcode-select --install) and Homebrew - An Anthropic API key
1. Install
git clone https://github.com/ben4mn/meet-edward.git && cd meet-edward
./setup.sh # installs everything, asks for your name, API key and time zone./setup.sh is safe to run again; each step checks what is already there. It stops before installing anything on an Intel Mac or in a Rosetta shell. It installs [email protected], postgresql@16 and node with Homebrew, builds pgvector from source for Postgres 16, creates the edward database, makes backend/.venv with pinned dependencies, installs Playwright’s headless shell, runs npm ci, builds two small Swift helpers (media and EventKit), and writes .env from .env.example.
| Flag | What it adds |
|---|---|
--with-test-db | the backend tests’ own Postgres cluster on :5433 |
--launchagents | runs scripts/install-launchagents.sh at the end |
--no-helpers | skips building the Swift helpers |
--non-interactive | never prompts; takes EDWARD_OWNER_NAME, ANTHROPIC_API_KEY and TIMEZONE from the environment |
2. Start Edward, one of two ways
Always on (the usual choice for the Mac that hosts him). launchd starts him now and at every login, and restarts him if he stops:
bash scripts/install-launchagents.shIt installs the backend (:8000), the frontend (:3000), a health check every five minutes plus a deeper one at 08:00, a nightly backup at 03:30 (to ~/edward-backups unless EDWARD_BACKUP_DIR says otherwise) and a daily memory report, labelled com.meet-edward.*. It takes --with-graph, --without-backup, --dry-run and --uninstall. If you started Edward by hand from this checkout, it stops that copy first.
By hand. He runs until you stop him or the Mac restarts:
./restart.sh # backend :8000, frontend :3000With the agents loaded, ./restart.sh (or ./restart.sh backend|frontend) restarts through launchd. It only restarts its own checkout’s Edward: in a second clone it refuses (exit 78) to touch agents that run another one.
The first start takes a few minutes: the backend downloads its embedding model and sets up the database, and the frontend runs its first production build. ./restart.sh waits up to 2 minutes for the backend and 4 for the frontend, then says “still starting” and exits 0. Logs: /tmp/edward-backend.log and /tmp/edward-frontend.log.
3. Choose a password, on the Mac itself
Open http://localhost:3000 on the Mac that runs Edward. The first visit asks for a password and a one-time setup code:
cat backend/.setup_codeThe backend writes the code when it starts with no password set; only your macOS user can read it, and it is deleted once the password is set. Until then the API answers nothing but the sign-in pages, and the setup request must come from a page at localhost on this Mac. No screen on the Mac? Forward the port and read the code over ssh:
ssh -L 3000:localhost:3000 [email protected]
ssh [email protected] cat <your checkout>/backend/.setup_code4. After you sign in
- Edward tab → Mind → Skills. Every skill starts off on a fresh install. Turn on what Edward may use: Shell/Bash (his computer:
bashand the editor), Web Search, iMessage, Push Notifications, iOS Widget. - House → Locale. Check your time zone: reminders, quiet hours and “today” follow it.
- macOS permissions (System Settings → Privacy & Security), only for what you use:
- Full Disk Access for the python
setup.shprints at the end: iMessage, Mail, Contacts, Calendar and Reminders are read from their databases through it. Started by hand with./restart.sh, macOS charges your terminal app instead, so grant that too. - Automation: macOS asks the first time Edward sends a message or drives Chrome.
- Calendars and Reminders (for changes): run
bash backend/scripts/eventkit_request_access.shwhile sitting at the Mac.
- Full Disk Access for the python
Reaching him from your phone
Installing the PWA, push notifications and the microphone all need HTTPS. Put a tunnel (Cloudflare Tunnel, Tailscale, ngrok) or a reverse proxy in front of port 3000, set EDWARD_PUBLIC_BASE_URL to that address, and name the tunnel’s LaunchAgent in EDWARD_TUNNEL_LABEL so the health check watches it. The backend listens on every interface so devices on your network (a hub) can reach it; EDWARD_BACKEND_HOST=127.0.0.1 keeps it to this Mac. Behind a tunnel, leave uvicorn’s FORWARDED_ALLOW_IPS unset: sign-in limits read the client from the tunnel’s own headers.
Is it working?
GET /api/health/report(signed in) says what works: turns and tool failures, pings, the calendar, mail, the last memory report, spend, and whether the app’s time zone matches the Mac’s.GET /api/health/spendshows today’s Claude spend against the cap.- The watchdog writes to
~/.edward-health/health.log.
Common issues
Signing in loops back to the login page
The session cookie is Secure, which assumes HTTPS (browsers make an exception for http://localhost). Use HTTPS, or set EDWARD_COOKIE_SECURE=off on a plain-HTTP network you trust.
Messages, Mail or Calendar can’t be read
Full Disk Access is tied to the python binary’s path, so brew upgrade [email protected] silently breaks it: grant the new path and re-run bash scripts/install-launchagents.sh and bash backend/scripts/eventkit_request_access.sh.
pgvector is missing after a Postgres reinstall
brew reinstall postgresql@16 removes the pgvector built from source. Run ./setup.sh again.
Next: Configuration (every setting, and what ships off), or Upgrading from March if you ran the March 2026 release. The README is the canonical version of this page.