Demo CRM MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Demo CRM MCP Server Show today's new leads in Victoria, check duplicates, suggest owners."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Demo CRM MCP Server
Let an AI assistant work a sales pipeline safely: search leads, catch duplicates before they are created, and route each lead to the right salesperson.
This is a Model Context Protocol (MCP) server written in Python. Connect it to an MCP client such as Claude Desktop and you can manage a CRM in plain English:
"Show me today's new leads in Victoria, check them for duplicates, and suggest who should own each one."
It is based on the kind of lead automation I build in production (duplicate detection, territory-based allocation, audit trails), rebuilt from scratch as an open demo with 100% fictional data.
Why this project
AI assistants are most useful when they can act on real business systems, but giving them write access to a CRM is risky. This server shows how to do it responsibly:
Risk | How this server handles it |
AI creates duplicate records | Every |
Black-box decisions | Duplicate matches and salesperson recommendations always come with reasons |
Unwanted changes | Tools are labelled read-only or write, and |
No accountability | Every change is recorded in an audit log, readable as an MCP resource |
Bad input | Strict validation on every field; all SQL is parameterised |
Related MCP server: BackCrew GoHighLevel MCP Server
Architecture
flowchart LR
U[You] -->|plain English| C[MCP client<br/>e.g. Claude Desktop]
C <-->|MCP over stdio| S[crm-mcp server]
S --> T1[Read tools<br/>search · get · duplicates<br/>recommend · summary]
S --> T2[Write tools<br/>create · status · note · assign]
T2 --> G{Guards<br/>validation · duplicate check<br/>read-only mode}
T1 --> DB[(SQLite demo CRM)]
G --> DB
G --> A[(Audit log)]What the AI can do
Tools
Tool | Type | What it does |
| read | Search by name, email, phone, postcode, status, state or owner |
| read | Full lead record with owner and notes |
| read | Compares a lead with every other lead and explains each match |
| read | Ranks salespeople by territory coverage and current workload |
| read | Counts by status and source, unassigned leads, win rate |
| write | Creates a lead, with built-in duplicate protection |
| write | Moves a lead through New → Contacted → Qualified → Quote Sent → Won/Lost |
| write | Adds a note to a lead |
| write | Assigns a lead to a salesperson |
Resources: crm://schema (fields, statuses, duplicate rules) and crm://audit-log (recent changes).
Prompt: daily_triage, a ready-made workflow that reviews new leads, flags duplicates and proposes assignments, then asks you to confirm before changing anything.
Duplicate detection
Phone numbers and emails are normalised first, so +61 491 570 156, 0491-570-156 and (04) 9157 0156 are treated as the same number.
Confidence | Rule |
High | Same email (case-insensitive) |
High | Same phone number (formatting ignored) |
High | Same full name and postcode |
Medium | Very similar name (85%+ similarity) in the same postcode, e.g. Sophia / Sofia |
Low | Same full name in the same state |
A lead is never matched against itself. Example output:
{
"lead_id": 38,
"possible_duplicates": [
{
"lead_id": 6,
"name": "Jack Khan",
"confidence": "high",
"reasons": [
"Same phone number (after removing formatting)",
"Same full name and postcode"
]
}
]
}And when the AI tries to create a lead that already exists:
{
"created": false,
"message": "Not created: this looks like an existing lead. Review the matches, then call create_lead again with allow_duplicate=true if it really is a new person.",
"possible_duplicates": [
{ "lead_id": 1, "name": "Ruby Singh", "confidence": "high", "reasons": ["Same email address"] }
]
}Quick start
Requires Python 3.10 or later.
git clone https://github.com/hayathi06/crm-mcp-server.git
cd crm-mcp-server
python -m venv .venv
# Windows: .venv\Scripts\activate macOS/Linux: source .venv/bin/activate
pip install -e ".[dev]"
pytest # run the testsOn first run the server creates demo_crm.db with 40 fictional leads, 6 salespeople and four planted duplicates for the detector to find.
Connect to Claude Desktop
In Claude Desktop, open Settings → Developer → Edit Config and add the server to claude_desktop_config.json. Use the full path to the Python inside your virtual environment:
{
"mcpServers": {
"demo-crm": {
"command": "C:\\path\\to\\crm-mcp-server\\.venv\\Scripts\\python.exe",
"args": ["-m", "crm_mcp"],
"env": {
"CRM_MCP_DB": "C:\\path\\to\\crm-mcp-server\\demo_crm.db",
"CRM_MCP_READ_ONLY": "0"
}
}
}
}On macOS or Linux the command is /path/to/crm-mcp-server/.venv/bin/python. Restart Claude Desktop and the CRM tools appear.
Try these prompts
"Give me a pipeline summary for NSW."
"Find leads that are probably duplicates and explain why."
"Add a new lead: Ruby Singh, RUBY.SINGH0@example.com, Perth 6000." (watch the duplicate check block it)
"Which new leads have no owner? Recommend a salesperson for each and assign them once I confirm."
"Run the daily triage for VIC."
Configuration
Variable | Default | Purpose |
|
| Path to the SQLite file, created and seeded if missing |
| off | Set to |
Project structure
src/crm_mcp/
server.py MCP tools, resources and prompt
crm.py CRM logic, validation, audit log, demo data
duplicates.py Normalisation and duplicate rules
tests/
test_crm.py Unit tests for the CRM logic
test_server.py End-to-end tests over a real MCP stdio sessionAbout the data
Everything is invented. Names are made up, emails use the reserved example.com domain, and phone numbers come from the ranges the Australian Communications and Media Authority reserves for fiction.
Author
Noor Hayathi Jamal Mohammed, AI Automation Engineer, Melbourne Portfolio · LinkedIn
MIT licensed.
Available Tools
9 toolsadd_noteC
Add a note to a lead.
Inputs: note (required), lead_id (required).
assign_leadAIdempotent
Assign a lead to a salesperson (use recommend_salesperson first).
Inputs: lead_id (required), salesperson_id (required).
create_leadA
Create a lead. Runs duplicate detection first and refuses high-confidence duplicates unless allow_duplicate is true.
Inputs: last_name (required), first_name (required), email, phone, +5 more.
find_duplicatesARead-only
Check an existing lead against every other lead and explain any likely duplicates.
Inputs: lead_id (required).
get_leadBRead-only
Get one lead with its owner and notes.
Inputs: lead_id (required).
pipeline_summaryBRead-only
Lead counts by status and source, unassigned open leads, and win rate.
Inputs: state.
recommend_salespersonBRead-only
Rank salespeople for a lead by territory coverage and current workload.
Inputs: lead_id (required).
search_leadsBRead-only
Search leads by text, status, state or owner. Newest first.
Inputs: limit, owner, query, state, +1 more.
update_lead_statusCIdempotent
Move a lead to a new pipeline status.
Inputs: status (required), lead_id (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Most tools have clearly distinct resource+action targets (search, get, create, add_note, assign, summarize). Minor overlap exists: find_duplicates partially duplicates the duplicate check built into create_lead, and assign_lead vs update_lead_status both mutate a lead's fields, though descriptions clarify intent.
The set is overwhelmingly consistent snake_case verb_noun (search_leads, get_lead, create_lead, assign_lead, add_note). The only deviation is pipeline_summary, which is a bare noun phrase without a verb, but it remains readable and predictable.
Nine tools is well-scoped for a CRM server, covering discovery, reading, mutation, and analytics without redundancy. Each tool earns its place and none feels like padding.
Core lead lifecycle is covered: create, search, get, status update, note, assignment, duplicate check, plus a pipeline analytics view. Gaps include no delete/archive lead, no general field-edit tool beyond status, and no way to list or manage salespeople outside recommend_salesperson.
Maintenance
Related MCP Connectors
Read-only sales CRM for AI clients: leads, pipeline, AI-agent chats, calls, ad attribution.
CRM with an AI phone receptionist: search leads, read call transcripts, move deals, log activity.
AI CRM: accounts, deals, meetings and agents, with approvals before anything is sent.
CRM, inbox, meetings, revenue intelligence, analytics and automations for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to interact with a CRM covering companies, people, leads, deals, and more, with role checks, scoped agent keys, approval gates, and a shared audit trail.AGPL 3.0
- AlicenseAqualityDmaintenanceEnables AI assistants to interact with GoHighLevel CRM via natural language for lead lookup, pipeline management, messaging, and calendar operations, with read-only mode by default.12MIT
- AlicenseNot gradedqualityCmaintenanceProvides safe, read-only CRM access for AI assistants with per-key scopes, field masking, rate limits, and a full audit log of allowed and blocked actions.MIT
- FlicenseNot gradedqualityAmaintenanceEnables AI assistants to access and manage CRM data by creating contacts and companies, retrieving activities and conversations, and performing semantic search over previously retrieved information with built-in vector storage and caching.-