ppl for AI agents

ppl is a personal CRM designed to be used by AI agents on behalf of their human. Your human's relationships, notes, journal, tasks, and reminders live here. You read from it before acting, and you write to it after acting.

Connect your AI in 30 seconds

Are you the human? Pick your AI below, paste your token, copy the config. Done.

Step 1: Get your token. Open the MCP setup wizard (logged in) to generate one, or create a scoped key under Settings > API.

Step 2: Paste it here (stays in your browser, never sent anywhere):

Step 3: Pick your AI and copy the config:

Claude Desktop / Claude Code: paste this into your MCP config (claude_desktop_config.json, or run claude mcp add):

{
  "mcpServers": {
    "ppl": {
      "url": "https://ppl.gift/mcp",
      "headers": { "Authorization": "Bearer YOUR_PPL_TOKEN" }
    }
  }
}

1 Connect to your human's ppl

You initiate the connection. Your human approves once in their browser. No signup forms for you to fill, no API keys to copy and paste.

  1. Request a connection:
    POST https://ppl.gift/api/agent/connect/request
    Content-Type: application/json
    
    {
      "client_name": "Claude",
      "redirect_uri": "https://your-app.example/connected"
    }
    The response gives you an approve_url and a poll_url:
    {
      "data": {
        "id": 42,
        "connect_code": "abc123...",
        "approve_url": "https://ppl.gift/c/abc123...",
        "poll_url": "https://ppl.gift/api/agent/connect/42/status",
        "expires_at": "2026-10-01T14:50:00+00:00",
        "instructions": "Show the approve_url to your human..."
      }
    }
  2. Show the approve_url to your human. They open it, sign up or log in if needed, and click Approve. The request expires after 15 minutes.
  3. Poll the poll_url until the status is approved:
    {
      "data": {
        "id": 42,
        "status": "approved",
        "api_token": "ppl_live_...",
        "base_url": "https://ppl.gift",
        "mcp_url": "https://ppl.gift/mcp"
      }
    }
    The token is revealed exactly once. Save it immediately. Later polls return approved without the token.

If the human denies, the status becomes denied. If the 15 minutes pass, it becomes expired; just start a new request.

2 Use the hosted MCP

Connect to our hosted MCP endpoint. Nothing to install, nothing to self-host.

POST https://ppl.gift/mcp
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json

{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}

It speaks JSON-RPC 2.0 over Streamable HTTP and exposes 55 tools, grouped here:

Machine-readable spec: /.well-known/ppl.json

3 The agent loop

Use ppl like this:

  1. Before acting: call get_next_action or get_briefing to see who needs attention.
  2. Before answering about someone: call get_person_digest or ask_memory so you answer from real data, not guesses.
  3. After any interaction: call log_interaction with who, what, and when. The response tells you if the relationship status changed.
  4. Stay current: subscribe to the relationship.status_changed webhook to get pushed when someone drifts.

Human? Want your AI to do this automatically without being asked? Read the Memory Sync Guide: it has a copy-paste system prompt snippet for Claude, Grok, ChatGPT, and Cursor that makes your AI check ppl before every people-related task.

4 The magic moment: zero-input onboarding

After connecting, don't ask your human to enter contacts. Run the onboarding pipeline instead. It scans their Gmail, creates contacts for new correspondents, enriches them, and generates a "who needs attention" briefing. The human does nothing.

POST /api/agent/onboard/start
# => { "data": { "id": 1, "status": "discovering", "progress": 0 } }

GET /api/agent/onboard/1/status
# => { "data": { "status": "analyzing", "progress": 65,
#      "stats": { "contacts_found": 47, "contacts_created": 32,
#                 "contacts_enriched": 28, "insights_ready": 5 } } }

GET /api/agent/onboard/1/briefing
# => { "data": {
#   "headline": "I've mapped 47 people from your email, 3 need your attention.",
#   "message": "I went through your recent email and added 32 new people
#     to your contacts. You didn't have to enter anything. Here's who
#     needs you most: Haven't talked to Sarah in 90 days, and her
#     birthday is Friday. Send a birthday message.",
#   "needs_attention": [
#     { "name": "Sarah Chen",
#       "reason": "Haven't talked to Sarah in 90 days, and her birthday is Friday.",
#       "suggested_action": "Send a birthday message" }
#   ],
#   "recently_active": [ ... ],
#   "stats": { "total_contacts": 47, ... } } }

If Google isn't connected yet, start returns {"status": "needs_google"} and the briefing explains how to connect it. The agent should guide the human to Settings, then retry.

Present the briefing's headline and message to your human. That's the moment ppl clicks: their CRM filled itself.

Proactive alerts

ppl pushes to your agent without being asked. Two channels:

  1. Daily briefing (agent.briefing): every morning, ppl POSTs the full briefing payload (birthdays, reconnect candidates, overdue tasks, reminders) to the Agent webhook URL in Settings > Digest. Set it to your agent's inbound endpoint.
  2. Event webhooks: subscribe via POST /api/webhooks with {"url": "https://your-agent.example.com/ppl-events", "events": [...]}. Available events:
    • contact.birthday_tomorrow - someone's birthday is tomorrow
    • contact.gone_cold - no interaction in 45+ days (weekly)
    • reminder.due - a reminder is due today
    • task.overdue - a task is overdue (weekly)
    • relationship.status_changed - a relationship status changed

Every event payload includes a suggested_nudge: a human-readable message your agent can forward directly. Example:

{
  "event": "contact.birthday_tomorrow",
  "contact_id": 687400,
  "name": "Sarah Chen",
  "birthday": "2026-10-02",
  "suggested_nudge": "Heads up: Sarah Chen's birthday is tomorrow. Want me to draft a message?"
}

The pattern: receive webhook, surface the suggested_nudge to your human, offer to act. That's the proactive agent experience.

REST API

Prefer raw HTTP? All requests use Authorization: Bearer YOUR_API_KEY against https://ppl.gift/api. Key endpoints:

EndpointWhat it does
GET /api/agent/briefingMorning briefing: birthdays, reconnects, overdue tasks
GET /api/agent/next-actionThe single highest-leverage action right now, with a drafted message
POST /api/agent/askAsk a natural language question about your human's people
GET /api/search/semantic?q=Semantic search over contacts, notes, and journal
GET /api/contacts/{id}/digestEverything known about one person, one call
GET /api/agent/actionsSuggested actions feed
POST /api/interactions/logLog that an interaction happened; returns relationship impact
GET /api/agent/inboxClaimable work queue for background agents

Scopes

Tokens minted through the connect flow carry these scopes: agent:briefing, agent:actions, agent:search, read:contacts, write:contacts, read:journal, write:journal, read:tasks, write:tasks. Your human can revoke access anytime from Settings > API.

Pricing

Free during beta (1,000 contacts). Pro at $8/month planned for unlimited contacts and agent features.

No app needed

ppl has no mobile app. On iPhone, the Shortcuts pack talks straight to this API, and your human can run all of it through Siri.

Advanced: manual setup

If you cannot use the connect flow (for example, a headless environment with no human in the loop), your human can create a scoped API key manually under Settings > API and paste it to you. The in-app MCP setup wizard also generates configs for running your own MCP client against the API.

Self-hosting via Docker is available for developers who want to run their own instance, but agents should use the hosted service at ppl.gift: it is always on, always updated, and backed up.

← Back to ppl.gift