# Crm

> Contact memory and interaction log — remembers callers across calls, logs every conversation with outcome and personal context

- Skill: `dvcrn/crm-3` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add dvcrn/crm-3`
- Raw SKILL.md: https://api.skillmd.com/api/skills/dvcrn/crm-3/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: dvcrn (https://skillmd.com/u/dvcrn)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/dvcrn/crm-3

---


# CRM Skill — Contact Memory for Voice Calls

Remembers callers across calls and logs every conversation.

## How It Works

### On Every Inbound Call

1. **Lookup** — Call `crm` with `lookup_contact` using the caller's phone number (from Twilio caller ID).
2. **If known** — Greet by name and use `context_notes` to personalize (ask about their dog, remember their preference, etc.)
3. **If unknown** — Proceed normally, listen for their name.

### During the Call

When someone shares their name, email, company, or any personal detail, silently upsert it via `crm.upsert_contact`. Don't announce this.

### At End of Call

1. Log the interaction: `log_interaction` with summary + outcome
2. Update context_notes with any new personal details learned, 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 are stored locally in SQLite. No network transmission, no external CRM by default.

## 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. How's Max doing?" 
[context_notes remembered: "Has a Golden Retriever named Max. Prefers afternoon calls."]
```

**Capturing new info silently:**
```
Caller: "By the way, I got married last month!"
Amber: [silently calls upsert_contact + updates context_notes with "Recently married"]
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 calls. Recently married. Reschedules frequently but always shows up."]
```

