Skip to content

Latest commit

 

History

History

cli

README.md

@singhak/nodeui-cli

Command line for NodeUI: attach the console to any Node app without changing its code, watch several services from one page, and expose the data to AI agents over MCP.

npx @singhak/nodeui-cli attach -- node server.js
npx @singhak/nodeui-cli attach -- npm run dev
npx @singhak/nodeui-cli dashboard api=http://127.0.0.1:3000 worker=http://127.0.0.1:3001
npx @singhak/nodeui-cli check --run latest --max-p99 300 http://127.0.0.1:3000

attach

Runs your command with a small preload (NODE_OPTIONS=--require …) that wraps http.Server / https.Server. The console is served on your app's own port under /nodeui, and the terminal prints the URL once the app is listening:

[nodeui] console: http://127.0.0.1:3000/nodeui/
Option Effect
--path <prefix> console path (default /nodeui)
--token <secret> require an access token
--persist <file> journal that survives restarts
--otlp <url> export spans to an OTLP/HTTP collector
--bodies capture request/response bodies (masked, capped)
--force attach even when NODE_ENV=production

What you get: requests, outgoing calls, logs, errors, health, memory/CPU/event loop, and queries from pg/mysql2. What you do not: route patterns and the route table for frameworks that expose them only through an adapter (Express still gets req.route patterns; Fastify, Koa, Hapi and Hono need their adapter), and Prisma (server.trackPrisma) or other manual hooks.

Notes and limits:

  • It does not attach to an already running process; start the app through the CLI. Node cannot inject code into a process that is already running.
  • Do not combine it with a NodeUI adapter in the same app: requests would be recorded twice.
  • Production stays fail-closed: with NODE_ENV=production nothing is attached unless you pass --force. The usual loopback, Host and Origin checks apply.
  • Child processes inherit NODE_OPTIONS, so tools that fork workers (e.g. npm run dev) attach in each Node process that creates an HTTP server.

check

Fails (exit 1) when a running console's recent traffic or a saved load-test run breaks a budget, for CI or a pre-push script:

npx @singhak/nodeui-cli check --window 300 --max-p99 300 --max-error-rate 1 http://127.0.0.1:3000
npx @singhak/nodeui-cli check --run latest --max-regression 10 http://127.0.0.1:3000
Option Meaning
--window <sec> check the last N seconds (default 300)
--run <name|latest> check a saved run instead
--max-p50/--max-p95/--max-p99 latency budgets in ms
--max-error-rate <pct> percentage of 5xx responses
--min-rps <n> throughput floor
--max-loop-p99 <ms> event-loop delay budget
--max-rss-mb <n> memory budget
--max-regression <pct> with --run: p99 may rise and throughput may fall at most this much against the pinned baseline

Exit codes: 0 all budgets held, 1 a budget failed, 2 nothing to check (no traffic, unknown run, console unreachable, or no limits given).

dashboard

One loopback page that lists several running consoles with health, request count, error rate, p95 and error groups, and opens any of them through a proxy at /s/<name>/:

nodeui dashboard --port 4000 api=http://127.0.0.1:3000 billing=http://127.0.0.1:3100/nodeui?token=secret
  • A service entry is name=url or just url; the console path defaults to /nodeui; ?token= is the service's access token and is sent as a bearer header by the proxy (never put into the page).
  • The dashboard is loopback-only, rejects foreign Host and Origin headers, and strips cookies/origin when proxying so each service's own checks still apply.
  • Each service keeps its own data; the dashboard stores nothing.

mcp (AI agents)

A Model Context Protocol server over stdio, so an agent (Claude Code, Cursor, …) can read what your app is doing instead of you pasting logs:

{
  "mcpServers": {
    "nodeui": { "command": "npx", "args": ["@singhak/nodeui-cli", "mcp", "http://127.0.0.1:3000"] }
  }
}

Give it one console URL, or several as name=url (tools then take a service argument). Tools, all read-only:

Tool Returns
nodeui_overview start here: prioritised digest of health, traffic, grouped errors, failing/slow requests, slow and N+1 queries, failing outgoing calls
nodeui_errors grouped errors with stacks and the last linked request
nodeui_requests recent requests; filter by minStatus / minDurationMs
nodeui_request one request joined with its outgoing calls, queries and log lines
nodeui_queries, nodeui_outgoing, nodeui_logs, nodeui_routes the matching panels, trimmed

It reads the console's REST API, so everything is already masked, and it never calls heap snapshots or any confirmation-gated action. An agent sees only what the console would show you, and only on your machine unless you point it elsewhere.

Programmatic use

import { startDashboard, parseTarget } from '@singhak/nodeui-cli';

const dashboard = await startDashboard({ services: [parseTarget('api=http://127.0.0.1:3000')] });