A church scheduling and communication management tool designed to run in Termux on Android, with desktop development support.
- Prayer Scheduling: Schedule opening and closing prayers for sacrament meetings
- Fair Rotation: Automatically tracks last prayer dates to ensure fair rotation
- Multi-Week Planning: Plan multiple weeks in advance with active queue
- SMS Integration: Generate SMS messages via Android intents (Termux)
- Appointment Scheduling: Schedule appointments with members (Temple Recommend, Youth Interviews, Callings, etc.)
- Configurable Types: Fully customizable appointment types with default durations
- State Workflow: Track appointments through Draft → Invited → Reminded → Completed
- Conductor Assignment: Separate appointments for Bishop and Counselor
- Auto-Sync: Appointments automatically sync to Google Calendar
- Separate Calendars: Bishop and Counselor appointments in different calendars
- State Indicators: Visual indicators for appointment states in calendar
- Smart Deletion: Preserves completed appointments as history
- Manual Sync: Optional manual sync button for troubleshooting
- Household Management: Track family relationships and household groupings
- Parent Routing for Minors: SMS messages to youth automatically route to parents
- Smart Member Import: Import member data and household relationships from church exports
- Member Profiles: Detailed member info with prayer history, appointment history, and household links
- SMS Integration: Generate SMS messages via Android intents (Termux)
- Smart Templates: Powerful template system with conditional logic and random variations
- Parent Templates: Automatic template selection for minors with parent-friendly messaging
- Template Variables: Support for formal/casual greetings, smart dates, and custom variables
- Mobile-First UI: Touch-friendly, responsive interface optimized for phone use
- CSV-Based Data: Simple, editable data storage with no database required
- Timezone Support: Proper UTC/local timezone handling for appointments
-
Clone the repository:
cd /home/nlod/claude/mls3 -
Create virtual environment and install dependencies:
python3 -m venv venv source venv/bin/activate pip install -r requirements.txt -
Run the application:
python app.py
-
Open in browser: Navigate to
http://localhost:5000
-
Install Termux and Termux:API from F-Droid
-
Install Python and dependencies:
pkg install python pkg install termux-api
-
Clone repository:
cd ~/storage/shared git clone <repository-url> mls3 cd mls3
-
Create virtual environment:
python -m venv venv source venv/bin/activate pip install -r requirements.txt -
Set up production data directory:
mkdir -p ~/mls3-data export MLS3_DATA_DIR=~/mls3-data
-
Copy initial data files:
cp data/*.example.csv ~/mls3-data/ cp data/message_templates.yaml ~/mls3-data/ cp data/appointment_types.yaml ~/mls3-data/ # Rename example files cd ~/mls3-data mv members.example.csv members.csv mv prayer_assignments.example.csv prayer_assignments.csv
-
(Optional) Set up Google Calendar integration: See docs/GOOGLE_CALENDAR_SETUP.md for complete instructions.
# Enable Google Calendar export MLS3_GOOGLE_CALENDAR=true export BISHOP_CALENDAR_ID="your_bishop_calendar_id" export COUNSELOR_CALENDAR_ID="your_counselor_calendar_id"
-
Run the application:
cd ~/storage/shared/mls3 source venv/bin/activate export MLS3_DATA_DIR=~/mls3-data python app.py
-
Open in browser:
termux-open-url http://localhost:5000
- Code (in git): All application code, mock data for development
- Production Data (outside git): Real member data stored separately, never committed
The system uses six main data files:
- members.csv - Member database with names, phone numbers, prayer history, household assignments
- households.csv - Household groupings and family relationships
- prayer_assignments.csv - All prayer assignments (past, present, future)
- appointments.csv - Appointment tracking database
- message_templates.yaml - Customizable SMS message templates
- appointment_types.yaml - Configurable appointment types with default durations
By default, the app uses mock data from ./data/:
python app.py
# Uses ./data/members.example.csv (automatically copied to members.csv)Set the MLS3_DATA_DIR environment variable:
export MLS3_DATA_DIR=/home/nlod/mls3-data
python app.py
# Uses /home/nlod/mls3-data/members.csvThe Import page reads the two reports printed from the church website, so nothing depends on which browser copied the text.
Print both to PDF and save them to the phone:
- the member list — default columns are fine; the Address column is not needed
- the household report — the one with a Household Members column
Then open Import, choose both files (either order — they're identified automatically), review the summary, and confirm. A full backup is taken before anything is written, and the same page restores it.
The household report is what supplies household structure and, from its indentation, who is a head of household versus a dependent. The member list alone cannot tell you that.
Two separate flags, deliberately kept apart:
in_wardis owned by the import. Present in the reports means in the ward; absent means they have moved away. Anyone out of the ward disappears from the app entirely - not a filter you can toggle, just gone - while their row, prayer history, notes and flags all stay put.activeis yours, set from the Members page. It means church-active and worth scheduling. An import never writes it.
That separation is what makes the common case work: someone who stops attending, moves out of the ward, and later moves back comes back exactly as you last judged them, rather than being quietly reinstated. Equally, someone who stops attending while still living in the boundaries stays visible and simply isn't offered as a candidate.
Household relationships - who a minor's parents are - follow in_ward, not
active. Whether a parent attends church has nothing to do with whether they are
the person to text about their child.
Prayer history, dont_ask_prayer, notes, flags, AKA and skip-until are never
overwritten by an import. Neither is anything the reports leave blank: if someone
has no phone on the report but you tracked one down yourself, yours is kept. The
same goes for household phones and addresses.
Phone numbers are normalised to 801-419-2648 rather than the report's
(801) 419-2648, because brackets and spaces have to be percent-encoded in an
SMS link, and because otherwise every number in the ward would appear to change
on the first import.
Requires pdftotext (Termux: pkg install poppler). Also available from the
command line:
python utils/pdf_import.py member-list.pdf household-report.pdf # preview
python utils/pdf_import.py member-list.pdf household-report.pdf --apply # importThe import utility supports multiple modes for managing member data:
Download tab-separated data from your church website with these columns:
- Name (format: "Last, First")
- Gender (M or F)
- Birth Date (format: "5 Dec 1953")
- Phone Number (format: "801-555-1234")
# Import members (updates existing, adds new)
python utils/import_members.py church_export.tsv
# Preview changes without saving
python utils/import_members.py church_export.tsv --dry-run
# Mark members in import as active, others as inactive (sync mode)
python utils/import_members.py church_export.tsv --activate-present --deactivate-absentTab-separated file with columns: Last Name, Adults (semicolon-separated), Children (semicolon-separated)
# Import household relationships
python utils/import_households.py households.tsv
# Preview changes without saving
python utils/import_households.py households.tsv --dry-runTab-separated file with columns: Name, Prayed
python utils/import_members.py --update-prayed prayer_history.tsvTab-separated file with single Name column:
# Mark members as shy (don't ask for prayers)
python utils/import_members.py --shy shy_list.tsv
# Re-enable members for prayer assignments
python utils/import_members.py --not-shy can_ask_list.tsvSee data/sample_*.tsv for example file formats.
Your production data directory should be backed up regularly:
# Manual backup
cp -r ~/mls3-data ~/mls3-data-backup-$(date +%Y%m%d)
# Or sync to cloud storage
cp -r ~/mls3-data ~/storage/shared/Dropbox/mls3-backup/mls3/
├── app.py # Flask application entry point
├── models.py # Data models (Member, PrayerAssignment, Appointment)
├── config.py # Configuration settings
├── requirements.txt # Python dependencies
├── authorize_google_calendar.py # OAuth setup for Google Calendar
├── templates/ # HTML templates
│ ├── base.html
│ ├── index.html
│ ├── prayer_scheduler.html
│ ├── appointment_scheduler.html
│ ├── events.html
│ ├── members_list.html
│ └── sms_composer.html
├── static/
│ ├── css/
│ │ └── style.css # Mobile-responsive styles
│ └── js/
│ ├── appointment_scheduler.js
│ ├── events.js
│ └── home.js
├── data/ # Mock data (committed to git)
│ ├── members.example.csv
│ ├── prayer_assignments.example.csv
│ ├── message_templates.yaml
│ └── appointment_types.yaml
├── utils/ # Utility scripts
│ ├── import_members.py
│ ├── import_households.py
│ ├── candidate_selector.py
│ ├── sms_handler.py
│ ├── template_expander.py
│ └── google_calendar.py # Google Calendar integration
└── docs/ # Documentation
├── DEPLOYMENT.md
├── TESTING.md
├── GOOGLE_CALENDAR_SETUP.md
└── mls-master-plan.md
Edit config.py or use environment variables:
MLS3_DATA_DIR- Path to data directory (default:./data)MLS3_TIMEZONE- The ward's timezone: the UI and texts always show times here, wherever the phone is (default:America/Denver)FLASK_DEBUG- Enable debug mode (default:True)FLASK_HOST- Host address (default:127.0.0.1)FLASK_PORT- Port number (default:5000)SECRET_KEY- Flask secret key (change in production)
MLS3_DEBUG_SMS- Debug mode (prints SMS instead of sending, default:false)MLS3_DISABLE_SMS- Disable SMS completely (default:false)
MLS3_GOOGLE_CALENDAR- Enable Google Calendar sync (default:false)BISHOP_CALENDAR_ID- Google Calendar ID for Bishop appointmentsCOUNSELOR_CALENDAR_ID- Google Calendar ID for Counselor appointments
- ✅ Core Infrastructure
- ✅ Member Database & Import
- ✅ Prayer Scheduler UI
- ✅ Candidate Selection Algorithm
- ✅ SMS Integration
- ✅ State Management & Workflow
- ✅ Active Queue & Multi-Week Support
- ✅ Mobile Optimization & Polish
- ✅ Documentation & Deployment
- ✅ Appointment data model with UTC timezone support
- ✅ Appointment types (Temple Recommend, Youth Interviews, Callings, etc.)
- ✅ Appointment scheduler UI with state workflow
- ✅ Google Calendar integration with OAuth
- ✅ Separate Bishop/Counselor calendars
- ✅ Auto-sync on create/update/delete/state change
- ✅ Smart deletion (preserves completed appointments)
- ✅ Manual sync button
- ✅ Timezone bug fixes and proper UTC/local handling
- ✅ Mobile-optimized calendar event colors
- ✅ Household data model and import utility
- ✅ Parent/child relationship tracking
- ✅ Automatic SMS routing to parents for minors
- ✅ Parent-specific message templates
- ✅ Household view in member modal
- ✅ Visual indicators for minors (red age display)
- ✅ Group SMS support (multiple parents)
- Conductor completion links in calendar events
- Google Sheet integration for clerk reports
- Self-service reporting without MLS3 access
Ready to Use:
- Full prayer scheduling workflow
- Full appointment scheduling workflow
- Household management and parent routing
- Fair rotation candidate selection
- SMS invitations and reminders with parent templates
- Multi-week prayer planning with active queue
- Google Calendar integration (optional)
- Mobile-optimized interface
- Termux deployment support
source venv/bin/activate
# Enable SMS debug mode (skips actual SMS sending, prints to console)
export MLS3_DEBUG_SMS=true
# Optional: Enable Google Calendar (requires setup)
export MLS3_GOOGLE_CALENDAR=true
python app.pyAccess at http://localhost:5000
SMS Debug Mode: When MLS3_DEBUG_SMS=true, clicking Invite or Remind buttons will:
- Skip opening the SMS app
- Print the message to console instead
- Still update the assignment/appointment state as if sent
- Great for testing on desktop without Termux
/- Homepage with system overview/members- List of all active members/prayer-scheduler- Prayer scheduling interface/appointment-scheduler- Appointment scheduling interface/events- Calendar view of all events/sms-composer- Standalone SMS message composer/api/members/search?q=<query>- Search members API/api/appointments/...- Appointment management API/api/prayers/...- Prayer assignment API
See docs/mls-master-plan.md for detailed development roadmap and architecture.
Private project for personal church use.
- docs/DEPLOYMENT.md - Complete Termux deployment guide
- docs/DATA-SAFETY.md - How the data files are protected, and what to do if something looks wrong
- docs/TESTING.md - Testing checklist for verification
- docs/GOOGLE_CALENDAR_SETUP.md - Google Calendar integration setup
- docs/COMPLETION_TRACKING_PLAN.md - Future: Completion tracking system
- docs/mls-master-plan.md - System architecture and design
- README.md - This file (quick start guide)
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
export MLS3_DEBUG_SMS=true
python app.pySee docs/DEPLOYMENT.md for complete setup guide.
Quick start:
cd ~/storage/shared/mls3
export MLS3_DATA_DIR=~/mls3-data
./start.shSee docs/GOOGLE_CALENDAR_SETUP.md for complete setup guide.
- Deployment Issues: See docs/DEPLOYMENT.md
- Testing: See docs/TESTING.md
- Google Calendar: See docs/GOOGLE_CALENDAR_SETUP.md
- Architecture: See docs/mls-master-plan.md
- Questions: Create an issue in the repository