Migadu exposes "family" and "business" address books via CardDAV. The contacts script now searches all subdirs under contacts/ and adds new contacts to the "family" collection by default.
2.8 KiB
name, description, metadata
| name | description | metadata | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| contacts | Contact management with CardDAV sync. Validates email recipients for calendar invites and himalaya email sending. Prevents hallucinated addresses. |
|
Contacts
Manage a local vCard contact list synced to Migadu CardDAV via vdirsyncer. Used by the calendar tool and himalaya wrapper to validate recipient addresses before sending.
Why This Exists
LLMs can hallucinate email addresses — inventing plausible-looking addresses from context instead of looking up the correct one. This contact list serves as a tool-level allowlist: outbound emails can only go to addresses that exist in the contacts.
Adding contacts and sending emails are separate operations. Never add a contact and send to it in the same request.
Prerequisites
- Python 3 (no external dependencies)
vdirsyncerconfigured with a CardDAV pair for contacts sync- Contacts directory:
~/.openclaw/workspace/contacts/(subdirs per address book, e.g.family/,business/)
Usage
SKILL_DIR=~/.openclaw/workspace/skills/contacts
# List all contacts
$SKILL_DIR/scripts/contacts.sh list
# Add a contact (single email)
$SKILL_DIR/scripts/contacts.sh add --name "小鹿" --email "mail@luyx.org"
# Add with email type and nickname
$SKILL_DIR/scripts/contacts.sh add --name "小橘子" --email "Erica.Jiang@anderson.ucla.edu" --type work --nickname "小橘子"
# Add a second email to an existing contact
$SKILL_DIR/scripts/contacts.sh add --name "小橘子" --email "xueweijiang0313@gmail.com" --type home
# Resolve a name to email address (used by other tools)
$SKILL_DIR/scripts/contacts.sh resolve "小橘子:work"
# Output: Erica.Jiang@anderson.ucla.edu
# Delete a contact
$SKILL_DIR/scripts/contacts.sh delete --name "小橘子"
Resolve Formats
The resolve command accepts three formats:
| Format | Example | Behavior |
|---|---|---|
| Name | 小橘子 |
Match by FN or NICKNAME. Error if multiple emails (use type). |
| Name:type | 小橘子:work |
Match by name, select email by type. |
| Raw email | user@example.com |
Accept only if the email exists in contacts. |
Unknown addresses are rejected with the available contacts list shown.
Integration
- Calendar tool (
cal_tool.py):send --tocallscontacts.py resolvebefore sending invites - Himalaya wrapper (
himalaya.sh): validates To/Cc/Bcc headers before passing to himalaya for email delivery
Data
Contacts are stored as vCard 3.0 .vcf files in ~/.openclaw/workspace/contacts/<collection>/, synced to Migadu CardDAV via vdirsyncer. Collections match Migadu address books (e.g. family/, business/). New contacts are added to family/ by default. The resolve command searches all collections.