Skip to content
Back to skills

Mockoon

ASecurity

Mockoon runs mock REST APIs on your machine from a JSON environment file: a desktop app designs them and a CLI serves them without a GUI. Use when the user wants to fake a backend for frontend work, mock an OpenAPI spec, return dynamic responses with templating and rules, or start a mock server in CI or Docker. Also use when the user mentions "mockoon," "API mocking," "mock server," "mock API," "OpenAPI mock," or "local API simulation." For programmatic HTTP mocking, see wiremock.

  • 142 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 6, 2026
toolsrustgobashnodedockertestinggitapidatabasefrontend

Works with

  • terminal
  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add TerminalSkills/skills --skill mockoon --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mockoon?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Mockoon
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/terminalskills-mockoon/badge)](https://www.skillsdirectory.com/skills/terminalskills-mockoon)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: mockoon
description: >-
  Mockoon runs mock REST APIs on your machine from a JSON environment file:
  a desktop app designs them and a CLI serves them without a GUI. Use when
  the user wants to fake a backend for frontend work, mock an OpenAPI spec,
  return dynamic responses with templating and rules, or start a mock server
  in CI or Docker. Also use when the user mentions "mockoon," "API mocking,"
  "mock server," "mock API," "OpenAPI mock," or "local API simulation." For
  programmatic HTTP mocking, see wiremock.
license: Apache-2.0
compatibility: "Node.js 18+ for the CLI (@mockoon/cli 9); desktop app on Windows, macOS and Linux"
metadata:
  author: terminal-skills
  version: "1.1.0"
  category: development
  repository: https://github.com/mockoon/mockoon
  tags:
    - api-mocking
    - mock-server
    - openapi
    - development
---

# Mockoon

## Overview

Mockoon is an open-source tool for running mock API servers locally. A mock is an *environment*: one JSON file holding routes, responses, rules and data. The desktop app edits and runs environments; the CLI (`mockoon-cli`) serves the same files headlessly in a terminal, CI job or container. Responses can be static, generated with Handlebars templating and Faker, chosen by rules on the request, or backed by an in-memory data bucket that behaves like a small CRUD database.

## Instructions

### Initial Assessment

1. **Purpose** — Frontend development, integration testing, or demo?
2. **API spec** — Do you have an OpenAPI/Swagger spec to import?
3. **Complexity** — Static responses or dynamic (templating, rules)?
4. **Environment** — Local development, CI, or Docker?

### CLI Setup

```bash
# Add the CLI to the project (the binary is called mockoon-cli)
npm install --save-dev @mockoon/cli
npx mockoon-cli start --data ./mocks/storefront.json --port 3001

# Or install it once for all projects
npm install -g @mockoon/cli
```

The desktop app is optional: `brew install --cask mockoon` (macOS), `winget install mockoon` (Windows), `snap install mockoon` (Linux). It stores each environment as a JSON file — right-click an environment and choose "Show in folder" to find it.

### Environment Configuration

`mocks/storefront.json` — a data bucket, a CRUD route on top of it, and a route with conditional responses:

```json
{
  "uuid": "f5420a7c-39c1-4441-a915-8b8e992c9aa8",
  "lastMigration": 33,
  "name": "Storefront API",
  "endpointPrefix": "api",
  "port": 3001,
  "hostname": "127.0.0.1",
  "data": [
    {
      "uuid": "0e938a92-13f3-4763-8728-720e9a7a582b",
      "id": "prod",
      "name": "products",
      "value": "[\n  {{#repeat 3}}\n  { \"id\": \"{{faker 'string.uuid'}}\", \"name\": \"{{faker 'commerce.productName'}}\", \"priceCents\": {{faker 'number.int' min=500 max=9900}} }\n  {{/repeat}}\n]"
    }
  ],
  "routes": [
    {
      "uuid": "5f86de43-cd07-425b-911b-0c9fe72d144e",
      "type": "crud",
      "endpoint": "products",
      "responses": [
        { "uuid": "1493969d-e219-401e-905d-e14c1cb99f86", "bodyType": "DATABUCKET", "databucketID": "prod", "default": true }
      ]
    },
    {
      "uuid": "18b5ebe3-9ef2-4662-9837-ff33b4cb0280",
      "type": "http",
      "method": "get",
      "endpoint": "orders/:id",
      "responses": [
        {
          "uuid": "2de84593-5bd0-402e-9931-1db212693cb1",
          "statusCode": 200,
          "label": "Found",
          "headers": [{ "key": "Content-Type", "value": "application/json" }],
          "body": "{ \"id\": \"{{urlParam 'id'}}\", \"status\": \"shipped\", \"placedAt\": \"{{now 'yyyy-MM-dd'}}\" }",
          "default": true
        },
        {
          "uuid": "5614aaa1-1942-4a87-b143-de99ae9fe737",
          "statusCode": 401,
          "label": "No token",
          "headers": [{ "key": "Content-Type", "value": "application/json" }],
          "body": "{ \"error\": \"Unauthorized\" }",
          "rules": [{ "target": "header", "modifier": "Authorization", "operator": "null", "value": "", "invert": false }]
        },
        {
          "uuid": "c75cf058-59ac-4840-9124-85aea071a2b0",
          "statusCode": 404,
          "label": "Unknown order",
          "headers": [{ "key": "Content-Type", "value": "application/json" }],
          "body": "{ \"error\": \"Order not found\" }",
          "rules": [{ "target": "params", "modifier": "id", "operator": "equals", "value": "ord_missing", "invert": false }]
        }
      ]
    }
  ]
}
```

This file is trimmed for reading. `mockoon-cli start` loads a copy, fills every omitted key with its default and leaves the file on disk untouched; `mockoon-cli validate --data mocks/storefront.json` is strict and lists each omitted key. Files saved by the desktop app or produced by `mockoon-cli import` are complete. Keep `lastMigration` (33 for version 9.9) — without it the CLI stops to ask whether to repair the file unless `--repair` is passed. Every `uuid` must be a real, unique UUID (`node -e "console.log(crypto.randomUUID())"`).

A CRUD route serves `GET`, `POST`, `PUT`, `PATCH` and `DELETE` on `/products` and `/products/:id` from the bucket. Changes live in memory until the server restarts. The list endpoint accepts `page`, `limit`, `sort`, `order`, `search` and filters such as `priceCents_gt=2000` or `name_like=Tote`, and returns `X-Total-Count` and `X-Filtered-Count` headers.

### Templating Helpers

A response body (or bucket value) is a Handlebars template:

```handlebars
{
  "id": "{{faker 'string.uuid'}}",
  "name": "{{faker 'person.fullName'}}",
  "email": "{{faker 'internet.email'}}",
  "createdAt": "{{now 'yyyy-MM-dd'}}",
  "quantity": {{faker 'number.int' min=1 max=20}},
  "request": {
    "method": "{{method}}",
    "pathId": "{{urlParam 'id'}}",
    "search": "{{queryParam 'search'}}",
    "customerEmail": "{{body 'customer.email'}}",
    "auth": "{{header 'Authorization'}}"
  },
  "firstProduct": {{data 'products' '0'}},
  "productNames": [{{#each (dataRaw 'products')}}"{{name}}"{{#unless @last}}, {{/unless}}{{/each}}],
  "region": "{{getEnvVar 'MOCKOON_REGION' 'eu-west-1'}}"
}
```

`data` and `dataRaw` read a bucket by name. `getEnvVar` only sees variables that start with `MOCKOON_` unless `--env-vars-prefix` changes the prefix.

### Response Rules

Each response may carry `rules`; the first response whose rules match is served, otherwise the one marked `"default": true`. Within a response, `"rulesOperator": "AND"` requires all rules (the default is `OR`).

- **target:** `body`, `query`, `header`, `cookie`, `params`, `path`, `method`, `request_number`, `global_var`, `data_bucket`, `templating`
- **operator:** `equals`, `regex`, `regex_i`, `null`, `empty_array`, `array_includes`, `valid_json_schema`
- **modifier:** the property to read, such as a header name, a query parameter or a body path like `customer.email`
- **invert:** `true` negates the rule

```json
{ "target": "query", "modifier": "category", "operator": "regex_i", "value": "^(tea|coffee)$", "invert": false }
```

### OpenAPI

```bash
# Serve a spec directly (Swagger 2 / OpenAPI 3, JSON or YAML)
npx mockoon-cli start --data ./openapi.yaml --port 3001

# Convert it to an environment file to add rules and templating, or go the other way
npx mockoon-cli import --input ./openapi.yaml --output ./mocks/inventory.json --prettify
npx mockoon-cli export --input ./mocks/storefront.json --output ./storefront.openapi.yaml --format yaml
```

### Docker

```bash
# The image's entrypoint is "mockoon-cli start", so only flags follow the image name.
docker run -d --name mockoon \
  -p 3001:3001 \
  -v "$(pwd)/mocks/storefront.json:/data/storefront.json:ro" \
  mockoon/cli:latest \
  --data /data/storefront.json --port 3001 --hostname 0.0.0.0

# Or generate a Dockerfile that bundles the environment file
npx mockoon-cli dockerize --data ./mocks/storefront.json --port 3001 --output ./docker-build/Dockerfile
```

Check the generated Dockerfile before `docker build`: 9.9.0 still writes `FROM node:16-alpine`, on which CLI 9 fails to start (`No such built-in module: node:readline/promises`) — change that line to a current image such as `node:24-alpine`. Its entrypoint passes no `--hostname`, so the bundled file must say `"hostname": "0.0.0.0"` to be reachable through the published port.

### CI Integration

```yaml
# .github/workflows/mock-api.yml — integration tests against a Mockoon mock server
name: Integration Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: 24
      - run: npm ci
      - name: Start mock server
        uses: mockoon/cli-action@v3
        with:
          version: "9.9.0"
          data-file: "./mocks/storefront.json"
          port: 3001
      - run: npm test
        env:
          API_BASE_URL: http://127.0.0.1:3001/api
```

Without the action, start the CLI in the background (`npx mockoon-cli start --data ./mocks/storefront.json --port 3001 &`) and wait for the port before running tests.

## Examples

### Example 1: Mock a product catalog for frontend work

User: "The products API isn't ready. Give me a fake one on port 3001 that I can read from and write to."

Save the environment above as `mocks/storefront.json`, then:

```bash
npx mockoon-cli start --data ./mocks/storefront.json --watch
```

```text
{"app":"mockoon-server","environmentName":"Storefront API","level":"info","message":"Server started on port 3001", …}
```

```bash
curl -s "http://127.0.0.1:3001/api/products?limit=2&sort=priceCents&order=desc"
# [{"id":"68e6f816-…","name":"Fresh Ceramic Shoes","priceCents":9532},{"id":"5370b85f-…","name":"Luxurious Ceramic Fish","priceCents":6775}]

curl -s -X POST -H 'Content-Type: application/json' \
  -d '{"name":"Canvas Tote","priceCents":2400}' http://127.0.0.1:3001/api/products
# {"name":"Canvas Tote","priceCents":2400,"id":"863298e9-9005-4676-8773-db2b7f05330d"}
```

The new product is returned by later `GET` calls until the server restarts. `--watch` reloads the file when it changes.

### Example 2: Test error handling with rules

User: "I need the order endpoint to return 401 without a token and 404 for a missing order."

The `orders/:id` route above already encodes both cases:

```bash
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3001/api/orders/ord_1042
# 401
curl -s -H "Authorization: Bearer $ORDERS_API_TOKEN" http://127.0.0.1:3001/api/orders/ord_1042
# { "id": "ord_1042", "status": "shipped", "placedAt": "2026-10-01" }
curl -s -H "Authorization: Bearer $ORDERS_API_TOKEN" http://127.0.0.1:3001/api/orders/ord_missing
# { "error": "Order not found" }   (HTTP 404)
```

## Guidelines

- **Environment files are plain JSON** — no comments. An unparseable file fails with "This file is not a valid OpenAPI specification (JSON or YAML v2.0.0 and v3.0.0) or Mockoon environment".
- **Mind the braces in templates.** A helper followed directly by a JSON brace (`max=9900}}}`) is read by Handlebars as a triple-stash and fails with "Expecting 'CLOSE', got 'CLOSE_UNESCAPED'". Put a space before the closing brace.
- **Set `Content-Type` on every response**; without the header Mockoon answers `text/html`.
- **Bind to localhost.** An empty `hostname` listens on all interfaces. Use `127.0.0.1` on a workstation (or `--hostname 127.0.0.1`) and `0.0.0.0` only inside a container.
- **Admin API.** Every running mock exposes `/mockoon-admin/` (logs, state, environment variables) protected by a bearer token that is auto-generated and printed at startup. Pass `--admin-api-token "$MOCKOON_ADMIN_API_TOKEN"` to fix it, or `--disable-admin-api` when it is not needed.
- **Logs.** The CLI also writes `~/.mockoon-cli/logs/{mock-name}.log`; use `--disable-log-to-file` in CI and `--log-transaction` to log full requests and responses (credential headers are redacted).
- **Reproducible data.** `--faker-seed 42` makes Faker output a predictable sequence; `--faker-locale en_GB` changes the locale.
- **Keep the CLI as new as the app.** A file saved by a newer desktop version than the installed CLI is refused; upgrade `@mockoon/cli`. Older files are migrated in memory.
- **OpenAPI is lossy.** Rules and templating have no OpenAPI equivalent, so keep the Mockoon JSON as the source of truth once you add them. Use `--disable-external-refs` for untrusted specs so remote `$ref` URLs are not fetched.
- **When not to use it.** For mocks defined inside test code use MSW or WireMock; Mockoon fits a shared, long-running fake backend.

Files in this skill

  • SKILL.md5.9 KB
  • _scores.json1.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…