Open CRM

Your server. Your data. Your agents.

Most CRMs are cumbersome: per-seat pricing, a menu for everything, and a data model you have to bend your work around. Open CRM is a small, self-hosted CRM you can run as it is, or fork and build into exactly the CRM you want.

Open CRM home: open pipeline, weighted forecast, won this month and win rate, with charts for pipeline by stage, won vs lost, new pipeline and activity by you and your agents
Simple
One container and your own Postgres. People, companies, deals and tasks, and nothing you didn't ask for.
Extensible
Objects and fields are data. Add them from the UI, or fork the code and change anything.
AI-native
A built-in MCP server, so Claude, ChatGPT and Cursor work in the same records you do.

Everything a small CRM needs, nothing it doesn't

Every screenshot here is the real app, running on demo data.

A pipeline you can see

Drag deals between stages on the board, or switch to a table. Each column shows its count, total value and win probability.

Group any object by any select field: the same board works for hiring, projects or fundraising.

Deals board with Lead, Qualified, Proposal and Negotiation columns, each with a count, win percentage and total

Your process, not ours

Rename, reorder and recolor stages. Mark which stages close a deal as won or lost, and give open stages a win percentage.

  • Weighted forecast on Home
  • Win rate and days to close
  • Won vs lost by month
Deal stages editor with order, color, type (open, won, lost) and win percentage for each stage

The whole story on every record

Notes, calls, emails, meetings and tasks sit on one timeline, next to every field change and who made it.

A note or task can link to as many records as it's about: the deal, the person and the company at once.

Deal record with company, contact, stage, amount and next step, and an activity timeline of tasks, calls and stage changes

Filters you'll actually use

Filter on any field, including relative dates like "updated in the last 14 days", then save the result as a view.

Agents use the same filters, so "show me big deals that went quiet" turns into a view you can open later.

People table filtered by Status is Active, with the filter menu open and a Save as view button

Shape it to your work

Add fields and whole new objects (investors, properties, candidates) from the UI. Every table, form, filter and board picks them up.

  • 12 field types, including links between records
  • Unique fields to dedupe imports
  • Colors for objects and options
New field dialog with 12 field types: text, select, multi-select, link to record, date, currency, number, yes/no, long text, email, URL and phone

Agents work in the open

Every change is in the audit log under your name or the agent's key. Undo record changes, notes, tasks, new or edited fields and objects, and archived fields and objects from there.

Archiving a field or object, removing options and changing a field's type can lose data, so agents have to ask. The request waits in your Approvals inbox until you decide.

Approvals inbox with a request from the agent Claude to remove an option, with Reject and Approve buttons Audit log listing changes by You and by the agent Claude

Your agent gets the same CRM you do

The MCP server isn't bolted on. Agents read the schema, so they know your objects, fields and stages, and they get tools for the same work you do in the UI. Give each agent its own key with only the scopes it needs.

Read read scope

describe_schemasearchlist_recordsget_recordget_overviewlist_taskslist_views

Write write scope

create_recordupdate_recordupsert_recordbulk_upsert_recordsarchive_recordlog_activitycreate_taskupdate_taskcomplete_tasksave_viewupdate_viewdelete_view

Schema schema scope

create_object_typeupdate_object_typeadd_fieldupdate_fieldrequest_schema_change

YouJust got off a call with Marcus at Northwind. They want EU and US on one contract, and legal is reviewing the DPA. Move the deal forward and remind me Friday.

Claude
search { "query": "Northwind" }
update_record { "id": "…", "data": { "stage": "negotiation", "next_step": "Redlines back from legal" } }
log_activity { "kind": "call", "record_ids": ["deal…", "marcus…"], "body": "EU and US on one contract. Legal reviewing the DPA." }
create_task { "title": "Chase Northwind redlines", "due_at": "2026-11-13", "record_ids": ["deal…"] }
Done. Northwind rollout is in Negotiation, the call is on both Marcus and the deal, and there's a task for Friday.

An example of the tool calls. Each one shows up in the audit log under the agent's key.

Small, but not missing the basics

Tasks

Due dates, overdue counts on Home, and tasks that link to any records.

CSV import and export

Map columns to fields, and match on email or domain to update instead of duplicating.

REST API

Records, schema, views and import/export over JSON at /api, with the same keys as MCP. Reference

Signed webhooks

Get record, activity and approval events, signed with HMAC and retried on failure.

Search everywhere

Press ⌘K to jump to any record by name, email or any text field.

Light, dark and your colors

Follows your system theme. Pick an accent color and a color for each object.

Your Postgres

Plain tables you can query, back up with pg_dump and take with you.

One process

The web app, API and MCP server ship as one Node process in one Docker image.

MIT licensed

No license keys, no telemetry, no seats. Fork it and make it yours.

Use it, or make it yours

Run it as it is and shape it from the UI, or fork it and change anything. All business logic lives in one folder (server/src/core), the API and MCP server are thin layers on top of it, and the UI renders from the schema, so most changes are small and local.

How the code is laid out →

Running in five minutes

Open CRM is one Docker container plus Postgres. Migrations run on boot, and the first boot creates People, Companies and Deals.

git clone https://github.com/housewithbricks/open-crm
cd open-crm
cp .env.example .env    # set ADMIN_PASSWORD
docker compose up -d

Or anywhere Docker runs: Fly.io, Coolify, Dokploy, Portainer, a VPS. See the self-hosting guide.

Connect your agent

Open CRM speaks MCP, so any MCP client can use it. Create a key in Settings → API keys & MCP, then pick your client:

Run once in your terminal:

claude mcp add --transport http open-crm https://your-host/mcp \
  --header "Authorization: Bearer ocrm_…"

In Claude on the web or desktop: Settings → Connectors → Add custom connector. Connectors take a URL rather than headers, so the key goes in the URL:

https://your-host/mcp?key=ocrm_…

Treat this URL like a password, and give each connector its own key.

In ChatGPT, turn on developer mode (Settings → Apps & Connectors → Advanced settings), then create a connector with this URL and No authentication. The key in the URL is the authentication.

https://your-host/mcp?key=ocrm_…

On the OpenAI API, add an mcp tool with server_url and an Authorization header instead.

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "open-crm": {
      "url": "https://your-host/mcp",
      "headers": { "Authorization": "Bearer ocrm_…" }
    }
  }
}

Add to .vscode/mcp.json for GitHub Copilot agent mode:

{
  "servers": {
    "open-crm": {
      "type": "http",
      "url": "https://your-host/mcp",
      "headers": { "Authorization": "Bearer ocrm_…" }
    }
  }
}

Point any MCP client at the Streamable HTTP endpoint with the key as a bearer token:

URL     https://your-host/mcp
Header  Authorization: Bearer ocrm_…

If the client only takes a URL, use /mcp?key=ocrm_…. If it only runs local servers, bridge with mcp-remote:

npx -y mcp-remote https://your-host/mcp --header "Authorization:Bearer ocrm_…"

Setup for Windsurf, Gemini CLI, Codex, Claude Desktop config files and the OpenAI API is in the guide to connecting agents.

Questions

Is it free?

Yes. It's MIT licensed, with no paid tier, license keys or telemetry. You pay only for wherever you host it.

Can a team use it?

Yes, but as it is there's one user login, so everyone shares it. Agents each get their own API key, so their changes are attributed separately. If you need separate users and roles, fork it and add them.

Where does my data live?

In your own Postgres database, in plain tables. Nothing is sent anywhere else unless you add a webhook. Back it up with pg_dump or export any object as CSV.

What can an agent do without asking me?

Whatever its key's scopes allow: read, write records and notes, or add objects and fields. Archiving a field or object, removing options and changing a field's type always wait for your approval, and you can revoke a key at any time.

Can I bring data from another CRM?

Export a CSV from it, add any fields you need, and import. Match on email or domain to update existing records instead of creating duplicates. Or ask your agent to do it.

How do I update it?

Pull the new image or code and restart. Database migrations run on boot.

Run it, or make it yours

One container, your Postgres, your agents.