Getting Started
This guide walks you through installing frm, connecting your address book, and building a daily habit of staying in touch with the people who matter.
Installation
Install with Go (requires Go 1.21 or later):
go install github.com/justinabrahms/frm@latest
Or download a prebuilt binary from the Releases page.
Verify it works:
frm --version
Setting up with frm init
The frm init wizard walks you through connecting a CardDAV
server. It supports iCloud, Fastmail, and custom CardDAV endpoints.
frm init
The wizard will prompt you to choose a provider and enter credentials.
iCloud
iCloud requires an app-specific password. Generate one at account.apple.com under Sign-In and Security → App-Specific Passwords.
The endpoint is https://contacts.icloud.com and your username
is your iCloud email address.
Fastmail
Use https://carddav.fastmail.com as the endpoint with your
Fastmail email and an app password.
Google Contacts
Use https://www.googleapis.com/.well-known/carddav as the
endpoint with your Gmail address and an app password.
Custom CardDAV
Choose "Custom URL" during init and provide your CardDAV server's endpoint. Any server that speaks the CardDAV protocol will work.
Adding JMAP for email context
After setting up CardDAV, frm will ask if you want to add a JMAP service.
JMAP provides email context during triage and in the frm context
command, showing recent emails exchanged with each contact.
Manual configuration
The config file lives at ~/.frm/config.json. You can edit it
directly instead of using the wizard. Override the directory with the
FRM_CONFIG_DIR environment variable.
{
"services": [
{
"type": "carddav",
"endpoint": "https://contacts.icloud.com",
"username": "you@icloud.com",
"password": "xxxx-xxxx-xxxx-xxxx"
}
]
}
Multiple accounts
You can configure multiple CardDAV accounts. Run frm init again
and choose "add a service" to append another account. All commands will
search across every configured account.
Your first triage session
Once connected, run frm triage to start categorizing your
contacts. For each person, frm shows their name, email, organization, and
phone number, then asks you to choose a frequency:
$ frm triage
Alice Smith
alice@example.com
Acme Corp
[m]onthly [q]uarterly [y]early [s]kip [i]gnore or frequency (e.g. 2w) [Enter=skip]>
Your options:
- m — monthly (every 30 days)
- q — quarterly (every 90 days)
- y — yearly (every 360 days)
- s or Enter — skip for now (come back later)
- i — ignore permanently (never show again)
- A custom duration like 2w (every 2 weeks) or 3d (every 3 days)
By default, triage shows 5 contacts at a time. Use --limit 20
to see more, or --limit -1 for all of them.
Duration format
frm understands three duration units:
3d— every 3 days2w— every 2 weeks1m— every month (30 days)
Daily workflow with frm check
Run frm check to see everyone who is overdue:
$ frm check
Overdue contacts:
Alice Smith (every 2w, last contact 3w ago)
Bob Jones (every 1m, never contacted)
When you reach out to someone, log the interaction:
frm log "Alice Smith" --note "caught up over coffee"
You can backdate interactions with the --when flag:
frm log "Alice Smith" --when 2026-02-15 --note "ran into her at the conference"
Pre-meeting context
Before a meeting, run frm context to see a summary of your
relationship with someone:
$ frm context "Alice Smith"
Name: Alice Smith
Group: friends
Frequency: every 2w
Last seen: 2026-02-14 (14 days ago)
Last note: caught up over coffee
Due in: 0 days
If you have JMAP configured, this also shows recent email threads.
Logging interactions
The frm log command records that you interacted with someone:
# Basic log
frm log "Alice"
# With a note about what you discussed
frm log "Alice" --note "discussed the quarterly report"
# Backdated to a specific date
frm log "Alice" --when 2026-02-01 --note "lunch meeting"
View someone's interaction history with frm history:
$ frm history "Alice"
2026-02-01 lunch meeting
2026-02-14 caught up over coffee
Groups and organization
Assign contacts to groups for organization:
# Assign a contact to a group
frm group set "Alice Smith" friends
frm group set "Bob Jones" professional
# List all groups
frm group list
# List contacts in a group
frm group members friends
# Remove from a group
frm group unset "Alice Smith"
Managing the overdue pile
Snoozing contacts
If someone is overdue but you know you will see them soon, snooze them:
# Snooze for 2 months
frm snooze "Alice" --until 2m
# Snooze until a specific date
frm snooze "Alice" --until 2026-06-01
# Remove the snooze early
frm unsnooze "Alice"
Spreading new imports
After a big import, everyone shows as overdue at once. The spread
command staggers snoozes so contacts come due gradually:
# Preview what would happen
frm spread
# Apply the spread
frm spread --apply
Viewing your dashboard
The frm stats command shows an overview of your contact tracking:
$ frm stats
Contacts: 142 total
Tracked: 45
Ignored: 80
Untriaged: 17 (12%)
Overdue: 3
Interactions: 127
Most contacted: Alice Smith (12)
Least contacted: Zara Jones (1)
Next steps
- See the Command Reference for every command and flag.
- Read the Agent Integration Guide to automate your workflow with AI agents.