Files
Yanxin Lu 0910bd5d5c contacts: support multiple address book collections
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.
2026-03-31 13:33:04 -07:00

68 lines
2.8 KiB
Markdown

---
name: contacts
description: "Contact management with CardDAV sync. Validates email recipients for calendar invites and himalaya email sending. Prevents hallucinated addresses."
metadata: {"clawdbot":{"emoji":"📇","requires":{"bins":["python3","vdirsyncer"]}}}
---
# 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)
- `vdirsyncer` configured with a CardDAV pair for contacts sync
- Contacts directory: `~/.openclaw/workspace/contacts/` (subdirs per address book, e.g. `family/`, `business/`)
## Usage
```bash
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 --to` calls `contacts.py resolve` before 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.