MicroPyramid
Django-CRM
Python

Open Source CRM for Startups — Django REST + SvelteKit · Self-hosted · Multi-tenant · Free forever

Last updated Jul 8, 2026
2.3k
Stars
1.0k
Forks
71
Issues
+5
Stars/day
Attention Score
90
Language breakdown
No language data available.
Files click to expand
README

BottleCRM

A modern, open-source CRM platform built with Django REST Framework and SvelteKit.

License Python Django SvelteKit Svelte Coverage

https://github.com/user-attachments/assets/f384f25e-ab52-4069-afaf-f8e2f1f3f0e7

Overview

BottleCRM is a full-featured Customer Relationship Management system designed for startups and small businesses. It combines a powerful Django REST API backend with a modern SvelteKit frontend, featuring multi-tenant architecture with PostgreSQL Row-Level Security (RLS) for enterprise-grade data isolation.

Try it free: bottlecrm.io

Features

Core CRM Modules

  • Leads - Track and manage sales leads through your pipeline
  • Accounts - Manage company/organization records
  • Contacts - Store and organize contact information
  • Opportunities - Track deals and sales opportunities
  • Cases - Customer support case management
  • Tasks - Task management with calendar and Kanban board views
  • Invoices - Create and manage invoices

Platform Features

  • Multi-Tenant Architecture - PostgreSQL RLS for secure data isolation between organizations
  • JWT Authentication - Secure token-based authentication
  • Team Management - Organize users into teams with role-based access
  • Activity Tracking - Comprehensive audit logs and activity history
  • Comments & Attachments - Collaborate with comments and file attachments on any record
  • Tags - Flexible tagging system for organizing records
  • Email Integration - AWS SES integration for transactional emails
  • Background Tasks - Celery + Redis for async task processing
  • AI Agents (MCP) - Built-in Model Context Protocol server (mcpserver/) lets Claude, Cursor, Codex, Gemini and any MCP client search, create and update records via a personal access token — acting as you, with your role and permissions. See mcp_server/README.md.

Tech Stack

Backend

  • Django 5.x with Django REST Framework
  • PostgreSQL with Row-Level Security (RLS)
  • Redis for caching and Celery broker
  • Celery for background task processing
  • JWT for authentication
  • AWS S3 for file storage
  • AWS SES for email delivery

Frontend

  • SvelteKit 2.x with Svelte 5 (runes)
  • TailwindCSS 4 for styling
  • shadcn-svelte UI components
  • Zod for schema validation
  • Axios for API communication
  • Lucide icons

Quick Start

Prerequisites

  • Python 3.10+
  • Node.js 18+ with pnpm
  • PostgreSQL 14+
  • Redis

Backend Setup

The backend uses uv for Python dependency management — it reads pyproject.toml, installs from uv.lock, and creates the virtual environment for you. uv is much faster than pip and gives reproducible installs out of the box.

# Clone the repository
git clone https://github.com/MicroPyramid/Django-CRM.git
cd Django-CRM/backend

Install uv (one time, system-wide)

curl -LsSf https://astral.sh/uv/install.sh | sh

Or on macOS via Homebrew: brew install uv

Install Python (matches the version in .python-version) and all deps into .venv/

uv sync

Set up environment variables (see env.md for details)

cp .env.example .env

Edit .env with your database and other settings

Run migrations

uv run python manage.py migrate

Create a superuser

uv run python manage.py createsuperuser

Start the development server

uv run python manage.py runserver

uv run <cmd> resolves binaries from .venv/bin/ automatically — no need to source .venv/bin/activate. If you prefer the activate-then-run flow, that still works:

source .venv/bin/activate
python manage.py runserver   # equivalent to uv run python manage.py runserver

Common dev commands (from backend/):

uv run pytest                                # run tests
uv run python manage.py makemigrations       # create migrations
uv run celery -A crm worker --loglevel=INFO  # background worker
uv add <package>                             # add a dependency (updates pyproject.toml + uv.lock)
uv add --group dev <package>                 # add a dev-only dependency
uv lock --upgrade                            # refresh the lockfile

Frontend Setup

# In a new terminal, from the project root
cd frontend

Install dependencies

pnpm install

Start the development server

pnpm run dev

Start Celery Worker

# In a new terminal
cd backend
uv run celery -A crm worker --loglevel=INFO

Access the Application

  • Frontend: http://localhost:5173
  • API Documentation: http://localhost:8000/swagger-ui/
  • Admin Panel: http://localhost:8000/admin/

Connect your AI agent (MCP)

Let Claude, Cursor, Codex, Gemini, or any MCP client work in your CRM:

  • In the app, go to Settings → API Tokens and create a personal access token (shown once).
  • Register the bcrm-mcp server in your AI client, passing BCRMBASEURL (your API host, e.g. http://localhost:8000) and BCRM_TOKEN (the token). The token page shows ready-to-paste config for each client.
  • Restart the client and start asking.
The agent authenticates as you and inherits your role, org and RLS scope — it can't see or do anything you can't. Full setup, the tool list, and the security model are in mcp_server/README.md.

Docker Setup

Run the full stack (backend, frontend, PostgreSQL, Redis, Celery) with a single command:

# Start all services (first run will build images)

An admin user (admin@localhost / admin) is created automatically

docker compose up --build

(Optional) Load sample data

docker compose exec backend python manage.py seed_data --email admin@example.com

Once running:

  • Frontend: http://localhost:5173
  • API / Swagger: http://localhost:8000/swagger-ui/
  • PostgreSQL: localhost:5432
  • Redis: localhost:6379

Daily workflow

docker compose up           # start all services (code changes auto-reload)
docker compose down         # stop all services
docker compose down -v      # stop and delete all data (full reset)

Running commands inside containers

docker compose exec backend python manage.py migrate
docker compose exec backend python -m pytest
docker compose exec backend python manage.py manage_rls --status

Custom environment overrides

The default env vars live in .env.docker (committed). To override locally without touching git:

  • Copy .env.docker to .env.docker.local
  • Edit values as needed
  • Update env_file in docker-compose.yml to point to .env.docker.local

Project Structure

Django-CRM/
├── backend/                 # Django REST API
│   ├── accounts/           # Accounts module
│   ├── cases/              # Cases module
│   ├── common/             # Shared models, utilities, RLS
│   ├── contacts/           # Contacts module
│   ├── invoices/           # Invoices module
│   ├── leads/              # Leads module
│   ├── opportunity/        # Opportunities module
│   ├── tasks/              # Tasks module
│   └── crm/                # Django project settings
├── frontend/               # SvelteKit frontend
│   ├── src/
│   │   ├── lib/           # Components, stores, utilities
│   │   └── routes/        # SvelteKit routes
│   │       ├── (app)/     # Authenticated app routes
│   │       └── (no-layout)/ # Auth pages (login, etc.)
│   ├── static/            # Static assets
│   └── Dockerfile         # Frontend dev container
├── mcp_server/             # MCP server (bcrm-mcp) for AI agents
│   └── src/bcrm_mcp/      # FastMCP tools over the REST API (stdio transport)
├── docker/                 # Docker support files
│   ├── backend/
│   │   └── entrypoint.sh  # DB wait + migrate + runserver
│   └── postgres/
│       └── init-rls-user.sql # Creates non-superuser for RLS
├── Dockerfile              # Backend / Celery image
├── docker-compose.yml      # Full-stack dev environment
└── .env.docker             # Docker env vars (dev defaults)

Multi-Tenancy & Security

BottleCRM uses PostgreSQL Row-Level Security (RLS) to ensure complete data isolation between organizations. Every database query is automatically filtered by organization context, providing enterprise-grade security.

# Check RLS status
python manage.py manage_rls --status

Verify RLS user configuration

python manage.py manage_rls --verify-user

Test data isolation

python manage.py manage_rls --test

Development

Testing

cd backend

Run all tests with coverage

pytest

Run tests without coverage (faster)

pytest --no-cov -x

Run a specific module's tests

pytest accounts/tests/ pytest leads/tests/testleadskanban.py

Run tests matching a keyword

pytest -k "test_login"

View coverage report in browser

open htmlcov/index.html

Backend Commands

# Format code
black . && isort .

Check dependencies

pipdeptree pip-check -H

Dev login (skip the Google OAuth flow)

For local development you can mint a JWT for any user without going through Google sign-in. The command refuses to run unless DEBUG=True, and there's no web endpoint — it's only reachable through manage.py:

cd backend

Mint tokens for an existing user (no org bound — same as the OAuth flow)

uv run python manage.py devlogin aswin.1231@gmail.com

Bind to a specific org so you skip the orgswitch step on first load

uv run python manage.py devlogin aswin.1231@gmail.com --org "MicroPyramid"

Create the user on the fly (random password) if they don't exist yet

uv run python manage.py devlogin newdev@example.com --create

The command prints the access/refresh tokens plus a ready-to-paste localStorage.setItem(...) snippet — drop it into the browser devtools console on http://localhost:5173 and reload to be signed in.

Frontend Commands

cd frontend

Type checking

pnpm run check

Linting

pnpm run lint

Formatting

pnpm run format

API Documentation

The API follows RESTful conventions:

GET/POST       /api/<module>/                 # List/Create
GET/PUT/DELETE /api/<module>/<pk>/            # Detail/Update/Delete
GET/POST       /api/<module>/comment/<pk>/    # Comments
GET/POST       /api/<module>/attachment/<pk>/ # Attachments

Interactive API documentation is available at /swagger-ui/ when running the backend.

Contributing

We welcome contributions! Please see our contributing guidelines for details.

  • Fork the repository
  • Create a feature branch (git checkout -b feature/amazing-feature)
  • Commit your changes (git commit -m 'Add amazing feature')
  • Push to the branch (git push origin feature/amazing-feature)
  • Open a Pull Request

Community

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributors

This project exists thanks to all the people who contributed.

Contributors

© 2026 GitRepoTrend · MicroPyramid/Django-CRM · Updated daily from GitHub