Croft

Setup & Admin Guide

Prerequisites

Initial Setup

# Clone and install
git clone <repo-url> croft-home-assistant
cd croft-home-assistant
pnpm install

# Create D1 database
wrangler d1 create croft-db

# Update wrangler.jsonc with the database_id from above

# Run migrations
pnpm --filter @croft/db migrate

# Seed with sample data (optional)
pnpm --filter @croft/db seed

# Start dev server
pnpm dev

Agent API Key

The AI agent authenticates with the web app using a Bearer token. Set the AGENT_API_KEY secret:

# For local development — set in wrangler.jsonc vars or .dev.vars
AGENT_API_KEY=your-secret-key-here

# For production
wrangler secret put AGENT_API_KEY

The agent includes this key in all API requests as Authorization: Bearer <key>.

Google Calendar API

Connecting Google Calendar lets the agent see your schedule and plan accordingly (quick meals on busy nights).

1. Create OAuth Credentials

  1. Go to the Google Cloud Console → Credentials
  2. Create an OAuth 2.0 Client ID (Web application type)
  3. Add your redirect URI: https://your-domain.com/api/calendar/callback
  4. For local dev: http://localhost:5173/api/calendar/callback

2. Enable the Calendar API

  1. Go to APIs & Services → Library
  2. Search for "Google Calendar API" and enable it

3. Required Scopes

Croft requests calendar.readonly and userinfo.email scopes — read-only access to calendar events and your email for display purposes.

4. Set Environment Variables

GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=https://your-domain.com/api/calendar/callback

Then connect your calendar in Settings → Calendar.

Notion Recipe Database

The meal plan generator reads recipes directly from Notion using the Notion API. Recipes are synced to the local database each time a plan is generated.

Setup

  1. Create a Notion database for your recipes. The generator reads the page Name (title property) and Page ID.
  2. Create a Notion integration and grant it access to your recipe database
  3. Add the integration token and database ID to agent/agent.config.json:
{
  "apiUrl": "https://your-domain.com",
  "apiKey": "your-agent-api-key",
  "notionApiKey": "ntn_your-notion-integration-token",
  "notionDatabaseId": "your-notion-database-uuid"
}

Push Notifications (VAPID)

Push notifications require VAPID keys for authentication with the Web Push protocol.

Generate Keys

npx web-push generate-vapid-keys

Set Environment Variables

VAPID_PUBLIC_KEY=BPxxxxxxx...
VAPID_PRIVATE_KEY=xxxxxxx...
VAPID_SUBJECT=mailto:you@example.com

Users can then subscribe in Settings → Notifications.

Cloudflare Access (Production Auth)

In production, the browser UI is protected by Cloudflare Access (Zero Trust). This handles user authentication without any login pages in the app.

  1. Go to Cloudflare Zero Trust → Access → Applications
  2. Add a Self-hosted Application for your domain
  3. Create a policy allowing your email or identity provider
  4. The agent API routes use Bearer token auth and bypass Access — no additional configuration needed

Scheduled Tasks

Two tasks run on the Mac Mini to manage meal plans:

Monthly — Generate 4-Week Plan

A deterministic script that reads all recipes from Notion, excludes recently planned meals, and generates a 4-week dinner plan. Run via cron or manually:

# Run the plan generator
pnpm --filter @croft/agent generate-plan

# Example cron (1st of each month at 8am):
0 8 1 * * cd /path/to/croft-home-assistant && source ~/.nvm/nvm.sh && nvm use 24 && pnpm --filter @croft/agent generate-plan

The script: fetches all Notion recipes, syncs them to the database, filters out meals planned in the last 2 weeks, shuffles and assigns 28 dinners across 4 weeks, then sends a push notification.

Weekly — Wednesday Check-in

Runs every Wednesday via Claude Desktop. The prompt is at agent/claude-desktop/weekly-task.md. It sends a push notification reminding you to review the upcoming week's plan.

Deployment

# Build all packages
pnpm build

# Deploy to Cloudflare Workers
cd apps/web
wrangler deploy

# Set production secrets
wrangler secret put AGENT_API_KEY
wrangler secret put GOOGLE_CLIENT_SECRET
wrangler secret put VAPID_PRIVATE_KEY