Apple Flow

Complete environment variable reference and defaults.

Environment Setup

All Apple Flow settings are controlled via the .env file (or shell environment variables). Every variable uses the apple_flow_ prefix.

Get started:

./scripts/setup_autostart.sh
# or manually:
# cp .env.example .env
# nano .env

Required Settings

These must be set before the daemon will start.

VariableExampleDescription
apple_flow_allowed_senders+15551234567Comma-separated phone numbers in E.164 format. Only messages from these numbers are processed. Your own number goes here.
apple_flow_allowed_workspaces/Users/yourname/codeComma-separated absolute paths the AI is allowed to read/write.
apple_flow_default_workspace/Users/yourname/code/my-projectDefault working directory for the AI connector. Must be inside allowed_workspaces.
apple_flow_db_path~/.apple-flow/relay.dbSQLite state database path. If not explicitly set, Apple Flow auto-migrates legacy ~/.codex/relay.db to this location when safe.

Phone number format:

  • Correct: +15551234567
  • Wrong: 5551234567, (555) 123-4567

Connector

Pick one AI backend. The value of apple_flow_connector determines which is used.

VariableDefaultOptions / Description
apple_flow_connectorcodex-clicodex-cli — uses codex exec (requires codex login)<br>claude-cli — uses claude -p (requires claude auth login)<br>gemini-cli — uses gemini -p (requires gemini auth login)<br>cline — uses cline -y (supports multiple model providers)<br>codex-app-server — deprecated stateful connector

Codex CLI settings (connector=codex-cli)

VariableDefaultDescription
apple_flow_codex_cli_commandcodexPath to the codex binary.
apple_flow_codex_cli_model(empty)Model flag passed to codex (e.g. gpt-5.3-codex). Empty = use codex default.
apple_flow_codex_cli_context_window10Number of recent message exchanges to inject as context per turn.

Claude Code CLI settings (connector=claude-cli)

VariableDefaultDescription
apple_flow_claude_cli_commandclaudePath to the claude binary.
apple_flow_claude_cli_model(empty)Model flag (e.g. claude-sonnet-4-6, claude-opus-4-6). Empty = claude default.
apple_flow_claude_cli_context_window10Recent exchanges to inject per turn.
apple_flow_claude_cli_dangerously_skip_permissionstruePass --dangerously-skip-permissions to the claude binary.
apple_flow_claude_cli_tools(empty)Comma-separated values for --tools (e.g. default,WebSearch).
apple_flow_claude_cli_allowed_tools(empty)Comma-separated values for --allowedTools (e.g. WebSearch).

Gemini CLI settings (connector=gemini-cli)

VariableDefaultDescription
apple_flow_gemini_cli_commandgeminiPath to the gemini binary.
apple_flow_gemini_cli_modelgemini-3-flash-previewModel flag passed to gemini.
apple_flow_gemini_cli_context_window10Number of recent exchanges to inject per turn.

Cline settings (connector=cline)

VariableDefaultDescription
apple_flow_cline_commandclinePath to the cline binary.
apple_flow_cline_model(empty)Model name for Cline. Empty = Cline default.
apple_flow_cline_context_window3Number of recent exchanges to inject per turn.
apple_flow_cline_use_jsontrueParse Cline JSON output when available.
apple_flow_cline_act_modetrueEnable Cline act mode for faster execution.

Safety & Security

VariableDefaultDescription
apple_flow_only_poll_allowed_senderstrueFilter unknown senders at SQL query time. Keep true unless debugging.
apple_flow_require_chat_prefixfalseWhen true, only messages starting with the chat prefix (e.g. relay:) are processed. Natural language mode is the default (false).
apple_flow_chat_prefixrelay:The prefix string checked when require_chat_prefix=true.
apple_flow_approval_ttl_minutes20How long a pending approval request stays valid before it expires.
apple_flow_max_messages_per_minute30Rate limit per sender. Messages beyond this are silently dropped.
apple_flow_process_historical_on_first_startfalseSkip messages already in the DB when the daemon first starts. Keep false to avoid a flood of old messages being replayed.
apple_flow_notify_blocked_sendersfalseReply to blocked senders explaining they're not allowed. Keep false in production.
apple_flow_notify_rate_limited_sendersfalseReply when rate limiting kicks in. Keep false in production.

Behavior & UX

VariableDefaultDescription
apple_flow_send_startup_introtrueSend an iMessage intro on daemon startup with workspace + command list.
apple_flow_suppress_duplicate_outbound_seconds90Suppress identical outbound messages within this window (prevents echo loops).
apple_flow_poll_interval_seconds2How often to poll the Messages database (seconds).
apple_flow_codex_turn_timeout_seconds300Timeout for a single AI turn across all connectors (5 minutes).
apple_flow_auto_context_messages10Number of recent messages to auto-inject as context each turn. 0 disables.
apple_flow_personality_prompt(empty)System prompt injected for all chat turns. Use {workspace} as a placeholder. Example: You are a senior engineer on the {workspace} project.
apple_flow_inject_tools_contexttruePrepend a description of Apple Flow tools (Notes, Mail, Reminders, Calendar, iMessage) to AI prompts.

Admin API

VariableDefaultDescription
apple_flow_admin_host127.0.0.1Host for the admin API server.
apple_flow_admin_port8787Port for the admin API server.

Access it at http://localhost:8787 — endpoints: /sessions, /approvals/pending, /events, POST /task.


Apple Mail Integration

Enable email as an additional ingress channel (optional, runs alongside iMessage).

VariableDefaultDescription
apple_flow_enable_mail_pollingfalseEnable Apple Mail as an ingress source.
apple_flow_mail_allowed_senders(empty)Comma-separated email addresses to accept.
apple_flow_mail_from_address(empty)Sender address for outbound replies. Empty = Mail.app default.
apple_flow_mail_poll_account(empty)Mail.app account name to poll. Empty = all accounts / inbox.
apple_flow_mail_poll_mailboxINBOXMailbox to poll within the account.
apple_flow_mail_max_age_days2Only process emails received in the last N days.
apple_flow_mail_signature\n\n—\nApple Flow 🤖, Your 24/7 AssistantSignature appended to all outbound email replies.

Minimal config to enable:

apple_flow_enable_mail_polling=true
apple_flow_mail_allowed_senders=you@example.com
apple_flow_mail_from_address=you@example.com

Apple Reminders Integration

Incomplete reminders in a designated list become tasks for the AI.

VariableDefaultDescription
apple_flow_enable_reminders_pollingfalseEnable Apple Reminders as a task queue.
apple_flow_reminders_list_nameagent-taskReminders list to watch for new tasks.
apple_flow_reminders_archive_list_nameagent-archiveList to move completed reminders into.
apple_flow_reminders_owner(first allowed_sender)Sender identity used for reminder tasks (phone number).
apple_flow_reminders_auto_approvefalseSkip the approval gate for reminder tasks.
apple_flow_reminders_poll_interval_seconds5How often to poll Reminders (seconds).

Apple Notes Integration

Notes in a designated folder become tasks; results are appended back to the note.

VariableDefaultDescription
apple_flow_enable_notes_pollingfalseEnable Apple Notes as a task ingress.
apple_flow_notes_folder_nameagent-taskNotes folder to watch.
apple_flow_notes_archive_folder_nameagent-archiveFolder to move completed notes into.
apple_flow_notes_owner(first allowed_sender)Sender identity for note tasks.
apple_flow_notes_auto_approvefalseSkip the approval gate for note tasks.
apple_flow_notes_poll_interval_seconds10How often to poll Notes (seconds).
apple_flow_notes_fetch_timeout_seconds20AppleScript fetch timeout per poll cycle.
apple_flow_notes_fetch_retries1Retries after a Notes fetch timeout.
apple_flow_notes_fetch_retry_delay_seconds1.5Seconds to wait between retries.

Notes Logging

Log every AI response as a new note (independent of notes polling).

VariableDefaultDescription
apple_flow_enable_notes_loggingfalseCreate a note for each AI completion.
apple_flow_notes_log_folder_nameagent-logsFolder to write log notes into (auto-created if missing).

Apple Calendar Integration

Calendar events in a designated calendar trigger tasks when they come due.

VariableDefaultDescription
apple_flow_enable_calendar_pollingfalseEnable Apple Calendar as a task scheduler.
apple_flow_calendar_nameagent-scheduleCalendar to watch for due events.
apple_flow_calendar_owner(first allowed_sender)Sender identity for calendar tasks.
apple_flow_calendar_auto_approvefalseSkip the approval gate for calendar tasks.
apple_flow_calendar_poll_interval_seconds30How often to poll Calendar (seconds).
apple_flow_calendar_lookahead_minutes5How many minutes ahead to look for events becoming due.

Trigger Tag

A global tag that gates processing across all Apple app channels (Reminders, Notes, Mail, Calendar). Items without this tag are silently skipped.

VariableDefaultDescription
apple_flow_trigger_tag!!agentTag string required on items for them to be processed. Set to empty string "" to process everything.

Multi-Workspace Routing

Route commands to different directories using @alias syntax (e.g. task: @web-app deploy).

VariableDefaultDescription
apple_flow_workspace_aliases{}JSON object mapping alias names to absolute workspace paths.

Example:

apple_flow_workspace_aliases={"web-app":"/Users/yourname/Projects/web-app","api":"/Users/yourname/Projects/api"}

Then send: task: @web-app run the test suite


Progress Streaming

Send periodic iMessage updates during long-running tasks.

VariableDefaultDescription
apple_flow_enable_progress_streamingtrueEnable intermediate milestone/progress messages.
apple_flow_progress_update_interval_seconds30Minimum seconds between progress updates.
apple_flow_execution_heartbeat_seconds120Heartbeat interval for long-running execution attempts.
apple_flow_checkpoint_on_timeouttrueConvert timeout outcomes into checkpoint + re-approval instead of immediate failure (until max attempts).
apple_flow_max_resume_attempts5Max execution attempts for one run before final failure.

When a run pauses at a checkpoint, continue it with:

approve <new_request_id>
# or with additional guidance:
approve <new_request_id> <extra instructions>

File Attachments

Allow the AI to read files sent as iMessage attachments.

VariableDefaultDescription
apple_flow_enable_attachmentsfalseEnable reading inbound file attachments.
apple_flow_max_attachment_size_mb10Maximum attachment size to process (MB).
apple_flow_attachment_temp_dir/tmp/apple_flow_attachmentsTemporary directory for attachment processing.

Agent Office

Path to the companion's personality file. Injected as companion/system context for supported stateless connectors when enable_companion=true.

VariableDefaultDescription
apple_flow_soul_fileagent-office/SOUL.mdPath to SOUL.md injected into connector prompts. Relative paths are resolved from the repo root.

Run cd agent-office && bash setup.sh once after cloning to scaffold the workspace directory.


Companion Layer

A proactive companion loop that observes stale approvals, upcoming calendar events, overdue reminders, and office inbox items, synthesizes them with AI, and sends proactive iMessages. All companion features are disabled by default.

VariableDefaultDescription
apple_flow_enable_companionfalseEnable the CompanionLoop proactive observation loop.
apple_flow_companion_poll_interval_seconds300How often the companion checks for new observations (seconds).
apple_flow_companion_max_proactive_per_hour4Maximum proactive iMessages sent per hour (rate limit).
apple_flow_companion_quiet_hours_start22:00Start of quiet hours — no proactive messages sent during this window.
apple_flow_companion_quiet_hours_end07:00End of quiet hours.
apple_flow_companion_stale_approval_minutes30Minutes before a pending approval is flagged as stale.
apple_flow_companion_calendar_lookahead_minutes60How far ahead to look for upcoming calendar events.
apple_flow_companion_enable_daily_digestfalseWrite a daily digest note to agent-office/10_daily/YYYY-MM-DD.md.
apple_flow_companion_digest_time08:00Time of day to generate the daily digest (24-hour format).
apple_flow_companion_weekly_review_daysundayDay of week for the weekly review.
apple_flow_companion_weekly_review_time20:00Time of day for the weekly review (24-hour format).

Control the companion from iMessage:

  • system: mute — silence all proactive messages
  • system: unmute — re-enable proactive messages

Minimal config to enable:

apple_flow_enable_companion=true

Memory

Inject durable memory from agent-office/MEMORY.md and topic files in agent-office/60_memory/ into every AI prompt.

VariableDefaultDescription
apple_flow_enable_memoryfalseInject FileMemory into AI prompts before each turn.
apple_flow_memory_max_context_chars2000Maximum characters of memory content to inject per turn. Oldest entries are trimmed first.

Follow-Up Scheduler

Automatically schedule follow-up nudges after task completions, stored in the scheduled_actions SQLite table.

VariableDefaultDescription
apple_flow_enable_follow_upsfalseEnable time-triggered follow-up messages after task completions.
apple_flow_default_follow_up_hours2.0Default delay (hours) before the first follow-up is sent.
apple_flow_max_follow_up_nudges3Maximum number of follow-up messages per task before giving up.

Ambient Scanner

Passively reads Notes, Calendar, and Mail every N minutes and writes enriched summaries to memory topic files. Never sends messages.

VariableDefaultDescription
apple_flow_enable_ambient_scanningfalseEnable the AmbientScanner background context enrichment loop.
apple_flow_ambient_scan_interval_seconds900How often to scan for new context (seconds). Default is 15 minutes.

Recommended Safe Defaults

For production use, keep these values:

apple_flow_process_historical_on_first_start=false
apple_flow_notify_blocked_senders=false
apple_flow_notify_rate_limited_senders=false
apple_flow_only_poll_allowed_senders=true
apple_flow_require_chat_prefix=false   # natural language mode (no prefix needed)
apple_flow_chat_prefix=relay:

Full Example .env

# --- Required ---
apple_flow_allowed_senders=+15551234567
apple_flow_allowed_workspaces=/Users/yourname/code
apple_flow_default_workspace=/Users/yourname/code/my-project

# --- Connector ---
apple_flow_connector=claude-cli
apple_flow_claude_cli_model=claude-sonnet-4-6
apple_flow_claude_cli_dangerously_skip_permissions=true

# --- Safety ---
apple_flow_only_poll_allowed_senders=true
apple_flow_require_chat_prefix=false
apple_flow_process_historical_on_first_start=false
apple_flow_notify_blocked_senders=false
apple_flow_notify_rate_limited_senders=false

# --- Behavior ---
apple_flow_send_startup_intro=true
apple_flow_auto_context_messages=10
apple_flow_codex_turn_timeout_seconds=300

See .env.example for a complete annotated file with every option.