Chassis

Official registry Data and databases

Scaffold an Express 5 + TypeScript backend: database, auth, optional Next.js front end.

What can you do with Chassis?

  • TypeScript 6 + Express 5 — strict types, async errors caught automatically
  • Decorator routing — @route / @protectedRoute on controller methods, controllers auto-mount
  • Consistent responses — req.resHandler.ok() / .notFound() / .validation() with structured logging
  • Request correlation — every request gets a callId (or propagates x-call-id), echoed in responses and logs
  • Typed, validated config — zod-checked environment via src/config; the app refuses to boot on bad config
  • Zod input validation — validate({ body, query, params }) middleware with structured 400s
  • Pick-your-stack scaffolder — presets or à la carte: database + ORM (Mongo/Postgres/SQLite), auth (Auth0/Clerk/local), a Next.js front end, Sentry, MCP, x402 — the CLI prunes everything else so package.json carries only what you chose
  • Opt-in integrations — every module enables by env var, never required

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

NPM package chassis-mcp
Claude Code
claude mcp add chassis -- npx -y chassis-mcp@0.1.2
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "chassis": {
            "command": "npx",
            "args": [
                "-y",
                "chassis-mcp@0.1.2"
            ]
        }
    }
}

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. 🏎️ Chassis
  2. Quick start
  3. For AI agents
  4. Features
  5. AI-agent ready
  6. Scripts
  7. Enabling integrations
  8. Project structure
  9. Documentation
  10. Docker
  11. License

🏎️ Chassis

A lightweight, decorator-driven Express + TypeScript backend starter. Clone, run, ship.

📖 Documentation · Getting started · create-chassis on npm

Chassis gives you NestJS-style controller ergonomics on plain Express 5 — in a handful of small files you can actually read. Zero configuration required: the server boots standalone, and every integration switches on only when you add its environment variable. Scaffold with a preset or pick à la carte — a database (Mongo, Postgres, or SQLite, ORM included), an auth provider (Auth0, Clerk, or built-in local sign-in), an optional Next.js front end, Sentry, an MCP server, and x402 payments — and the CLI ships only what you chose.

export class UserController extends Routable {
  constructor() {
    super('/users');
  }

  @route('get', '/:id')
  async show(req: Request) {
    const user = await findUser(req.params.id);
    if (!user) throw new AppError(ERROR_CODES.NOT_FOUND, 'User not found');
    return req.resHandler.ok(user);
  }

  @protectedRoute('post', '/', [validate({ body: createUserSchema })])
  async create(req: Request) {
    return req.resHandler.created(await createUser(req.body));
  }
}

Export the class from src/controllers/index.ts — that's the whole wiring.

Quick start

npm create chassis my-api -- --yes                      # zero prompts: Postgres + JWT + Sentry + Docker
npm create chassis my-app -- --preset fullstack --yes   # the same, plus a Next.js front end
npm create chassis my-api                               # interactive — pick a preset
npm create chassis my-api -- --db postgres --auth jwt --mcp   # à la carte
npm create chassis my-api -- --bare                     # nothing — standalone build

Or use the template directly:

git clone https://github.com/dvd90/chassis.git my-api
cd my-api && npm install && npm run dev

That's it — no database, no env file, no accounts needed. Open http://localhost:8000/status.

New here? Follow the step-by-step getting-started guide — zero to a tested API in ~10 minutes.

For AI agents

Every path is non-interactive: --yes and --bare never prompt, and the CLI skips prompts automatically whenever stdin isn't a TTY. One command produces a project that already typechecks, lints and tests green.

  • llms.txt — the project, its conventions and its docs index, in one fetch
  • llms-full.txt — every documentation page, concatenated
  • AGENTS.md — the conventions to follow when writing code in a Chassis project, and the definition of done

Generated projects carry AGENTS.md, CLAUDE.md, llms.txt and an add-resource skill, so whichever agent opens one writes code that matches the rest of the codebase rather than fighting it.

Features

  • TypeScript 6 + Express 5 — strict types, async errors caught automatically
  • Decorator routing — @route / @protectedRoute on controller methods, controllers auto-mount
  • Consistent responses — req.resHandler.ok() / .notFound() / .validation() with structured logging
  • Request correlation — every request gets a callId (or propagates x-call-id), echoed in responses and logs
  • Typed, validated config — zod-checked environment via src/config; the app refuses to boot on bad config
  • Zod input validation — validate({ body, query, params }) middleware with structured 400s
  • Pick-your-stack scaffolder — presets or à la carte: database + ORM (Mongo/Postgres/SQLite), auth (Auth0/Clerk/local), a Next.js front end, Sentry, MCP, x402 — the CLI prunes everything else so package.json carries only what you chose
  • Opt-in integrations — every module enables by env var, never required
  • Payment-gated routes — @paidRoute('get', '/report', '$0.01') via the x402 protocol (opt-in)
  • Optional Next.js front end — --web adds an App Router app and makes the project an npm-workspaces monorepo (apps/api + apps/web); the auth provider you picked is wired on both sides
  • MCP server — expose your API to AI agents as MCP tools (npm run mcp, opt-in)
  • Health endpoints — /healthz (liveness) and /readyz (readiness, checks enabled integrations)
  • Graceful shutdown — drains connections and closes integrations on SIGTERM/SIGINT
  • Vitest + supertest — fast tests against the pure app factory, no server or DB needed
  • DB-aware code generator — npm run gen user scaffolds a controller + test wired to your ORM (Drizzle or Mongoose)
  • Production Docker — multi-stage build, non-root user, plus docker-compose with your database for dev
  • CI + Renovate — GitHub Actions verify pipeline and automated dependency updates
  • AI-agent ready — ships AGENTS.md, CLAUDE.md, llms.txt, and an add-resource skill so agents write code that matches the conventions (see below)

AI-agent ready

Most people scaffolding a backend today have an AI agent in the loop. Chassis is built so that agent-written code reads like hand-written code — because the framework gives agents rails and a verifiable finish line:

  • AGENTS.md + CLAUDE.md ship in every project — Claude Code, Cursor, Copilot, and Codex pick them up automatically and follow the conventions (thin controllers, resHandler responses, throw AppError, config in one place).
  • One obvious place for everything means agent output converges on the same shape a maintainer would write — that's what keeps it readable.
  • npm run verify (strict TypeScript + ESLint + tests) is a deterministic quality gate agents iterate against until green.
  • .claude/skills/add-resource turns "add a books resource" into one consistent, checklisted operation.
  • llms.txt gives doc-fetching tools a compact map of the conventions.

Nothing to install — it's all in the scaffold. See AGENTS.md.

Scripts

CommandWhat it does
npm run devStart with hot reload (tsx watch)
npm test / npm run test:watchRun the vitest suite
npm run verifyTypecheck + lint + test (CI runs this)
npm run build / npm startCompile to dist/ and run production build
npm run gen <Name>Generate a controller + test
npm run lint / npm run formatESLint / Prettier

Enabling integrations

Copy .env.example to .env. Each integration turns on when its variables are set — and stays completely dormant otherwise:

IntegrationEnable by settingWhat you get
MongoDBMONGODB_URIMongoose connection, readiness check, graceful disconnect
Auth0AUTH0_DOMAIN + AUTH0_AUDIENCEJWT verification on every @protectedRoute
SentrySENTRY_DSNAutomatic error reporting from the central error handler

Using a different IdP? Call setAuthProvider([...yourMiddleware]) at boot and @protectedRoute uses it — see src/core/auth.ts.

Sign in without a third party

Local sign-in ships in three variants — emailed link, the classic credential form, or both. Run npm create chassis --help to see the --auth values, or read Authentication. Whichever you pick, they share one session layer.

POST /auth/magic/request  {email, returnTo?}   → 202, identical for every address
GET  /auth/magic/:token                        → confirm page — consumes nothing
POST /auth/magic/redeem   {token}              → session + redirect
POST /auth/magic/code     {email, code}        → same, from the other device
POST /auth/refresh | /auth/logout | /auth/revoke-all

Four things worth knowing about the emailed-link flow:

  • GET never spends a token. Mail security scanners prefetch links, and a single-use token burned by a scanner is how this feature usually breaks in production. Redemption is a POST, on a click.
  • Every email carries a six-digit code too, so someone who asks on a laptop and reads their mail on a phone can still finish on the laptop.
  • The request endpoint will not tell you who has an account — same body, same timing, every address.
  • Refresh tokens rotate on every use, and replaying a spent one revokes the whole session family. Sliding SESSION_IDLE, hard SESSION_ABSOLUTE cap.
VariableDefault
JWT_SECRET(required)
SESSION_IDLE / SESSION_ABSOLUTE30d / 90d
MAGIC_TOKEN_TTL / MAGIC_CODE_ATTEMPTS15m / 5
MAGIC_LINK_BASE_URLhttp://localhost:8000
SMTP_URLunset → logs the email

Chassis binds no email or SMS provider — bind yours through setMailTransport() or setSmsTransport(). Proving an address fires one hook, setOnVerified(), and that is the whole extension surface: consent and onboarding are yours.

Guides: magic link · sessions · transports

Project structure

src/
├── config/          # zod-validated env → typed config + feature flags
├── core/            # the framework: Routable, decorators, responses, errors, validation
├── middleware/      # callId correlation, dev request logging
├── integrations/    # opt-in modules: mongo, auth0, sentry
├── controllers/     # your endpoints — exported classes auto-mount
├── __tests__/       # vitest + supertest
├── app.ts           # pure app factory (no I/O — trivially testable)
└── server.ts        # boot: integrations → listen → graceful shutdown

Documentation

Read them at dvd90.github.io/chassis — searchable, one page. The source lives in docs/ and the site is generated from it, so the two can never disagree:

Docker

docker compose up --build     # API + MongoDB
docker build -t my-api .      # production image only

License

MIT

Frequently asked questions

What is Chassis?

Scaffold an Express 5 + TypeScript backend: database, auth, optional Next.js front end.

How do I install Chassis?

It runs on your machine. In Claude Code: claude mcp add chassis -- npx -y chassis-mcp@0.1.2. For other clients, paste the JSON configuration from this page into their MCP settings.

Does Chassis need an API key?

Its registry entry lists no required key or secret. Some features may still need an account with the service it connects to.

Is Chassis open source?

Yes. Its code is on GitHub under the MIT license.

Who maintains Chassis?

It is published by dvd90. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.