CRM Skill — Contact Memory for Voice Calls
Stores local, operator-reviewed caller context and interaction history for phone follow-up.
How It Works
On Every Inbound Call
- Lookup — Call
crm with lookup_contact using the caller's phone number (from Twilio caller ID) only under the operator's caller notice/consent and retention policy.
- If known — Greet by name and use
context_notes only when relevant to the call purpose. Avoid surprising rapport-building from intimate or unnecessary details.
- If unknown — Proceed normally, listen for their name.
During the Call
When someone shares their name, email, company, or relevant follow-up details, upsert it via crm.upsert_contact only if that fits the operator's caller notice/consent and retention policy. Avoid collecting sensitive or unnecessary personal details.
At End of Call
- Log the interaction:
log_interaction with summary + outcome
- Update context_notes with concise, relevant follow-up context, synthesizing with what was known before
On Outbound Calls
Same exact flow: lookup at start, upsert + log_interaction at end.
API Reference
| Action |
Purpose |
lookup_contact |
Fetch contact + last 5 interactions + context_notes. Returns null if not found. |
upsert_contact |
Create or update a contact by phone. Only provided fields are updated. |
log_interaction |
Log a call: summary, outcome, details. Auto-creates contact if needed. |
get_history |
Get past interactions for a contact (sorted newest-first). |
search_contacts |
Search by name, email, company, notes. |
tag_contact |
Add/remove tags (e.g. "vip", "callback_later"). |
Privacy
- Event details stay private. Like the calendar skill, never disclose event details to callers.
- CRM context is personal. The
context_notes field is for Amber's internal memory, not for sharing call transcripts. Use it to inform conversation, not to recite it.
- PII storage. Phone, name, email, company, context_notes, call summaries, and interaction metadata are stored locally in SQLite. Operators must provide appropriate caller notice/consent and retention/deletion practices. No network transmission, no external CRM by default.
- Review and correction. Operators should periodically review, correct, or delete CRM entries so inaccurate transcript extraction or overly sensitive details do not persist.
Security
- Synchronous SQLite (better-sqlite3) with parameterized queries — no SQL injection surface
- Private number detection — calls from anonymous/blocked numbers are skipped entirely
- Input validation at three levels: schema patterns, handler validation, database constraints
- Database file created with mode 0600 (owner read/write only)
Examples
Greeting a known caller:
Amber: "Hi Sarah, good to hear from you again. I have you down as preferring afternoon callbacks."
[context_notes remembered: "Prefers afternoon callbacks for appointment changes."]
Capturing relevant follow-up context:
Caller: "By the way, I got married last month!"
Amber: [only records this if it is relevant and appropriate under the operator's retention policy]
Amber (aloud): "That's wonderful! Congrats!"
End-of-call log:
Amber: [calls log_interaction: summary="Called to reschedule Friday appointment", outcome="appointment_booked"]
Amber: [calls upsert_contact with context_notes: "Prefers afternoon callbacks. Usually calls to reschedule appointments."]
1---2name: crm3description: Local contact memory and interaction log for operator-reviewed phone follow-up4---56# CRM Skill — Contact Memory for Voice Calls78Stores local, operator-reviewed caller context and interaction history for phone follow-up.910## How It Works1112### On Every Inbound Call13141. **Lookup** — Call `crm` with `lookup_contact` using the caller's phone number (from Twilio caller ID) only under the operator's caller notice/consent and retention policy.152. **If known** — Greet by name and use `context_notes` only when relevant to the call purpose. Avoid surprising rapport-building from intimate or unnecessary details.163. **If unknown** — Proceed normally, listen for their name.1718### During the Call1920When someone shares their name, email, company, or relevant follow-up details, upsert it via `crm.upsert_contact` only if that fits the operator's caller notice/consent and retention policy. Avoid collecting sensitive or unnecessary personal details.2122### At End of Call23241. Log the interaction: `log_interaction` with summary + outcome252. Update context_notes with concise, relevant follow-up context, synthesizing with what was known before2627### On Outbound Calls2829Same exact flow: lookup at start, upsert + log_interaction at end.3031## API Reference3233| Action | Purpose |34|--------|---------|35| `lookup_contact` | Fetch contact + last 5 interactions + context_notes. Returns null if not found. |36| `upsert_contact` | Create or update a contact by phone. Only provided fields are updated. |37| `log_interaction` | Log a call: summary, outcome, details. Auto-creates contact if needed. |38| `get_history` | Get past interactions for a contact (sorted newest-first). |39| `search_contacts` | Search by name, email, company, notes. |40| `tag_contact` | Add/remove tags (e.g. "vip", "callback_later"). |4142## Privacy4344- **Event details stay private.** Like the calendar skill, never disclose event details to callers.45- **CRM context is personal.** The `context_notes` field is for Amber's internal memory, not for sharing call transcripts. Use it to inform conversation, not to recite it.46- **PII storage.** Phone, name, email, company, context_notes, call summaries, and interaction metadata are stored locally in SQLite. Operators must provide appropriate caller notice/consent and retention/deletion practices. No network transmission, no external CRM by default.47- **Review and correction.** Operators should periodically review, correct, or delete CRM entries so inaccurate transcript extraction or overly sensitive details do not persist.4849## Security5051- Synchronous SQLite (better-sqlite3) with parameterized queries — no SQL injection surface52- Private number detection — calls from anonymous/blocked numbers are skipped entirely53- Input validation at three levels: schema patterns, handler validation, database constraints54- Database file created with mode 0600 (owner read/write only)5556## Examples5758**Greeting a known caller:**59```60Amber: "Hi Sarah, good to hear from you again. I have you down as preferring afternoon callbacks."61[context_notes remembered: "Prefers afternoon callbacks for appointment changes."]62```6364**Capturing relevant follow-up context:**65```66Caller: "By the way, I got married last month!"67Amber: [only records this if it is relevant and appropriate under the operator's retention policy]68Amber (aloud): "That's wonderful! Congrats!"69```7071**End-of-call log:**72```73Amber: [calls log_interaction: summary="Called to reschedule Friday appointment", outcome="appointment_booked"]74Amber: [calls upsert_contact with context_notes: "Prefers afternoon callbacks. Usually calls to reschedule appointments."]75```