Switch to dark mode
Switch to light mode

reference

Lemma CLI

See Installation for install options.

Commands

lemma run: evaluate a spec

lemma run [[repo] spec] [name=value ...] [--prefix PATH] [--rules=RULES] [options]

Syntax:

  • Positionals: optional repository qualifier (e.g. @iso/countries), then spec name (see lemma run --help)
  • spec --rules=rule: evaluate one rule
  • spec --rules=rule1,rule2: evaluate specific rules (comma-separated)
  • No arguments with -i: interactive mode

Options:

  • --prefix <path>: workspace directory or .lemma file (default: current directory)
  • --rules <rules>: comma-separated Show.rules keys (omit to evaluate this spec's outputs)
  • --json: output results as JSON (default: human-readable table). Each rule result may include missing_data (unbound input keys in evaluation / decision-tree order). Types, filled values, and suggestions come from lemma show, not from evaluate JSON.
  • -x, --explain: include explanation trees (human: reasoning tables per rule; JSON: per-rule explanation objects matching api.v1.json). Unbound inputs appear in those tables when a rule still awaits input (MissingData veto). JSON still carries raw per-rule missing_data from the engine.
  • -i, --interactive: guided spec/rule/data selection
  • --effective <datetime>: evaluate at effective datetime (e.g. 2025, 2025-03, 2025-03-04)

Examples:

lemma run pricing
lemma run pricing --rules=total,tax
lemma run --prefix ./policies nl/tax/net_salary --rules=net_salary -x
lemma run pricing quantity=10 is_vip=true
lemma run pricing --json
lemma run pricing -x
lemma run pricing --effective 2025-01-01
lemma run -i
lemma run '@iso/countries' alpha2

lemma show: declared data catalog and rules

Shows declared data slots with types and constraints (minimum, maximum, units, decimals, text options), filled values, suggestions, import path, and this spec's rule graph (ShowRule: type, path, branches, depends_on_rules as input_key). Lemma source text is available via Engine::source (API) only.

show lists every declared promptable data slot (types, constraints, fill, suggestions, path). needed_by_rules names Show.rules keys that still need the slot after normalize; empty means offered for reuse (data x: alias.slot), not an eval intake key for this spec. Run-data-aware pruning for a concrete run is per-rule results.*.missing_data.

lemma show [[repo] spec] [--prefix PATH] [--effective <datetime>] [--json]

Options:

  • [repo]: optional repository qualifier (e.g. @iso/countries)
  • [spec]: spec name (omit when workspace has a single spec)
  • --prefix <path>: workspace directory or .lemma file (default: current directory)
  • --effective <datetime>: effective datetime for temporal specs
  • --json: output as JSON (default: human-readable table)

Examples:

lemma show pricing
lemma show --prefix ./policies net_salary
lemma show --prefix tax.lemma calculator
lemma show '@iso/countries' alpha2
lemma show pricing --json

lemma list: list loaded specs by repository

Lists every loaded spec, grouped by repository. Local specs (no repository qualifier) are printed unindented; named repositories (including embedded lemma) appear as headers with indented spec names.

lemma list [--prefix PATH] [--json]

Options:

  • --prefix <path>: workspace directory or .lemma file (default: current directory)
  • --json: output Engine::list() JSON: array of { "repository", "specs" } where each spec is a ListedSpec (name, optional effective_from / effective_to). Human text lists unique spec names only.

Examples:

lemma list
lemma list --prefix ./project
lemma list --json

lemma install: install repositories from LemmaBase

Resolves @... references and downloads repositories from LemmaBase into lemma_deps/.

lemma install [--prefix PATH] --all
lemma install [--prefix PATH] <repository> -f

Options:

  • --prefix <path>: workspace directory or .lemma file (default: current directory)
  • -a, --all: install all @... references in the workspace
  • -f, --force: overwrite existing repositories when content has changed on LemmaBase

lemma format: format .lemma files

lemma format [paths...] [--check] [--stdout]

Options:

  • --check: check formatting without modifying (exit 1 if any file would change)
  • --stdout: write formatted output to stdout

lemma server: start HTTP server

lemma server [--prefix PATH] [--host <host>] [-p <port>] [--watch] [--explain] [--eval-timeout SECONDS] [--cors]

Options:

  • --prefix <path>: workspace directory or .lemma file (default: current directory)
  • --host <host>: bind address (default: 127.0.0.1)
  • -p, --port <port>: port (default: 8012)
  • --watch: live-reload on .lemma file changes
  • --explain: enable explanation generation (clients send x-explain header; JSON shape api.v1.json)
  • --eval-timeout <second>: wall-clock timeout for a single evaluation request (default: 10)
  • --cors: allow cross-origin browser requests from any origin (off by default)

SIGINT/SIGTERM stop accepting new connections, drain in-flight requests up to --eval-timeout, then exit 0.

Routes:

Method Route Description
GET / List all specs
GET /{spec} Show spec interface (data, rules, versions)
POST /{spec} Evaluate (data as JSON or form body)
GET/POST /{spec}/{rules} Evaluate specific rules (comma-separated)
GET /openapi.json OpenAPI 3.1 specification
GET /docs Interactive API documentation (Scalar)
GET /health Health check

Example:

lemma server --prefix ./policies --watch

curl "http://localhost:8012/pricing?quantity=10&is_member=true"

curl -X POST http://localhost:8012/pricing \
  -H "Content-Type: application/json" \
  -d '{"quantity": 10, "is_member": true}'

lemma lsp: start language server

Starts the Language Server Protocol server over stdio for editor integration (diagnostics, formatting, semantic tokens). The VS Code/Cursor extension invokes this automatically; a globally installed lemma CLI is the only requirement.

Workspace file discovery uses the same policy as lemma list / lemma run: project .gitignore rules, plus always loading <workdir>/lemma_deps/**/*.lemma. The CLI injects that discovery and a filesystem watch into the LSP. The watch covers discovered workspace .lemma files and lemma_deps/ only (not a recursive whole-tree watch), so disk changes such as lemma install update diagnostics without hanging on large build directories. Editor open/change/save/close remain the primary sync path for buffers.

lemma lsp

lemma mcp: start MCP server

Start the MCP server so AI assistants can work with workspace specs. Default transport is stdio. Pass --http for Streamable HTTP (POST /mcp). Full setup guide: MCP.

lemma mcp [--prefix PATH] [--write] [--request-timeout SECONDS]
lemma mcp --http [--prefix PATH] [--write] [--request-timeout SECONDS] [--host HOST] [--port PORT] [--cors]

Options:

  • --prefix <path>: workspace directory or .lemma file (default: current directory)
  • --write: enable write tools (read-only by default)
  • --request-timeout <seconds>: wall-clock timeout for a single request (default: 10)
  • --http: Streamable HTTP instead of stdio
  • --host <host>: bind address when using --http (default: 127.0.0.1)
  • --port <port>: listen port when using --http (default: 8013; lemma server uses 8012)
  • --cors: permissive CORS when using --http (off by default)

HTTP MCP has no built-in authentication or TLS. It binds to localhost by default; for non-localhost bind, put it behind a reverse proxy that terminates TLS and enforces access control.

Workspace

A workspace is a directory containing .lemma files. Commands that load specs use --prefix to select the workspace (default: current directory). Every .lemma file is loaded recursively from that directory, plus any repositories in lemma_deps/.

policies/
  pricing.lemma
  shipping.lemma
  tax.lemma

Resource Limits

Resource limits control parse-time and planning-time budgets. These are security boundaries that prevent unbounded resource consumption from untrusted input.

Limit Default Purpose
max_sources 4096 Maximum source files in one engine
max_loaded_bytes 50 MB Total source text across all files
max_source_size_bytes 5 MB Single source file size
max_expression_depth 7 AST nesting depth
max_expression_count 65,536 Expression nodes per source (parser)
max_normalized_expression_nodes 30,000 Unique normal-form cells reachable from one rule root after normalize (rule references count as one cell)
max_normal_form_depth 4096 Nesting depth of a rule's normalized NormalForm DAG (rule references count as one level)
max_data_value_bytes 1 KB Single data value size
max_spec_dependency_depth 32 uses chain depth
max_dag_specs 4096 Total specs in dependency DAG

max_expression_depth and max_spec_dependency_depth bound recursion during parsing and planning. Raising these beyond the defaults requires stack analysis for your deployment.

API Defaults

Effective datetime: when no --effective flag or Accept-Datetime header is provided, the engine uses the current instant to select the temporal version of the root spec.

Accept-Datetime (HTTP): clients send Accept-Datetime with the same formats as --effective: YYYY, YYYY-MM, YYYY-MM-DD, or an ISO 8601 datetime. Empty or omitted → now. Invalid values are a bad request. Responses include Vary: Accept-Datetime. When the resolved spec row has an effective_from, the server also sets Memento-Datetime to that instant.

Explanations: disabled by default in CLI (lemma run), HTTP, and SDKs. Use --explain (CLI and server) + x-explain (HTTP client), or explain: true (SDK) to opt in. MCP run/evaluate always return formatted ASCII explanation trees (no explain arg, no opt-out) plus a Missing data block when inputs are unbound. Evaluate/run JSON (CLI --json, HTTP, SDKs) has no top-level data array: unbound inputs are per-rule missing_data; types and suggestions come from lemma show / MCP show. When explanations are enabled on JSON surfaces, each results.<rule>.explanation is a rule node ("type":"rule", "name", "result", "body", optional "causes" / "children") per api.v1.json. Bound data uses "type":"data", unused cause paths "type":"data_unused".

See Also