Headless Mode

CheatMD includes a --headless mode designed for programmatic integration with other tools, editors, and plugins (such as the VS Code and Obsidian extensions).

Instead of launching the interactive TUI, Headless Mode communicates entirely via a JSON-RPC interface over standard input and standard output.

Overview

When you launch CheatMD with --headless, it automatically resolves all variables that can be satisfied automatically (either through prefilled scope, default values, or successful shell evaluation).

If a variable requires user input (e.g., a picker list), the runner suspends execution and emits a JSON-RPC prompt request to stdout. The host application must present this prompt to the user and return their selection via stdin.

Usage

Start a headless session by passing --headless along with a precise query to isolate a single cheat:

cheatmd --headless -q "docker exec container"

JSON-RPC Protocol

1. prompt Request (Engine -> Host)

If a variable cannot be auto-resolved, CheatMD will emit a JSON-RPC request to stdout asking for the value.

Example Request:

{
  "jsonrpc": "2.0",
  "method": "prompt",
  "params": {
    "variables": [
      {
        "name": "container",
        "header": "Select container",
        "placeholder": "",
        "options": ["web_server", "db_server", "cache"],
        "multi": false
      }
    ]
  },
  "id": 1
}

The host application is responsible for reading this JSON, displaying a UI to the user (like a dropdown or an input field), and sending the result back to CheatMD.

2. Prompt Response (Host -> Engine)

The host responds by writing a JSON-RPC response to CheatMD’s stdin.

Example Response:

{
  "jsonrpc": "2.0",
  "result": {
    "values": {
      "container": "web_server"
    }
  },
  "id": 1
}

If the user cancels the prompt, the host can send an error response to abort the execution:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32000,
    "message": "User aborted"
  },
  "id": 1
}

3. completed Notification (Engine -> Host)

Once all variables are resolved, CheatMD finalizes the command and executes it (depending on your configured output mode). It then emits a completed notification to stdout and exits.

Example Notification:

{
  "jsonrpc": "2.0",
  "method": "completed",
  "params": {
    "status": "success",
    "command": "docker exec -it web_server /bin/sh",
    "stdout": "...",
    "stderr": "",
    "error": "",
    "exit_code": 0
  }
}

Error Handling

If CheatMD encounters a fatal error before or during execution, it will emit a completed notification with "status": "error" and the error message string populated.

Example Error Notification:

{
  "jsonrpc": "2.0",
  "method": "completed",
  "params": {
    "status": "error",
    "command": "",
    "stdout": "",
    "stderr": "",
    "error": "no executable cheats found in index",
    "exit_code": -1
  }
}

See also

  • [Shell Integration](/docs/shell integration) - other ways to integrate CheatMD
  • Dump - metadata export for external tools
  • Configuration - output modes and configuration options