Welcome to Mokkify - a self-hosted RestAPI mocking service built with Next.js. Mokkify provides a flexible response builder and templating system for crafting your mocks, as well as support for Relay requests to an external hook to simulate various scenarios, like DLR. We've done our best to make the interface intuitive and easy to use.
Demo admin / admin
- 🔁 RestAPI mocking
- 🏗️ Self-hosted
- ⚡ In-memory endpoint caching and batched log writes. 2,500+ rps on a single node
- 🧭 Path parameters and wildcards:
/users/:id,/files/* - 🧩 Flexible response builder and templates with variables
- 🎛️ Custom response headers and content types (JSON, XML, plain text, HTML, CSV)
- 🌐 CORS out of the box (preflight, custom headers, credentials)
- 📥 OpenAPI / Swagger import: generate endpoints from a spec
- ⏲️ Response delay emulation
- 🔄 Relay request support with external hooks
- 🔮 Intuitive interface with light & dark themes
- 🔐 Authorization
- 🤖 Agent-ready: API keys, a published OpenAPI contract, and a built-in MCP server (
/mcp) - 📈 Endpoint RPS graphics
- 🗄️ Dump and restore configuration
Next.js 16 (Turbopack) · React 19 · Tailwind CSS 4 + shadcn/ui · Sequelize + SQLite (WAL)
- Node.js >= 20.17
- pnpm 10
- SQLite3
First, clone the repository:
git clone https://github.com/Wavix/Mokkify.gitThen, navigate to the project directory and install the necessary dependencies:
cd Mokkify
pnpm install
pnpm cli dbcreate
pnpm cli useradd <login> <password>After that, start the project in development mode:
pnpm devOr build and run the production server:
pnpm build
pnpm startOpen http://localhost:3000 with your browser to see the result.
Response templates (and relay payloads) support variables that are resolved per request:
| Variable | Value |
|---|---|
@uuid |
Random UUID v4 |
@date |
Current date/time (ISO 8601) |
@dateYYYYMMDD |
Current date as YYYYMMDD |
@unix |
Current unix timestamp |
@request.field.nested |
Value from the request body or query string |
@response.field |
Value from the mock response body (relay payloads) |
@path.param |
Path parameter value (/users/:param); wildcard tail: @path.wildcard |
Environment variables (all optional):
| Variable | Default | Description |
|---|---|---|
JWT_SECRET |
built-in dev secret | Secret used to sign auth tokens. Set your own in production. |
DATABASE_PATH |
database.sqlite |
Path to the SQLite database file (mount a volume here in Docker). |
LOG_RETENTION_DAYS |
30 |
Request logs older than this are purged hourly. 0 disables the purge. |
MOKKIFY_SELF_ORIGIN |
http://127.0.0.1:${PORT:-3000} |
Loopback origin the verify endpoint uses for its internal self-call. Override only if the app can't reach its own /api/* on the default. |
A GET /health endpoint (no auth) reports service and database status for load balancers and container healthchecks.
Beyond the browser UI, Mokkify exposes a machine-facing surface so agents (or any client) can configure and test mocks programmatically, without clicking through webhooks by hand.
/backend/* is protected. In addition to the UI's JWT session, you can mint long-lived API keys:
- Create one in the UI (Settings → API Keys) or via
POST /backend/api-keywith a JWT. - The key is returned once as
<key_id>.<secret>— only a bcrypt hash of the secret is stored, so copy it immediately. - Send it as
Authorization: Bearer <key_id>.<secret>on every request. Revoke or deactivate keys from the same screen.
GET /openapi serves the full OpenAPI 3.1 contract (no auth) describing every /backend/* operation. Point Swagger UI, code generators, or an agent's tool loader at it.
Two operations cover the whole "make a mock, then prove it works" loop:
POST /backend/mock— atomically creates the response template and its endpoint in one call.POST /backend/mock/{endpointId}/verify— fires the mock server-side and returns its synchronous response plus the correlated log row for that exact request.
Mokkify speaks MCP natively: one tool per /backend/* operation, generated from the OpenAPI contract — no hand-written tools. The same tool set is served over two transports.
The MCP server is built into the app at POST /mcp — nothing to install or run. Point an MCP client at a running Mokkify with an API key:
claude mcp add --transport http mokkify http://localhost:3000/mcp \
--header "Authorization: Bearer <key_id>.<secret>"or in a JSON client config:
The endpoint is stateless (POST-only, no sessions), so any replica can answer. Settings → API Keys shows a ready-to-paste config for the current origin. File-upload operations (dump restore, OpenAPI import) take the raw file content inline via file_content instead of a local path.
For MCP clients without HTTP transport, or to inspect the tool set offline, mcp/ is a standalone stdio server consuming the same contract. Build it first (dist/ and node_modules/ are gitignored):
cd mcp
pnpm install
pnpm build # -> mcp/dist/index.jsRegister over stdio, pointing at a running Mokkify and an API key:
{
"mcpServers": {
"mokkify": {
"command": "node",
"args": ["/absolute/path/to/mokkify/mcp/dist/index.js"],
"env": {
"MOKKIFY_BASE_URL": "http://localhost:3000",
"MOKKIFY_API_KEY": "<key_id>.<secret>"
}
}
}
}On startup the stdio server logs which spec source it used (remote: when Mokkify is reachable, otherwise a fallback to the bundled public/openapi.yaml) and how many tools it registered. Bumped Mokkify to a version with new endpoints? Tools regenerate from the fresh spec — the HTTP endpoint picks it up on deploy, the stdio server on restart. See mcp/README.md for the full stdio reference.
Once the MCP is registered, ask the agent to replace a project's external integrations with mocks — no hand-wired webhooks. A prompt like:
Scan this project for outbound HTTP integrations. For each, use the
mokkifyMCP to create a mock with a realistic response under its own path prefix, then repoint the integration's base URL at Mokkify and run the integration tests.
The agent discovers the calls and repoints your config itself; the MCP does the Mokkify side — createMock per integration (namespaced, e.g. POST https://api.stripe.com/v1/charges → mock POST /stripe/v1/charges, base URL → http://localhost:3000/api/stripe) and verifyMock to confirm each. Feed it real response examples where the shape isn't obvious in code, and split conditional behavior into one mock per branch.
Response compression is intentionally disabled in the app server (compress: false) - enable gzip in nginx instead.
upstream webhook {
server 127.0.0.1:3000;
}
location / {
proxy_set_header Host <Your host>;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://webhook;
}
If you encounter any issues or have questions about using Mokkify, please create an "Issue" in this repository, and we'll be glad to assist you.
If you wish to contribute to the project's development, feel free to fork the repository and submit pull requests.
This project is licensed under the MIT License - see the LICENSE file for more information.


{ "mcpServers": { "mokkify": { "type": "http", "url": "http://localhost:3000/mcp", "headers": { "Authorization": "Bearer <key_id>.<secret>" } } } }