A TUI-based HTTP mock server for development
  • Rust 92.3%
  • Shell 7.7%
Find a file
Ivan Exposito 8d7f8ea31b
Some checks failed
CI / Clippy Lints (push) Failing after 6s
CI / Format Check (push) Failing after 35s
CI / Unit Tests (push) Failing after 36s
CI / Build Verification (push) Failing after 35s
CI / E2E Tests (push) Has been skipped
CI / Security Audit (push) Failing after 32s
docs: design for uuid template fix and nil variant
2026-04-18 16:02:40 +02:00
.forgejo/workflows feat: add cargo-binstall, deb/rpm packaging, and crates.io CI publish 2026-03-09 18:57:09 +01:00
dist feat: add cargo-binstall, deb/rpm packaging, and crates.io CI publish 2026-03-09 18:57:09 +01:00
docs/superpowers/specs docs: design for uuid template fix and nil variant 2026-04-18 16:02:40 +02:00
examples feat: add JWT generation templates and claim-based request matching 2026-03-20 21:07:38 +01:00
src fix: use wl-copy/xclip for clipboard on Linux instead of arboard 2026-03-28 21:45:26 +01:00
tests/e2e fix: use sub=user-123 in e2e JWT tests to match user-.* regex 2026-03-20 21:40:58 +01:00
.gitignore feat: add headless mode for CI e2e tests 2026-02-04 22:15:33 +01:00
Cargo.lock feat: add JWT generation templates and claim-based request matching 2026-03-20 21:07:38 +01:00
Cargo.toml feat: add JWT generation templates and claim-based request matching 2026-03-20 21:07:38 +01:00
CLAUDE.md feat: add JWT generation templates and claim-based request matching 2026-03-20 21:07:38 +01:00
Cross.toml fix: make CI/CD workflows compatible with Forgejo Actions 2026-02-03 22:32:09 +01:00
LICENSE chore: prepare for crates.io publishing 2026-02-04 22:57:06 +01:00
llms.txt feat: add compound duration shorthand and cookie-based JWT extraction 2026-03-20 21:30:31 +01:00
mockr-schema.json feat: add compound duration shorthand and cookie-based JWT extraction 2026-03-20 21:30:31 +01:00
README.md feat: add compound duration shorthand and cookie-based JWT extraction 2026-03-20 21:30:31 +01:00
rust-toolchain.toml fix: make CI/CD workflows compatible with Forgejo Actions 2026-02-03 22:32:09 +01:00

mockr-tui

                      _            _         _
 _ __ ___   ___   ___| | ___ __   | |_ _   _(_)
| '_ ` _ \ / _ \ / __| |/ / '__|  | __| | | | |
| | | | | | (_) | (__|   <| |     | |_| |_| | |
|_| |_| |_|\___/ \___|_|\_\_|      \__|\__,_|_|

Crates.io License: MIT

A TUI-based HTTP mock server for development.


Features

Core Advanced Developer Experience
Path parameters ({id}) Weighted multi-response Terminal UI with live logs
Catch-all patterns ({*path}) Conditional responses Hot-reload configuration
CORS support Response templating Runtime port settings
Configurable delays JSONPath body matching Request filtering & detail search
JWT generation & claim matching JSON syntax highlighting
Export log to JSON / copy curl
Endpoint detail preview
Stats bar with request counts
Tree view with endpoint grouping

Quick Start

# 1. Install
cargo install mockr-tui

# 2. Create config
mockr --init

# 3. Run
mockr

That's it! Your mock server is running at http://127.0.0.1:8080.



Installation

Linux

One-line install (recommended — downloads pre-built binary):

curl -fsSL https://code.byjokese.net/byjokese/mockr-tui/raw/branch/main/dist/install.sh | sh
Other options

Debian / Ubuntu (.deb):

# Download from releases page, then:
sudo dpkg -i mockr-<version>-amd64.deb

Fedora / RHEL (.rpm):

# Download from releases page, then:
sudo rpm -i mockr-<version>-x86_64.rpm

Arch Linux (AUR):

yay -S mockr-tui-bin  # Pre-built binary
yay -S mockr-tui      # From source

Cargo binstall (downloads pre-built binary via cargo):

cargo binstall mockr-tui

Cargo install (builds from source):

cargo install mockr-tui

Specific version:

MOCKR_VERSION=0.4.0 curl -fsSL https://code.byjokese.net/byjokese/mockr-tui/raw/branch/main/dist/install.sh | sh

Custom install directory:

INSTALL_DIR=$HOME/.local/bin curl -fsSL https://code.byjokese.net/byjokese/mockr-tui/raw/branch/main/dist/install.sh | sh

macOS

cargo binstall mockr-tui   # Fastest — downloads pre-built binary
# or
cargo install mockr-tui     # Builds from source

Requires Rust toolchain. Install via rustup.rs if needed.

Windows

PowerShell (recommended):

irm https://code.byjokese.net/byjokese/mockr-tui/raw/branch/main/dist/install.ps1 | iex
Other options

Cargo binstall:

cargo binstall mockr-tui

Cargo install:

cargo install mockr-tui

Specific version:

$env:MOCKR_VERSION="0.4.0"; irm https://code.byjokese.net/byjokese/mockr-tui/raw/branch/main/dist/install.ps1 | iex

Build from Source

git clone https://code.byjokese.net/byjokese/mockr-tui.git
cd mockr-tui
cargo install --path .

Updating

Re-run the same install command — the script detects your current version and updates if a newer release is available.

Linux:

curl -fsSL https://code.byjokese.net/byjokese/mockr-tui/raw/branch/main/dist/install.sh | sh

Windows:

irm https://code.byjokese.net/byjokese/mockr-tui/raw/branch/main/dist/install.ps1 | iex

Cargo:

cargo install mockr-tui

Usage

mockr                    # Use default mockr.json
mockr -c config.json     # Use specific config file
mockr -p 3000            # Override port
mockr --headless         # Run without TUI (server only)

CLI Options

Option Default Description
-c, --config <FILE> mockr.json Path to configuration file
-p, --port <PORT> from config Override server port
-H, --host <HOST> from config Override server host
--no-watch false Disable hot reload
--headless false Run HTTP server only (no TUI)
--init - Create a starter configuration file

Configuration

Basic Example

{
  "server": {
    "host": "127.0.0.1",
    "port": 8080
  },
  "endpoints": [
    {
      "name": "Get Users",
      "path": "/api/users",
      "method": "GET",
      "response": {
        "status": 200,
        "body": [
          { "id": 1, "name": "Alice" },
          { "id": 2, "name": "Bob" }
        ]
      }
    }
  ]
}

Server Options

Option Default Description
host 127.0.0.1 Host to bind to
port 8080 Port to listen on
cors.enabled true Enable CORS
cors.origins ["*"] Allowed origins
cors.methods ["GET", "POST", ...] Allowed methods
cors.allow_credentials true Allow credentials (cookies, auth headers). When true with wildcard origins, the server mirrors the request Origin header instead of sending *
jwt_secret mockr-secret HS256 secret for {{jwt}} generation and jwt_claims verification

Endpoint Options

Option Required Description
path Yes URL path pattern
method Yes HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, ANY)
name No Human-readable name
description No Description
enabled No Active state (default: true)
response No Single response configuration
responses No Multiple weighted/conditional responses
delay_ms No Fixed response delay (ms)
delay_range_ms No Random delay range [min, max]
priority No Higher priority matches first (default: 0)

Path Patterns

/api/users           # Exact match
/api/users/{id}      # Path parameter - captures "id"
/files/{*path}       # Catch-all - captures entire remaining path

Response Options

Option Default Description
status 200 HTTP status code
headers {} Response headers
body null Response body (string or JSON)
body_file - Path to file containing response body
content_type application/json Content-Type header

Request Matching

Match requests based on headers, query parameters, or body content:

{
  "path": "/api/data",
  "method": "POST",
  "request": {
    "headers": { "Authorization": "Bearer.*" },
    "query_params": { "type": "admin" },
    "body_contains": "important",
    "body_json_path": { "$.user.role": "admin" },
    "jwt_claims": { "role": "admin" },
    "jwt_token_from": "header:Authorization"
  },
  "response": {
    "status": 200,
    "body": { "matched": true }
  }
}
Matcher Description
headers Match request headers (supports regex)
query_params Match query string parameters
body_contains Match if body contains substring
body_json_path Match JSON body using JSONPath expressions
jwt_claims Match decoded JWT token claims (regex patterns)
jwt_token_from Where to extract JWT: header:Authorization (default), header:X-Custom, query:param, cookie:name

Response Templating

Response bodies and headers support dynamic template variables:

Variable Description
{{timestamp}} ISO 8601 timestamp
{{timestamp_unix}} Unix timestamp (seconds)
{{uuid}} Random UUID v4
{{request.method}} HTTP method
{{request.path}} Request path
{{request.query}} Query string
{{request.header.Name}} Request header value
{{path.param}} Path parameter value
{{jwt}} HS256 JWT with default claims
{{jwt(key=val,...)}} HS256 JWT with custom claims (exp accepts 1h, 30m, 7d, 1h30m)
{{jwt.claim}} Extract claim from incoming request's JWT
{
  "path": "/api/users/{id}",
  "method": "GET",
  "response": {
    "headers": { "X-Request-Id": "{{uuid}}" },
    "body": {
      "id": "{{path.id}}",
      "requested_at": "{{timestamp}}"
    }
  }
}

Multiple Responses

Weighted random selection:

{
  "path": "/api/flaky",
  "method": "GET",
  "responses": [
    { "status": 200, "body": { "ok": true }, "weight": 8 },
    { "status": 500, "body": { "error": "Server error" }, "weight": 2 }
  ]
}

Conditional responses:

{
  "path": "/api/users",
  "method": "GET",
  "responses": [
    {
      "when": { "headers": { "X-Admin": "true" } },
      "status": 200,
      "body": { "users": ["all", "users"] }
    },
    {
      "status": 200,
      "body": { "users": ["public", "only"] }
    }
  ]
}

The first matching when condition is selected; responses without when act as fallback.


Keyboard Shortcuts

Key Action
Tab / Shift+Tab Next / previous panel
1 / 2 / 3 Jump to panel
/ k, / j Navigate up/down
PgUp / PgDn Page up/down
Home / End Go to top/bottom
Ctrl+u / Ctrl+d Half-page scroll (Detail View)
Enter View details / expand/collapse group (Tree View)
Space Toggle endpoint or group
t Toggle tree/list view (Endpoints panel)
/ h, / l Expand/collapse group (Tree View)
r Reload config
c Clear request log
e Export log to JSON
y Copy curl command to clipboard
Y Copy response body to clipboard
/ Start filtering (Request Log) / search (Detail View)
n / N Next / previous search match (Detail View)
s Settings
? / F1 Show help
Esc Close popup / Clear filter or search
q / Ctrl+c Quit

Editor Autocompletion

The --init command includes a $schema reference for JSON autocompletion. If your editor reports the URL as untrusted, add the domain to your editor's trusted schemas:

VS Code — add to settings.json:

{
  "json.schemas": [
    {
      "fileMatch": ["mockr.json"],
      "url": "https://code.byjokese.net/byjokese/mockr-tui/raw/branch/main/mockr-schema.json"
    }
  ]
}

Alternatively, download mockr-schema.json to your project and use "$schema": "./mockr-schema.json".

AI Integration

mockr-tui ships with an llms.txt file — a machine-readable reference that lets AI assistants (Claude, Copilot, Cursor, etc.) generate valid mockr configurations. Just tell your AI to "mock a REST API for [your use case]" and point it at the file.

For Claude Code users, the included CLAUDE.md is picked up automatically.

License

MIT