Node CLI
@msw-dev-tool/node-cli gives AI agents and scripts machine-readable JSON control of a Node MSW Dev Tool session. Use it to select HTTP and WebSocket scenarios in a process that runs setupDevToolServer().
Configuration
Install
pnpm
pnpm add -D @msw-dev-tool/core @msw-dev-tool/node-cli mswConnect the runtime
import { setupDevToolServer } from "@msw-dev-tool/core/node";
import { handlers } from "./handlers";
const server = await setupDevToolServer(...handlers);
server.listen();Each server process writes a PID-named session snapshot to .msw-dev-tool/sessions/<pid>.json in its current working directory. Start the process first, list sessions, select the PID, and then pass that PID to each command.
msw-dev-tool sessions
msw-dev-tool --pid <pid> sessionAfter changing handler code, run msw-dev-tool --pid <pid> reset and verify the JSON result contains "pendingReset": false before issuing another command. Changes written while pendingReset is true can be replaced when the running process reloads its code. A normal process exit removes its session file; inspect and remove stale files after a crash before selecting a PID.
Commands & API
Every command prints machine-readable JSON to stdout. Handler IDs are JSON strings such as {"path":"/api/items","method":"get"}; use list to copy them safely.
HTTP scenarios
msw-dev-tool --pid <pid> list
msw-dev-tool --pid <pid> get '{"path":"/api/items","method":"get"}'
msw-dev-tool --pid <pid> set-behavior '{"path":"/api/items","method":"get"}' delay
msw-dev-tool --pid <pid> set-enabled '{"path":"/api/items","method":"get"}' false
msw-dev-tool --pid <pid> set-mock-enabled false
msw-dev-tool --pid <pid> set-custom-response '{"path":"/api/items","method":"get"}' --json '{"status":"200","contentType":"application/json","response":"[]","delay":100}'
msw-dev-tool --pid <pid> set-behavior '{"path":"/api/items","method":"get"}' 'custom response'
msw-dev-tool --pid <pid> add-temp --json '{"path":"/api/preview","method":"get","contentType":"application/json","status":"200","response":"{\\"ok\\":true}"}'
msw-dev-tool --pid <pid> remove-temp '{"path":"/api/preview","method":"get"}'
msw-dev-tool --pid <pid> reset{"ok":true,"handlers":[{"id":"{\\"path\\":\\"/api/items\\",\\"method\\":\\"get\\"}","path":"/api/items","method":"get","behavior":"default","enabled":true}],"mockEnabled":true}set-enabled <handlerId> <true|false> bypasses only that HTTP handler. set-mock-enabled <true|false>
is the global HTTP and WebSocket switch and returns the current mockEnabled value. Both preserve
individual behavior and response settings.
WebSocket scenarios
First discover endpoint and listener IDs, then pass the exact IDs returned by those commands to later mutations. Do not construct an endpoint ID from its URL.
msw-dev-tool --pid <pid> ws-list
endpoint_id="$(msw-dev-tool --pid <pid> ws-add-endpoint \
--json '{"kind":"string","value":"ws://localhost:8080/preview"}' \
| jq -r '.endpoint.endpointId')"
listener_id="$(msw-dev-tool --pid <pid> ws-add-listener "$endpoint_id" --json '{"behavior":{"preset":"default"},"response":{"type":"send","dataType":"string","value":"temp response","delay":300,"repeat":{"interval":500,"repetitions":3}},"customResponse":{"type":"send","dataType":"string","value":"custom response","delay":100}}' \
| jq -r '.listener.info.id')"
msw-dev-tool --pid <pid> ws-get-endpoint "$endpoint_id"
msw-dev-tool --pid <pid> ws-set-endpoint-enabled "$endpoint_id" false
msw-dev-tool --pid <pid> ws-set-listener-behavior "$listener_id" --json '{"preset":"close","options":{"code":4001,"reason":"test"}}'
msw-dev-tool --pid <pid> ws-set-listener-response "$listener_id" --json '{"type":"send","dataType":"string","value":"scheduled","delay":300,"repeat":{"interval":500,"repetitions":"Infinity"}}'
msw-dev-tool --pid <pid> ws-set-listener-enabled "$listener_id" false
msw-dev-tool --pid <pid> ws-remove-listener "$listener_id"
msw-dev-tool --pid <pid> ws-remove-endpoint "$endpoint_id"{"ok":true,"endpoint":{"endpointId":"<value returned in endpoint.endpointId>","enabled":false,"listeners":[]}}ws-set-*-enabled commands control only the selected WebSocket endpoint, listener, or logical event branch; the global set-mock-enabled switch takes precedence. ws-add-endpoint, ws-add-listener, and ws-set-listener-behavior accept JSON input.
A temporary listener defaults to { "preset": "default" }. Its response and customResponse are independent configurations containing payload, delay, and repeat. Default uses response, while { "preset": "custom response" } uses customResponse. repeat.repetitions includes the first response. Use "Infinity" only with a positive interval and a local test client because it can flood the client. Stop an unbounded sequence by updating or removing the listener, closing the client, or resetting the Dev Tool.
Update each complete configuration with ws-set-listener-response or ws-set-listener-custom-response. Send supports String, Blob, and ArrayBuffer values; Blob and ArrayBuffer values are space-separated hexadecimal bytes. Close accepts optional code and reason. Code-discovered endpoints and listeners cannot be removed; remove commands apply only to temporary items.