Open source · MIT License

Your contacts,
in your terminal.

A local-first personal CRM that lives in the command line. Manage contacts, organizations, interactions, deals, and tasks. Built-in AI integration. No cloud required.

Get Started View on GitHub
$ brew install jdanielnd/tap/crm

Features

Everything you need.
Nothing you don't.

A complete CRM in a single binary. No sign-ups, no subscriptions, no data leaving your machine.

👤

People & Organizations

Full contact profiles linked to companies. Track names, emails, phones, titles, locations, and custom notes.

💬

Interaction Log

Record calls, emails, meetings, notes, and messages. Track direction, timestamps, and link to multiple contacts.

💰

Deals & Pipeline

Manage opportunities through stages from lead to won. Track values, associated contacts, and view pipeline summaries.

Tasks & Follow-ups

Create tasks with due dates, priorities, and person associations. Filter by overdue, completed, or open status.

🔍

Full-Text Search

Find anything instantly across all entities. Powered by SQLite FTS5 for sub-millisecond search on local data.

🤖

AI Integration

Built-in MCP server lets Claude and other AI agents read and update your CRM through a structured protocol.

🏷

Tags & Relationships

Flexible tagging on any entity. Person-to-person relationships like colleague, mentor, or referred-by.

📋

Context Briefing

One command to get everything about a contact: profile, org, interactions, deals, tasks, tags, and relationships.

📤

Multiple Output Formats

Table, JSON, CSV, or TSV. Pipe into jq, fzf, awk, or anything else. Unix-native by design.

Up and running in 30 seconds.

Install, add a contact, and you're done. No configuration, no setup wizard, no account creation.

Install

Run brew install jdanielnd/tap/crm via Homebrew. Or use go install, or download a binary from Releases.

Add your first contact

Run crm person add "Jane Smith" and you're in business. The database is auto-created at ~/.crm/crm.db.

Start tracking

Log interactions, create deals, set tasks. Everything stays local in a single SQLite file you own.

# Add a company and a contact
$ crm org add "Acme Corp" --domain acme.com
Created organization #1: Acme Corp

$ crm person add "Jane Smith" --email jane@acme.com --title "CTO" --org 1
Created person #1: Jane Smith

# Log an interaction
$ crm log call 1 --subject "Intro call — discussed roadmap"
Logged call #1 with Jane Smith

# Create a deal
$ crm deal add "Website Redesign" --value 15000 --person 1 --stage proposal
Created deal #1: Website Redesign

# Get a full briefing before your next meeting
$ crm context 1

Let AI manage your CRM.

crm ships with a built-in MCP server. Connect it to Claude or any MCP-compatible agent and let AI handle the busywork. Two steps:

1. Install crm-cli

If you haven't already, install via Homebrew or any other method from the quickstart.

$ brew install jdanielnd/tap/crm

2. Connect to Claude

Register crm as an MCP server so Claude can access your contacts, deals, and tasks:

$ claude mcp add crm -- crm mcp serve

That's it. Claude can now read and update your CRM.

After a meeting, just tell Claude:

"Had a great meeting with Jane. She'll sign the contract next week. Set a follow-up for Thursday."

Claude will automatically:

  • Log the meeting interaction
  • Update the deal stage to negotiation
  • Create a follow-up task for Thursday
  • Update Jane's summary with new context

18 tools available

crm_person_search Find contacts
crm_person_get Get person details
crm_person_create Create a person
crm_person_update Update person fields
crm_person_delete Archive a person
crm_person_relate Link two people
crm_org_search Search organizations
crm_org_get Get org details
crm_interaction_log Log an activity
crm_interaction_list List interactions
crm_deal_create Create a deal
crm_deal_update Update a deal
crm_task_create Create a task
crm_task_list List open tasks
crm_tag_apply Apply a tag
crm_search Cross-entity search
crm_context Full person briefing
crm_stats CRM summary stats

See it in action.

Real examples of how crm-cli works with Claude across different workflows.

After a conference

You met several people at a conference and want to log them before you forget.

C
Claude
I just got back from ReactConf. Met a few people I want to remember: Sarah Chen, she's a staff engineer at Vercel, we talked about server components. Also met David Park from Linear, he's their head of design. And Julia Torres, freelance consultant, she might be a great mentor — her email is julia@torres.dev
I'll add all three to your CRM and log the context from the conference.

crm_person_create Sarah Chen — Staff Engineer, Vercel
crm_person_create David Park — Head of Design, Linear
crm_person_create Julia Torres — Freelance Consultant
crm_interaction_log Note: "Met at ReactConf" for all three
crm_person_relate Julia Torres → potential mentor
crm_tag_apply "reactconf-2026" on all three

Done! All three are in your CRM, tagged with "reactconf-2026". I noted Julia as a potential mentor. Want me to set follow-up reminders?
Yes, remind me to email Sarah and David next week, and set up a coffee chat with Julia within 2 weeks.
crm_task_create "Email Sarah Chen — follow up on server components" — due Mar 14
crm_task_create "Email David Park — follow up from ReactConf" — due Mar 14
crm_task_create "Schedule coffee chat with Julia Torres" — due Mar 21, high priority

All set. Three follow-ups created. I gave the Julia one high priority since mentorship connections are valuable.

Managing a sales pipeline

Tracking deals, logging calls, and preparing for client meetings.

C
Claude
Just finished a demo call with Acme Corp. They loved the product, want to move forward with a $45k annual contract. The decision maker is Tom Bradley, their VP of Engineering. He wants a proposal by Friday.
Great news! Let me update everything.

crm_interaction_log Demo call with Tom Bradley — "Product demo, positive reception, $45k annual"
crm_deal_create "Acme Corp — Annual Contract" — $45,000, stage: proposal
crm_person_update Tom Bradley summary updated with demo feedback
crm_task_create "Send proposal to Tom Bradley (Acme)" — due Friday, high priority

Deal created at $45k in the proposal stage. You have a task to send the proposal by Friday. Want me to pull up your pipeline summary?
Yes, show me the pipeline and any overdue tasks.
crm_stats
crm_task_list overdue tasks

Pipeline: 3 leads ($12k), 2 proposals ($67k incl. Acme), 1 negotiation ($28k). Total open: $107k across 6 deals.

Overdue: 1 task — "Follow up with Beta Inc on contract terms" was due 2 days ago. Want me to bump it or should I draft a follow-up?

Preparing for an investor meeting

Pulling together context on a VC before a fundraising conversation.

C
Claude
I have a call with Maria Gonzalez from Sequoia in an hour. Can you brief me on our history?
crm_context Maria Gonzalez — full briefing

Maria Gonzalez — Partner at Sequoia Capital
Org: Sequoia Capital (VC, Growth & Early Stage)
Tags: investor, series-a-target

History (3 interactions):
• Mar 1 — Intro email via warm intro from Alex Kim
• Feb 15 — Met at SaaStr Annual, discussed market opportunity
• Feb 10 — She liked your blog post on PLG metrics (inbound)

Relationships: Referred by Alex Kim (angel investor)

Open tasks: "Send updated pitch deck" (due today, high priority)

Key context: she's interested in your PLG motion and asked about net revenue retention last time. Your pitch deck task is due today — have you sent it?
Not yet, sending now. After the call, remind me to log how it went and update the deal.
crm_task_create "Log call with Maria Gonzalez and update Series A deal" — due today

Reminder set. Good luck on the call! When you're back, just tell me how it went and I'll handle the rest.

Philosophy

Built on principles.

Every design decision optimizes for simplicity, speed, and data ownership.

🏠

Local-first

Your data lives on your machine in a single SQLite file. No cloud, no sync, no accounts.

Instant

Sub-millisecond queries on local SQLite. No network latency, no loading spinners, no waiting.

📦

Single binary

One file, zero dependencies. Pure Go with embedded SQLite. Download and run.

🔧

Composable

Structured output, exit codes, stdin/stdout discipline. Plays well with pipes and scripts.

Common questions.

What is Homebrew?

Homebrew is a package manager for macOS and Linux. Install it by pasting the command from brew.sh into your terminal. Once installed, you can use brew install to install crm-cli and thousands of other tools.

Can I install without Homebrew?

Yes. You can use go install github.com/jdanielnd/crm-cli/cmd/crm@latest if you have Go installed, or download a prebuilt binary for your platform from GitHub Releases.

Where is my data stored?

In a single SQLite file at ~/.crm/crm.db. You can override this with the --db flag or the CRM_DB environment variable. The file is portable — copy it anywhere, back it up however you like.

Can I sync across machines?

Point your database to a cloud-synced folder like iCloud Drive or Dropbox. On macOS: export CRM_DB="$HOME/Library/Mobile Documents/com~apple~CloudDocs/crm/crm.db". Just avoid writing from two machines at the same time.

What is MCP?

The Model Context Protocol is an open standard that lets AI agents interact with local tools. crm-cli includes a built-in MCP server, so Claude can read and update your contacts, deals, and tasks directly.

Is my data sent to the cloud?

Never. crm-cli is fully local. When used with Claude via MCP, the data flows between your local crm binary and the Claude client on your machine — it's not uploaded to any external server by crm-cli.

Does it work on Windows?

Yes. Prebuilt Windows binaries are available on the Releases page. You can also build from source with go build — no CGO required.

Can I delete data permanently?

crm-cli uses soft deletes (archiving) by default, so records are recoverable. The SQLite file is yours — you can always open it with any SQLite client if you need to permanently remove data.