The Django MCP server. Even if you don't use Django.

Stop writing the same MCP server scaffolding on every project — tool registry, schema generation, transport plumbing, auth, rate limit. 0-mcp collapses it into a single class. Your Django models become agent-callable tools instantly; the REST API ships at the same time, from the same source. And if you're not on Django at all, 0-mcp init reads any MySQL or Postgres schema and writes the entire project for you in one shot.

Already have a database but no Django? Skip the boilerplate entirely:

pip install 'django-zeromcp[gen-mysql]'
0-mcp init                             # interactive — prompts for host/db/credentials
cd ./<dbname> && ./run.sh

Every table becomes a model, every model becomes an MCP tool. ~10 seconds. Full walkthrough.

Slide 1 — The problem

Every team adopting MCP today writes the same thing:

And then the next project starts and it's all written again.

Slide 2 — The promise

Setup (once per app)

from zeromcp import BaseResource
from myapp.models import Space

Your entire resource — 2 lines

class SpaceResource(BaseResource):
    model = Space

What you got for free — MCP

What you got for free — REST API

Async dispatch, session and API-key auth, per-IP rate limit, scanner blocking, sanitized 500s — all on by default. Both for MCP and REST.

Slide 3 — The numbers

MetricHand-written MCP0-mcp
Lines per resource (typical)300–6002–30
Tool schema sourcehand-rolledfrom Django/Pydantic
Transports supportedone, manuallystdio + HTTP built in
Auth shared with REST APIno, two codebasesyes, one source
Rate limit on tool callsDIYinherited from API layer
Multi-tenant scopingDIY per toolone config line
Time to first toolhours to days5 minutes

Slide 4 — Production-ready by default

ConcernStatus
MCP server (stdio + HTTP)✅ opt-in
MCP tool schema generation✅ default
Async views (Django 5+)✅ default
Redis-backed sessions / cache / rate limit✅ default
Multi-tenant DB routing✅ opt-in
Pydantic validation✅ opt-in
Scanner blocking + 4xx flood detection✅ default
OpenAPI 3.0.3 + Scalar UI✅ one flag
HMAC-SHA256 anti-replay token✅ opt-in
IP spoof prevention via TRUSTED_PROXIES✅ default
Sanitized 500 responses in production✅ default
Test suite✅ 165 tests, green

Slide 5 — Cache that doesn't lie

Most cache layers blow up the world on every write. 0-mcp's doesn't.

OperationEffect
GET /spacescached under list:<model>
GET /spaces/5cached under detail:<model>:5
PATCH /spaces/5invalidates list:<model> + detail:<model>:5 only
DELETE /spaces/5same as PATCH
POST /spacesinvalidates list:<model> only

Editing row 5 does not drop the cache for row 7. Your Redis stops being a stampede waiting to happen. The same invalidation rules apply to MCP tool responses — your agent never serves stale data.

Slide 6 — Security middleware that bites

SecurityMiddleware matches request paths against patterns scanners actually use:

And user agents like sqlmap, nikto, nuclei, masscan, acunetix. One match, IP blocked for 24 hours. Logs get clean. DB stops processing junk. Real users never notice. The same protection covers the MCP HTTP transport.

Slide 7 — Multi-tenant routing that disappears

aset_tenant(account_id) switches the active database connection for the rest of the request. Combined with DBRouter, every ORM query is automatically scoped to the right tenant DB.

Your model code does not change. Your business logic does not know there are multiple databases. Your queries cannot cross tenants because the connection is gone. An agent authenticated for tenant A cannot see tenant B's data — the routing applies to MCP tool calls automatically.

Slide 8 — Pydantic when you want it

class UserCreate(BaseModel):
    email: EmailStr
    password: str = Field(min_length=8)

class UserResource(BaseResource):
    model = User
    create_schema = UserCreate

Set the schema, get validation. Skip it, fall back to Django field introspection. Adopt one resource at a time. No big migration. The same schemas drive MCP tool input validation and OpenAPI generation.

Slide 9 — OpenAPI that does not lie

urlpatterns = get_routes(endpoints)

Done. You now have:

Slide 10 — Who is this for

Slide 11 — When NOT to use it

Be honest about it:

Slide 12 — Get started

pip install django-zeromcp
# MCP server is bundled in the base install — no extras needed.
pip install 'django-zeromcp[schemas]'    # optional Pydantic

Slide 13 — One-liner

🚀

Ship an MCP server in 2 lines. Not 300. The first tool takes five minutes. The fiftieth takes five minutes too. API ships in the same line.

0-mcp by Stamatios Stamou Jr — github.com/ssjunior/0-mcp