Skip to main content
The lmnr-cli is a command-line tool for onboarding a project, querying Laminar data, managing datasets, and annotating debug sessions from your terminal. It is the fastest way to wire up a new project, pull traces into a shell pipeline, script dataset maintenance, or connect an AI coding agent that can shell out, all without leaving the command line.
The CLI is a standalone npm package (lmnr-cli) and ships independently from the @lmnr-ai/lmnr SDK. You do not need the SDK installed to onboard a project, query data, or manage datasets.

Install

# Run directly with npx (no install)
npx lmnr-cli@latest <command>

# Or install globally
npm install -g lmnr-cli

Quick start

lmnr-cli setup takes you from a fresh install to an instrumented project in one command:
lmnr-cli setup
It opens your browser to authorize the CLI, then:
  1. Logs you in (if you are not already).
  2. Lets you pick or create a project.
  3. Mints a project API key for your application’s SDK and writes LMNR_PROJECT_API_KEY=... to your env file (an existing .env.local if you have one, otherwise .env). If a valid key for this project is already configured, it keeps that one.
  4. Links the directory by writing .lmnr/project.json.
  5. Installs the Laminar agent skill into your project (.claude/, .cursor/, .codex/, or .agents/).
The CLI itself never uses that key: it authenticates as you (see Authenticate). The key is purely for the SDK in your app to send traces. Add the SDK to your app, run it, then confirm traces are landing:
lmnr-cli sql query "SELECT * FROM traces ORDER BY start_time DESC LIMIT 1"
setup is designed to be driven by coding agents. Pass --json for a single machine-readable line on stdout:
lmnr-cli setup --json
Useful flags:
lmnr-cli setup --project-id <uuid>   # Disambiguate when you can access multiple projects
lmnr-cli setup --no-write-env        # Skip writing ./.env
lmnr-cli setup --no-browser          # Print the device-flow URL instead of opening it
Re-running setup in the same directory reuses the linked project and keeps a working key in place: if a valid key for this project is already configured (in your environment or env file), it leaves it untouched. If your API key is invalid or revoked it will mint a new one. If your API key does not match the project configured in .lmnr/project.json it will abort with an error. Keys stay visible (and revocable) in Settings → Project API Keys.

Authenticate

Every CLI command authenticates as you, the signed-in user. Log in once with lmnr-cli login (or run lmnr-cli setup, which logs you in as its first step):
lmnr-cli login
This starts an OAuth device flow: the CLI prints a verification URL and code and opens your browser. Approve the request to finish signing in. Credentials are stored at ~/.config/lmnr/credentials.json (fallback precedence &XDG_CONFIG_HOME/, %APPDATA%\, ~/.config/). The short-lived access token is refreshed automatically as it nears expiry; if your session is revoked, run lmnr-cli login again.
lmnr-cli logout   # Remove the stored credentials

Self-hosting

For a self-hosted deployment, point the CLI at your instance. login talks to your frontend (the auth issuer); the data commands (sql, dataset, project, trace, debug) talk to your API. The cleanest way is to set the URLs once via environment variables. The CLI reads them from your environment and from a .env or .env.local file in the current directory.
LMNR_FRONTEND_URL=https://example.com   
LMNR_BASE_URL=https://api.example.com  
LMNR_HTTP_PORT=8000                             
With those set, every command works as usual:
lmnr-cli login
lmnr-cli sql query "SELECT 1"
You can also pass the URLs per command instead. login takes --frontend-url; the data commands take --base-url (and --port):
lmnr-cli login --frontend-url https://laminar.example.com
lmnr-cli sql query "SELECT 1" --base-url https://api.laminar.example.com
The CLI does not use a project API key. The LMNR_PROJECT_API_KEY that lmnr-cli setup writes to your env file is for the Laminar SDK in your application to send traces; the CLI authenticates as you instead.

Directory-scoped projects

Every project command (sql, dataset, project, trace, debug) resolves which project it targets from the directory you run in. lmnr-cli setup writes a .lmnr/project.json link file at the project root (it holds the project id and display details, never secrets). Commands then resolve the project in this order:
  1. --project-id <id> flag.
  2. The nearest .lmnr/project.json, walking up from the current directory.
So once a directory is linked, every command in it (or any subdirectory) targets that project with no extra flags. Override per command with --project-id. List the projects you can access and see which one is linked here:
lmnr-cli project list
lmnr-cli project list --json
The linked project is marked with a .

Query data with SQL

Run ClickHouse SQL against your project’s spans, traces, signal events, and more. sql runs against the linked project, so lmnr-cli login plus a linked directory (or --project-id) is all you need:
lmnr-cli sql query "SELECT name, duration FROM spans WHERE start_time > now() - INTERVAL 1 HOUR LIMIT 20"
Add --json to emit structured JSON on stdout (messages and errors go to stderr), which makes it trivial to pipe into jq, a local script, or an AI coding agent:
lmnr-cli sql query "SELECT trace_id, total_cost FROM spans WHERE span_type = 'LLM' LIMIT 10" --json \
  | jq '.[] | select(.total_cost > 0.01)'
List the available tables and columns:
lmnr-cli sql schema
For the full schema and query guide, see SQL Editor.
Only SELECT queries are allowed. The query runs scoped to your project automatically; no tenant filter is needed in your WHERE clause.

Manage datasets

List, push, pull, and create datasets from files on disk. Supported formats: .jsonl, .json, .csv. Like sql, these commands run against the linked project.
# List all datasets in the project
lmnr-cli dataset list --json

# Push new datapoints into an existing dataset
lmnr-cli dataset push data.jsonl -n my-dataset

# Pull a dataset down to a local file
lmnr-cli dataset pull output.jsonl -n my-dataset

# Create a new dataset from a file, writing a local copy with dataset IDs
lmnr-cli dataset create my-dataset data.jsonl -o my-dataset.jsonl
See Datasets CLI for the full dataset workflow including versioning semantics.

Annotate debug sessions

These commands are the operational layer for the Debugger: you run the agent with LMNR_DEBUG=true, then use these to name the session, write per-trace notes, and open the session view. Like the other commands, they run against the linked project.
None of these commands need an id passed in. By default they target the session in .lmnr/debug-session.json (the most recent LMNR_DEBUG=true run in this directory), and trace append-note targets that session’s latest trace. Pass --session-id or --trace-id to target a different one.

trace append-note

Append a markdown note to a trace (stored in rollout.note trace metadata). Notes are append-only: each call adds a paragraph to the existing note. The note text is the only required argument; the note lands on the latest trace of the current debug session unless you pass --trace-id.
lmnr-cli trace append-note "## What this run showed
Length cap is working. Next: check citations."

lmnr-cli trace append-note "Length cap is working." --trace-id <trace-id>
Span references in the note are written as XML tags; the Laminar UI renders them as clickable chips:
lmnr-cli trace append-note "<span id='<spanId>' name='synthesis call' />"

debug session new

Mint a fresh debug session and reset .lmnr/debug-session.json to it. The next LMNR_DEBUG=true run in this directory rejoins the new session instead of continuing the previous one. Use this to start a clean investigation.
lmnr-cli debug session new
lmnr-cli debug session new --json
lmnr-cli debug session new --no-browser
The bare session id prints to stdout (so an agent can capture it); --json emits {"sessionId","projectId","debuggerUrl"} instead. The command opens the session in your browser unless you pass --no-browser.

debug session open

Open the debug session’s debugger page in your browser. With no flag it opens the session in .lmnr/debug-session.json; pass --session-id to open another. The URL also prints to stdout (--json emits {"sessionId","debuggerUrl"}). This command is local-only: no login or network call.
lmnr-cli debug session open
lmnr-cli debug session open --session-id <session-id>

debug session set-name

Set the display name of the current debug session (the one in .lmnr/debug-session.json), or pass --session-id to name another. The session must already exist (created by a LMNR_DEBUG=true run or debug session new). You can also rename a session inline by clicking its title in the session view.
lmnr-cli debug session set-name "Fix report length + search tool"
lmnr-cli debug session set-name "Fix report length" --session-id <session-id>

debug session summary

Print every trace in the debug session with its note, oldest first. Use this to re-orient in an ongoing session after a context reset. Defaults to the current session; pass --session-id for another.
lmnr-cli debug session summary
lmnr-cli debug session summary --session-id <session-id> --json
Output is one block per trace: the markdown note followed by a <trace id="..." end-time="..."/> tag you can feed into SQL queries. See Debugger for the full record/replay process.

Piping and agent-friendly output

The CLI is designed to be scriptable and to plug cleanly into AI coding agents:
  • One-shot onboarding. lmnr-cli setup --json emits a single machine-readable line (project id, minted key, dashboard URL) and uses distinct exit codes so an agent can branch on the failure mode: 6 login failed, 7 no project to select, 8 .env write failed, 9 key minting failed, 10 project discovery failed.
  • Structured output on stdout, logs on stderr. Every command that supports it takes --json and prints machine-readable output to stdout, while human-friendly progress messages are written to stderr. This keeps pipes clean.
Combined with sql query --json, this makes the CLI a drop-in SQL layer for any agent that can run shell commands, with no SDK install required.

Help

Every command accepts -h / --help:
lmnr-cli --help
lmnr-cli setup --help
lmnr-cli login --help
lmnr-cli project --help
lmnr-cli sql --help
lmnr-cli sql query --help
lmnr-cli dataset --help
lmnr-cli trace --help
lmnr-cli debug --help
lmnr-cli debug session --help
lmnr-cli debug session new --help
lmnr-cli debug session open --help

What’s next

SQL Editor

The UI counterpart for ad-hoc SQL queries, with schema reference and examples.

MCP Server

Connect Claude Code, Cursor, or any MCP client to Laminar directly.

Datasets CLI workflow

End-to-end example of pulling, editing, and pushing a dataset.

Debugger

Rerun long-running agents from a checkpoint without leaving the page.