Skip to main content
What is this? A concrete recipe for an AI-powered personal CRM. Your agent watches Gmail / Calendar / Slack, logs who you talked to and what about, surfaces people you haven’t reached out to in a while, and drafts follow-ups — all backed by Salty.

The scenario

You meet 50+ new people a year — at conferences, intro emails, calls. Six months later you remember vaguely “the one who worked at Stripe and was into game design” but can’t reconstruct context. A traditional CRM is too heavyweight for personal use. A note-taking app loses the structure. Salty sits between them: structured enough to query (“who at fintech companies haven’t I talked to in 3 months?”), light enough to maintain by talking to an LLM.

Data model

Salty objectYour concept
personSomeone in your network
companyWhere they work (optional)
noteFree-form context: “met at OpenAI dinner Nov 2026, building voice agents”
activityEach meeting, call, email exchange
task”Follow up by Friday” (REST/CLI — no MCP write tool in v1)
custom_attributes on persontier (1/2/3), last_contact_at, interests

Set up the schema

# tier — who matters most
curl -X POST $SALTY_API/schema/person/attributes \
  -H "Authorization: Bearer $SALTY_API_KEY" \
  -d '{"attribute_key":"tier","display_name":"Tier","data_type":"enum",
       "enum_values":["1","2","3"]}'

# interests — comma-separated tags you want to filter on
curl -X POST $SALTY_API/schema/person/attributes \
  -H "Authorization: Bearer $SALTY_API_KEY" \
  -d '{"attribute_key":"interests","display_name":"Interests","data_type":"text"}'

# how you met — useful for context
curl -X POST $SALTY_API/schema/person/attributes \
  -H "Authorization: Bearer $SALTY_API_KEY" \
  -d '{"attribute_key":"met_via","display_name":"Met via","data_type":"text"}'

What the agent does

When you meet someone new

You say to Claude Desktop:
“I just met Priya Mehta at the OpenAI dinner — she’s building voice agents at a YC company. Tier 2. Add her.”
Claude calls:
  1. create_person with email (if you provided), first_name: "Priya", last_name: "Mehta", custom_attributes: {tier: "2", interests: "voice-agents", met_via: "OpenAI dinner 2026-05-23"}
  2. add_note parent: person, body: “Met at OpenAI dinner, building voice agents at a YC company”
Two calls, one prompt, no clicking.

After every call or meeting

“Log a 30-min call with Priya today about her early traction with B2B.”
Claude calls:
  1. search_people with {filter: {first_name: "Priya"}} → get her id
  2. log_activity with parent_object_type: "person", parent_object_id: <id>, activity_type: "call", occurred_at: <ISO-8601 in your timezone>, payload: {topic: "early B2B traction", duration_min: 30}

Weekly surfacing — “who am I forgetting”

“Show me everyone in tier 1 or 2 I haven’t talked to in 60 days.”
Claude calls search_people + search_activities + filters by occurred_at, ranks the list. You get a 12-name action list every Monday.

Driving it without MCP — your own script

A nightly cron job that updates last_contact_at from Calendar events:
import { Salty } from '@salty/sdk';
import { getCalendarEventsToday } from './gcal';

const salty = new Salty({ apiKey: process.env.SALTY_API_KEY! });

for (const event of await getCalendarEventsToday()) {
  for (const attendeeEmail of event.attendees) {
    // Find or create the person
    const search = await salty.people.searchPeople({
      query: { filter: JSON.stringify({ email: attendeeEmail }) }
    });
    const person = search.data.data[0] ?? (await salty.people.postPeople({
      body: { email: attendeeEmail }
    })).data;

    // Log the activity
    await salty.activities.postActivities({
      body: {
        parent_object_type: 'person',
        parent_object_id: person.id,
        activity_type: 'meeting',
        occurred_at: event.start.dateTime,   // ISO-8601 with offset works
        payload: { topic: event.summary, calendar_event_id: event.id },
      },
    });

    // Update last_contact_at
    await salty.people.patchPeopleById({
      path: { id: person.id },
      body: { custom_attributes: { last_contact_at: event.start.dateTime } },
    });
  }
}

Volume guidance

A heavy networker who meets 5 new people a week + logs 20 meetings a week makes ~5,000 API calls/month — comfortably inside Solo ($20/mo, 100k calls). Free (500 calls/mo) is fine to demo the platform, but it also blocks custom attributes and webhooks, which the pattern above leans on. Personal CRM at any real cadence runs on Solo.

Why not just Notion / Apple Notes / Airtable?

NeedNotion / NotesAirtableSalty
Query “tier 1 + fintech + not contacted in 3 months”hardyesyes
Add a structured custom field without leaving the conversationnoAPI limitsadd_attribute then write
LLM agent can write directly via OAuthnoAPI keyOAuth 2.1 + PKCE
Receive a webhook on every changenoyes (limited)yes (signed, retried)
Cost at 1k people$$ + tab clutter$20+ per editor$0 (free tier)