Setup & Admin Guide
Prerequisites
- Node.js 24+ (via nvm recommended)
- pnpm package manager
- A Cloudflare account with Workers and D1 enabled
- A Notion integration for recipe access
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 devAgent 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_KEYThe 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
- Go to the Google Cloud Console → Credentials
- Create an OAuth 2.0 Client ID (Web application type)
- Add your redirect URI:
https://your-domain.com/api/calendar/callback - For local dev:
http://localhost:5173/api/calendar/callback
2. Enable the Calendar API
- Go to APIs & Services → Library
- 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/callbackThen 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
- Create a Notion database for your recipes. The generator reads the page Name (title property) and Page ID.
- Create a Notion integration and grant it access to your recipe database
- 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-keysSet Environment Variables
VAPID_PUBLIC_KEY=BPxxxxxxx...
VAPID_PRIVATE_KEY=xxxxxxx...
VAPID_SUBJECT=mailto:you@example.comUsers 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.
- Go to Cloudflare Zero Trust → Access → Applications
- Add a Self-hosted Application for your domain
- Create a policy allowing your email or identity provider
- 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-planThe 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