Twenty CRM Cloud or self host Claude ready

A CRM you can run yourself. Move one pipeline first.

Compare Twenty with Salesforce, pick cloud or self host, import your CSV, then ask Claude about your deals.

Catch. Self hosting means updates and backups are yours. Twenty's own cloud starts at US$9.

Get the setup checklist

By Raj Singh · October 2026 · 12 min read

FREE SETUP CHECKLIST

Your Twenty setup pack.

  • Cloud and self host checklists
  • CSV import steps, in order
  • A CSV checker script
  • Connect Claude in four steps
  • Five prompts for your pipeline

One email opens every guide in the library.

One email. No follow-up unless I ship something that fits.

Read firstSelf hosting makes updates, backups and uptime yours. Twenty's licence is mostly AGPLv3, with some paid Enterprise files and a few MIT packages. Do not call it fully open source. Prices below are list prices checked on 25 Oct 2026.
THE PRICE GAP, ATTRIBUTED

What each option lists today

Both vendors list a per user price. Here are the plans I would compare, from their own pages.

Twenty Cloud Pro
US$9 per user per month, billed yearly. Source: twenty.com/pricing, 25 Oct 2026.
Twenty Organization
US$19 per user per month. Adds SSO and row level permissions, per the same page.
Twenty self host
No licence fee for the open source core. You pay for the server and your own time.
Salesforce Pro Suite
US$100 per user per month, billed annually. Source: salesforce.com/sales/pricing, 25 Oct 2026.
Salesforce Starter Suite
US$25 per user per month on the same page. Compare it fairly if you are small.
Five users, one year
Twenty Cloud Pro: US$540. Salesforce Pro Suite: US$6,000. My arithmetic, before tax and add ons.
CatchA price is not a feature match. Write down what you use in Salesforce today and check each item in Twenty's trial before you move.
PICK YOUR PATH

Cloud or self host

Twenty Cloud
Fastest. No server. You pay per user, and Twenty runs updates and backups. Choose this if you want to be working today.
Self host
Cheapest licence. Needs a machine with at least 2GB of RAM, Docker, and someone who will run backups and upgrades.

If you are unsure, start on the cloud trial with one pipeline. You can import the same CSV files into a self hosted copy later.

CHECKLIST A: CLOUD

Six steps

Step 1Start a trialSign up at twenty.com. The trial is 30 days per the pricing page. Twenty's quickstart says 30 days with a card and 7 days without. Check which you get.
Step 2Create the workspaceName it and invite your team. Roles are under Settings, Members, Roles.
Step 3Add custom fields firstSettings, Data Model. An import creates records, not fields.
Step 4Import companies, then peopleUse the CSV steps below.
Step 5Connect ClaudeUse the Claude steps below.
Step 6Decide by day 25Check the plan you need before the trial ends.
CHECKLIST B: SELF HOST

Six steps, with the real commands

Step 1Check the machineAt least 2GB of RAM, plus Docker and Docker Compose, per Twenty's docs. PostgreSQL 15 or newer if you bring your own database.
Step 2InstallTwenty's one line script, or the manual steps below. Read any script before you run it.
Step 3Guard the encryption keyLosing ENCRYPTION_KEY means losing every secret stored in the database, per the docs. Keep a copy in a password manager.
Step 4Open itVisit port 3000. If it is on a server, set SERVER_URL to the public address.
Step 5Schedule backupsBack up the database, then test a restore. Twenty tells you to do both.
Step 6Plan upgradesBack up first, change the tag, restart. Migrations run on startup.
terminalfrom Twenty's docs, 25 Oct 2026
# one line install bash <(curl -sL https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/scripts/install.sh) # or manual: key, then start curl -o .env https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/.env.example openssl rand -base64 32 # paste as ENCRYPTION_KEY in .env openssl rand -hex 32 # paste as PG_DATABASE_PASSWORD in .env curl -o docker-compose.yml https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/docker-compose.yml docker compose up -d # backup docker exec twenty-postgres pg_dump -U postgres twenty > backup_$(date +%Y%m%d).sql
Not run by meI did not run the Docker install, because there is no Docker on my test machine. The commands are copied from Twenty's docs.
CSV IMPORT: FROM SALESFORCE OR HUBSPOT

Seven steps, and the rules behind them

Step 1ExportUse each tool's own export to get CSV files, one per object: companies, contacts, deals. I have not checked their current menus.
Step 2Match the formatIn Twenty, open Companies, press the three dots, choose Import records, then Download sample file. Copy its column names.
Step 3Clean the fileUnique emails for people, unique domains for companies. Dates as YYYY-MM-DD. Booleans as TRUE or FALSE. No thousands separators.
Step 4Run my checkerIt catches the common errors before Twenty does. Script below.
Step 5Import companies firstMap Domain to Domain URL. Fix yellow rows in the preview, then confirm.
Step 6Import people secondLink them with the company domain in https://domain.com form. Opportunities come third.
Step 7Spot checkOpen five records and compare them to your old CRM.
  • Each file holds one object type and up to 10,000 records. Larger sets need Twenty's API import.
  • Select fields need the API name, not the label. Find it under Settings, Data Model, Show API values.
  • Deleted records still count toward uniqueness. Importing a matching value restores the deleted record.
  • Move one pipeline first, then check that your custom fields came across.
A CHECKER FOR YOUR CSV

Fix the file before you upload it

I wrote this to catch six rules from Twenty's CSV guide: file size, duplicates, domain format, uppercase booleans, number format and missing parent companies. It reads your files and changes nothing.

terminalreal output, 25 Oct 2026, test files with seeded errors
companies.csv: 3 problem(s) line 3: employees is 1,200, remove the thousands separator line 3: domain widgets.co should look like https://domain.com line 4: duplicate Domain / Domain URL https://acme.com (first on line 2) people.csv: 3 problem(s) line 4: email sam-at-nowhere is not a valid address line 3: companyDomain https://widgets.co is not in companies.csv. Import companies first. line 4: companyDomain https://nowhere.example is not in companies.csv. Import companies first. Fix the lines above, then import companies first, people second.
terminalreal output, clean test files
good-companies.csv: 0 problem(s) good-people.csv: 0 problem(s) Ready to import.
checker scriptsave as twenty_csv_check.py, scroll sideways
#!/usr/bin/env python3 """Check for a Twenty CSV import. Standard library only. Usage: python3 twenty_csv_check.py companies.csv [people.csv] Rules come from Twenty's CSV prep guide (docs.twenty.com). Read only.""" import csv, re, sys LIMIT = 10000 EMAIL = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$") THOUSANDS = re.compile(r"^\d{1,3}(,\d{3})+(\.\d+)?$") def load(path): raw = open(path, "rb").read() try: text = raw.decode("utf-8-sig") except UnicodeDecodeError: print(f"{path}: FIX not UTF-8, re-save as UTF-8 CSV") sys.exit(1) return list(csv.DictReader(text.splitlines())) def col(rows, *names): for n in names: if rows and n in rows[0]: return n return None def check(path, kind): rows = load(path) problems = [] if len(rows) >= LIMIT: problems.append(f"{len(rows)} rows, the limit is {LIMIT} per file. Split it.") key = col(rows, "Domain / Domain URL", "domain") if kind == "companies" else col(rows, "email", "Emails / Primary Email") seen = {} for i, r in enumerate(rows, start=2): for name, v in r.items(): v = (v or "").strip() if v in ("true", "false"): problems.append(f"line {i}: {name} is {v}, use {v.upper()}") if THOUSANDS.match(v): problems.append(f"line {i}: {name} is {v}, remove the thousands separator") if key: v = (r.get(key) or "").strip().lower() if v: if v in seen: problems.append(f"line {i}: duplicate {key} {v} (first on line {seen[v]})") seen[v] = i if kind == "companies" and key and r.get(key) and not r[key].startswith("https://"): problems.append(f"line {i}: domain {r[key]} should look like https://domain.com") if kind == "people": e = (r.get("email") or "").strip() if e and not EMAIL.match(e): problems.append(f"line {i}: email {e} is not a valid address") d = (r.get("companyDomain") or "").strip() if d and not d.startswith("https://"): problems.append(f"line {i}: companyDomain {d} should look like https://domain.com") return rows, problems def main(): args = sys.argv[1:] if not args: sys.exit(__doc__) crows, cprob = check(args[0], "companies") allprob = {args[0]: cprob} if len(args) > 1: prows, pprob = check(args[1], "people") known = {(r.get("Domain / Domain URL") or "").strip().lower() for r in crows} for i, r in enumerate(prows, start=2): d = (r.get("companyDomain") or "").strip().lower() if d and d not in known: pprob.append(f"line {i}: companyDomain {d} is not in {args[0]}. Import companies first.") allprob[args[1]] = pprob bad = 0 for path, probs in allprob.items(): print(f"{path}: {len(probs)} problem(s)") for p in probs: print(" " + p) bad += len(probs) print("Ready to import." if not bad else "Fix the lines above, then import companies first, people second.") sys.exit(1 if bad else 0) main()
LimitsIt is my script, not Twenty's. It covers six rules, not all of them. Twenty's own preview is still the final check.
CONNECT CLAUDE

Four steps

Twenty runs an MCP server at your workspace address. Claude Code can connect with OAuth, so you store no key.

Step 1Find your addressCloud looks like https://yourcompany.twenty.com. Self hosted is your own domain. Twenty's page is Settings, AI, MCP.
Step 2Add the serverRun the command below in a terminal.
Step 3Sign inStart Claude Code, type /mcp, pick twenty and finish the browser login.
Step 4Test with a readAsk: show me the five most recently created companies.
terminalClaude Code and Twenty docs, 25 Oct 2026
claude mcp add --transport http twenty https://yourcompany.twenty.com/mcp
  • Claude acts with your Twenty permissions. For a safer start, create an API key with a read only role, under Settings, Members, Roles. Twenty documents roles for keys.
  • Self hosted: set SERVER_URL to your public address. Twenty builds its OAuth details from it.
  • Twenty lists Claude Desktop, Claude Code, Cursor and ChatGPT as supported clients.
Not run by meI did not connect a live workspace. These steps come from the Twenty and Claude Code docs.
FIVE PROMPTS FOR YOUR PIPELINE

Copy, paste, read the answer

Paste these into Claude once it is connected. Each starts read only. Change the numbers to suit you.

prompt 1deals gone quiet
Using the Twenty tools, list every open opportunity with no update in the last 7 days. Show company, amount, stage and last updated date. Sort by amount, largest first. Do not change anything.
prompt 2pipeline snapshot
Count open opportunities and total their amounts by stage. Show a small table. Then say which stage holds the most money and which has the fewest deals. Do not change anything.
prompt 3duplicates
Find people who share an email and companies that share a domain, or have near identical names. List them in a table with ids. Do not merge or delete anything. I will decide.
prompt 4follow up drafts
Take my five largest open opportunities. For each, draft a three sentence follow up email in plain words, using the notes on the record. Show the drafts here. Do not send or save them.
prompt 5import audit
I just imported from a CSV. Pick ten random people and ten random companies. List their key fields so I can compare them with my old CRM. Flag anything blank, odd or duplicated.
CatchClaude only sees what is in Twenty. If your team does not log updates, prompt 1 finds nothing useful.
WHAT CAN GO WRONG

Six traps

  • Importing people before companies. The link fails. Companies first.
  • Wrong domain format. Use https://domain.com every time, or duplicates appear later.
  • Lowercase true or false. Twenty needs TRUE or FALSE.
  • Skipping backups. A self hosted CRM with no tested restore is a risk.
  • Giving Claude write access too early. Start read only.
  • Assuming a match. Check every feature you rely on during the trial.
SOURCES AND DATES

Where these facts come from

  • Twenty pricing: twenty.com/pricing, 25 Oct 2026. Salesforce pricing: salesforce.com/sales/pricing, 25 Oct 2026. Both are starting prices.
  • Twenty docs: Docker Compose, Upgrade guide, Prepare Your CSV Files, Import Companies and Contacts via CSV, MCP Server, at docs.twenty.com, read 25 Oct 2026.
  • Claude Code docs, Connect Claude Code to tools via MCP, code.claude.com/docs/en/mcp, 25 Oct 2026.
  • Twenty on GitHub, 59,669 stars on 25 Oct 2026. The licence file says mostly AGPLv3, with some Enterprise files and some MIT packages.
  • Format idea: an Instagram reel, instagram.com/p/DePIgOcMOzi, 60,861 views, about 9 times the account's usual.
That is the whole thing

Move one pipeline first. Clean the CSV, import companies, then people, and keep Claude read only until you trust it.

View Twenty on GitHub →

↑ Unlocks the moment you submit the form above.

RS
WRITTEN BY

Raj Singh

I'm Raj Singh. I've led ecommerce at two Fortune 100 companies, and at one of them I ran about $8M a year in ads for four years. I've worked with AI since 2019. Now my engineering team and I ship AI products, including debtops.ai. Each guide here is written from a real install, with the output dated.

2
Fortune 100 companies
~$8M
A year in ads, at one
2019
Working with AI
43
Guides shipped
More guides

Run it with your own Claude.

Want Claude working on it all day? The free tokens setup shows how to run Claude Code on free provider tiers.