An OpenAPI 3.1 REST framework for Node.js. You describe resources and operations; arrest serves them, validates them against JSON Schema, authorizes them, documents them as an OpenAPI document — and, if you want, exposes them to AI agents as MCP tools, with the same validation and the same authorization as the REST endpoints.
- OpenAPI 3.1 first — the document is generated from your definitions, not maintained beside them, with JSON Schema 2020-12 validation of every request
- MongoDB CRUD out of the box — six operations per collection, plus RQL querying, projections, sorting and pagination headers
- One authorization decision — OAuth2 scopes or CASL abilities, enforced on requests,
reflected in
openapi.json?filter=authorizedand in the MCP tool list, from a single method - Record- and field-level rules — CASL conditions become part of the MongoDB query; CASL fields redact responses and reject write bodies
- MCP server — expose chosen operations as tools, grouped in independently scoped bundles
- JSON-RPC — for the calls that don't fit REST
- Extensible by design — a seven-stage operation pipeline, and
Resource/Operationsubclassing as a first-class path - Express-native — mount it in an app you own, or let it own the server
- TypeScript, ESM — full type definitions, native ES modules
- Node.js >= 20.0.0
- MongoDB 7.x or later, if you use
MongoResource
npm install arrest # or: pnpm add arrest / yarn add arrestTypeScript projects need "module": "NodeNext" and, for the @rpc decorator,
"experimentalDecorators": true. See
Installation and setup.
import { API, MongoResource } from 'arrest';
const api = new API({ title: 'My API', version: '1.0.0' });
api.addResource(new MongoResource('mongodb://localhost:27017/mydb', { name: 'Person', namePlural: 'People' }));
await api.listen(3000);That serves a full CRUD API and its own documentation:
GET /people |
list, with RQL filtering (q), limit, skip, fields, sort, and JSON/JSONL/CSV output |
POST /people |
create |
GET /people/{id} |
read one |
PUT /people/{id} |
update |
PATCH /people/{id} |
RFC 6902 JSON Patch |
DELETE /people/{id} |
delete |
GET /openapi.json |
the OpenAPI 3.1 document describing all of it |
$ curl -s localhost:3000/people -H 'content-type: application/json' \
-d '{"name":"Ada Lovelace","email":"ada@example.com","country":"GB"}'
{"name":"Ada Lovelace","email":"ada@example.com","country":"GB","_id":"6a7448e1ba3533ca10cf6b9f"}
$ curl -s 'localhost:3000/people?q=eq(country,GB)&fields=name,country&limit=10'
[{"name":"Ada Lovelace","country":"GB"}]Add a schema and every request is validated against it, in both the document and the code path:
api.registerSchema('person', {
type: 'object',
required: ['name', 'email'],
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 0 },
},
additionalProperties: false,
});
api.addResource(
new MongoResource(db, { name: 'Person', namePlural: 'People', requestSchema: { $ref: 'person' }, responseSchema: { $ref: 'person' } })
);The manual lives in docs/ and is in three parts:
- Guide — how arrest works. Architecture, the OpenAPI document, schemas, the security model, Express integration, errors.
- Tutorial — a fifteen-chapter course
building one application, from
new API()to an MCP server and a production shape. The code is in examples/tutorial/ and type-checked in CI. - Reference — the complete surface, one page per module.
Start with the introduction if arrest is new to you, or with chapter 00 to build something immediately.
- RQL querying —
q=and(eq(country,IT),gt(age,40))translated to MongoDB, with an aggregation pipeline when needed - Authorization — scopes or CASL abilities, one decision reused by request enforcement, document filtering and MCP tool listing
- Field and record redaction — declare fields and conditions once; responses are filtered and forbidden writes refused
- MCP server — opt-in per resource, named bundles, per-tool descriptions and schemas
- Output formats — JSON, JSONL and CSV from the same operation
- JSON Patch — RFC 6902 translated to atomic MongoDB updates
- The pipeline — seven override points between request and response
- Custom operations and resources —
getCustomInfoplus a handler, and you have a documented, validated, authorized endpoint - JSON-RPC —
@rpc-decorated methods on a single endpoint - Dynamic schemas and resources — schemas and MCP tools resolved per request
Contributions are welcome. The project uses pnpm and requires 100% test coverage — statements, branches, functions and lines — which CI enforces.
pnpm install
pnpm run build
pnpm test # mocha; MongoDB tests start a container via mongodoki
pnpm run check-coverage # must report 100%
pnpm run check:examples # type-checks the tutorial applicationTests are written in TypeScript under test/ts/ and compiled before running. Commit with
conventional commits, branch from master, and open a pull request.
MIT — see LICENSE.
- jsonref — JSON Reference resolution
- openapi-police — OpenAPI and JSON Schema validation
- @vivocha/scopes — the scope grammar arrest authorizes with