lf-cli
An open-source CLI for Langfuseยฎ
A powerful command-line interface for querying and analyzing Langfuse LLM observability data. Built with Ruby and designed for developers who prefer working in the terminal.
Disclaimer
This is an unofficial, community-maintained CLI tool for Langfuse.
This project is not affiliated with, endorsed by, or sponsored by Langfuse GmbH. Langfuseยฎ is a registered trademark of Langfuse GmbH.
Features
- ๐ Query Traces - List and filter traces by name, user, session, tags, or time range
- ๐ Analyze Sessions - View complete session details with all associated traces
- ๐ฏ Inspect Observations - List LLM generations, spans, and events
- ๐ Query Metrics - Run analytics queries with custom aggregations and dimensions
- โญ View Scores - Access quality scores and evaluation metrics
- ๐จ Multiple Output Formats - Table, JSON, CSV, or Markdown
- ๐ Multi-Profile Support - Manage credentials for dev, staging, and production
- ๐ Interactive Setup - Browser-integrated credential configuration
- โก Type-Safe - Built with Sorbet Runtime for reliability
Installation
Install from RubyGems
gem install lf-cliInstall from Source
git clone https://github.com/vicentereig/lf-cli.git
cd lf-cli
bundle install
bundle exec rake installRequirements
- Ruby >= 2.7.0
- Langfuse account (cloud or self-hosted)
Quick Start
1. Configure Credentials
Run the interactive setup wizard:
lf config setupThis will:
- Ask for your Langfuse project name
- Open your browser to the Langfuse settings page
- Prompt you to enter your API keys
- Test the connection
- Save credentials securely to
~/.langfuse/config.yml
2. Start Querying
# List recent traces
lf traces list --from "1 hour ago" --limit 20
# Get specific trace details
lf traces get trace_abc123
# Query metrics
lf metrics query --view traces --measure count --aggregation countUsage
Configuration Commands
# Interactive setup (recommended)
lf config setup
# Set credentials manually
lf config set production \
--public-key pk_... \
--secret-key sk_...
# Show current configuration (keys are masked)
lf config show
# List all profiles
lf config listTrace Commands
# List all traces
lf traces list
# Filter traces by various criteria
lf traces list \
--name "chat_completion" \
--user-id user_123 \
--from "2024-01-01" \
--limit 50
# Get detailed trace information
lf traces get trace_abc123
# Export to CSV
lf traces list --format csv --output traces.csvSession Commands
# List all sessions
lf sessions list
# Show specific session with details
lf sessions show session_xyz789Observation Commands
# List all observations
lf observations list
# Filter by type
lf observations list --type generation
# Filter by trace
lf observations list --trace-id trace_abc123Score Commands
# List all scores
lf scores list
# Filter by name
lf scores list --name quality
# Get specific score
lf scores get score_123Metrics Commands
# Count total traces
lf metrics query \
--view traces \
--measure count \
--aggregation count
# Average latency by trace name
lf metrics query \
--view observations \
--measure latency \
--aggregation avg \
--dimensions name
# Token usage with time range
lf metrics query \
--view observations \
--measure tokens \
--aggregation sum \
--from "2024-01-01" \
--to "2024-12-31"
# P95 latency grouped by model
lf metrics query \
--view observations \
--measure latency \
--aggregation p95 \
--dimensions modelGlobal Options
All commands support these global options:
-f, --format [table|json|csv|markdown] # Output format (default: table)
-o, --output FILE # Save output to file
-l, --limit N # Limit number of results
-P, --profile PROFILE # Use specific profile
--from TIMESTAMP # Start of time range (ISO 8601 or relative)
--to TIMESTAMP # End of time range
-v, --verbose # Verbose outputTime Range Examples
Supports both ISO 8601 and natural language:
# ISO 8601
--from "2024-01-01T00:00:00Z" --to "2024-12-31T23:59:59Z"
# Natural language (requires 'chronic' gem)
--from "1 hour ago"
--from "yesterday"
--from "last monday"Output Formats
Table (Default)
lf traces list --format tableOutputs a formatted ASCII table - great for terminal viewing.
JSON
lf traces list --format jsonPerfect for piping to jq or other tools:
lf traces list --format json | jq '.[] | select(.name == "chat")'CSV
lf traces list --format csv --output data.csvImport into spreadsheets or data analysis tools.
Markdown
lf traces list --format markdownGreat for documentation and reports.
Configuration
Configuration File
Credentials are stored in ~/.langfuse/config.yml:
profiles:
default:
host: https://cloud.langfuse.com
public_key: pk_...
secret_key: sk_...
output_format: table
page_limit: 50
production:
host: https://cloud.langfuse.com
public_key: pk_prod_...
secret_key: sk_prod_...The file is created with 0600 permissions (owner read/write only) for security.
Environment Variables
You can also use environment variables:
export LANGFUSE_PUBLIC_KEY="pk_..."
export LANGFUSE_SECRET_KEY="sk_..."
export LANGFUSE_HOST="https://cloud.langfuse.com"
export LANGFUSE_PROFILE="production"Priority Order
Configuration is loaded in this order (highest to lowest priority):
- Command-line flags (
--public-key,--secret-key, etc.) - Environment variables (
LANGFUSE_PUBLIC_KEY, etc.) - Config file (
~/.langfuse/config.yml) - Defaults
LLM Reference (llms-full)
This section mirrors the depth of a llms-full.txt so AI assistants can answer detailed questions about lf-cli without inspecting the source.
CLI Metadata
| Item | Details |
|---|---|
| Binary names |
lf (preferred), langfuse (legacy alias used in docs) |
| Entry point |
bin/lf โ Langfuse::CLI::Main.start(ARGV)
|
| Ruby compatibility | Ruby >= 2.7.0 (same as gemspec requirement) |
| Default API host | https://cloud.langfuse.com |
| Config path |
~/.langfuse/config.yml (0600 permissions) |
| Source namespace |
Langfuse::CLI with command classes under lib/langfuse/cli/commands
|
| HTTP stack | Faraday + JSON middleware, 2s open/read timeouts, retry with exponential backoff on 429/5xx
|
| Logging | Set DEBUG=1 to enable Faraday request/response logging |
Authentication & Configuration
- Credentials (
public_key,secret_key) plushostare mandatory for all API calls. - Resolution order: CLI flags โ environment variables โ profile in
~/.langfuse/config.ymlโ defaults. - Profiles let you store multiple environments (e.g.,
default,staging,production) inside the same YAML file. - The
config setupcommand validates keys before saving by hitting/api/public/traceswithlimit=1.
Environment variable matrix
| Variable | Purpose | Required | Notes |
|---|---|---|---|
LANGFUSE_PUBLIC_KEY |
Public API key | โ | Required for non-interactive config setup and all other commands if no profile is configured. |
LANGFUSE_SECRET_KEY |
Secret API key | โ | Same priority rules as the public key. |
LANGFUSE_HOST |
Override API base URL | Optional | Use for self-hosted Langfuse instances. |
LANGFUSE_PROFILE |
Profile name | Optional | Overrides the profile selected via -P/--profile. |
LANGFUSE_PROJECT_NAME |
Used by config setup to show the correct settings URL. |
Optional | Only needed for UX hints. |
DEBUG |
When set to 1, logs Faraday requests/responses to stdout. |
Optional | Useful for diagnosing API issues. |
Global Flags & Behavior
| Flag | Description | Notes |
|---|---|---|
-P, --profile PROFILE |
Selects a saved profile. | Defaults to default. |
--public-key KEY / --secret-key KEY
|
Inject credentials without touching config files. | Highest priority source. |
--host URL |
Override Langfuse host. | Combine with --profile to temporarily test another region. |
-f, --format FORMAT |
table (default), json, csv, markdown. |
Applies to every command; CSV/Markdown require structured arrays. |
-o, --output PATH |
Write output to a file. | Respects format; prints โOutput writtenโฆโ when --verbose. |
-l, --limit N |
Caps number of records pulled per command. | Pagination helper, defaults to API limit (50) when omitted. |
-p, --page N |
Start from an explicit page. | Useful when you know an offset. |
--from, --to
|
ISO 8601 or natural language timestamps. | Natural language parsing uses chronic if installed; otherwise the string is sent as-is. |
-v, --verbose |
Prints extra logs (e.g., file paths). | Some commands emit status lines prefixed with emojis. |
--no-color |
Forces monochrome table output. | Forwarded to formatters that support color. |
Pagination strategy: the client keeps fetching pages until it collects the requested limit or no more pages remain. limit therefore caps the total combined size, not per-page size.
Output & Files
-
tablerenders ASCII tables viaFormatters::TableFormatter. -
jsonstreamsJSON.pretty_generatefor direct piping tojq. -
csvandmarkdownuse dedicated formatters and require array-like data (single hashes are wrapped automatically). -
--outputwrites the formatted string verbatim; combine with--format jsonfor scripts. - Use
lf ... --format json | jq ...for automation recipes.
Command Reference
Each command inherits the global flags above. API errors exit with status code 1.
config (profile management)
| Subcommand | Synopsis | Notes |
|---|---|---|
lf config setup |
Interactive wizard; supports env-variable non-interactive mode. | Tests credentials before saving. |
lf config set PROFILE --public-key ... --secret-key ... [--host ...] |
Writes/updates a profile directly. | Does not hit the API. |
lf config show [PROFILE] |
Prints the resolved profile (keys masked). | Reads from YAML + ENV. |
lf config list |
Shows every profile name plus masked public key/host. | Warns if file missing. |
traces
| Subcommand | Purpose |
|---|---|
lf traces list |
Lists traces with filters/pagination. |
lf traces get TRACE_ID [--with-observations] |
Fetches a single trace. The --with-observations flag is accepted for forward compatibility but currently behaves the same as the default API payload. |
traces list options:
| Flag | Type | Description |
|---|---|---|
--name NAME |
String | Filter by trace name. |
--user-id USER_ID |
String | Filter by Langfuse user identifier. |
--session-id SESSION_ID |
String | Filter by session. |
--tags TAG1 TAG2 |
Array | Matches traces containing all provided tags. |
--from, --to
|
String | Time boundaries; accepts ISO 8601 or relative strings. |
--limit, --page
|
Numeric | Override pagination per request. |
Sample workflow:
latest_trace_id=$(lf traces list --format json --limit 1 | jq -r '.[0].id')
lf traces get "$latest_trace_id" --format json > trace.jsonsessions
| Subcommand | Purpose |
|---|---|
lf sessions list |
Enumerates sessions. |
lf sessions show SESSION_ID [--with-traces] |
Shows a session and optionally its traces (flag reserved for future enrichments). |
Options mirror trace pagination: --from, --to, --limit, --page.
observations
| Subcommand | Purpose |
|---|---|
lf observations list |
Lists generations, spans, or events. |
lf observations get OBSERVATION_ID |
Fetches a single observation. |
list filters:
| Flag | Values | Description |
|---|---|---|
--type |
generation, span, event
|
Restrict to an observation type. |
--trace-id |
Trace ID | Only observations under a specific trace. |
--name |
String | Filter by observation name. |
--user-id |
String | Filter by associated user. |
--from, --to, --limit, --page
|
As described earlier. |
scores
| Subcommand | Purpose |
|---|---|
lf scores list |
Lists evaluation scores. |
lf scores get SCORE_ID |
Fetches a single score document. |
Filters: --name, --from, --to, --limit, --page.
metrics
Single subcommand: lf metrics query.
Required flags:
| Flag | Allowed values | Description |
|---|---|---|
--view |
traces, observations, scores-numeric, scores-categorical
|
Which metrics view to query. |
--measure |
count, latency, value, tokens, cost
|
Base metric. |
--aggregation |
count, sum, avg, p50, p95, p99, min, max, histogram
|
Aggregation function. |
Optional flags:
| Flag | Description |
|---|---|
--dimensions field1 field2 |
Array of dimension field names (e.g., name, userId, sessionId, model). |
--from, --to
|
Time range. |
--granularity |
minute, hour, day, week, month, auto. Controls the time bucket. |
--limit |
Defaults to 100 for metrics; caps the number of buckets/rows returned. |
The CLI builds a payload matching the Langfuse metrics API (metrics array, timeDimension etc.) via Langfuse::CLI::Types::MetricsQuery.
Data Model Cheat Sheet
-
Trace:
id,name,userId,sessionId,timestamp,durationMs,tags[],metadata(object),observations[](optional when usingget),scores[]. -
Session:
id,userId,name,createdAt,updatedAt,traceIds[],metadata. -
Observation:
id,traceId,type(generation/span/event),name,status,model,input,output,metrics(latency, usage),level,parentObservationId. -
Score:
id,name,value(number/string),type(numeric/categorical),traceId,observationId,timestamp,metadata,comment. -
Metrics response: Usually
{ "data": [ { "dimensions": {...}, "metrics": {...} } ], "meta": {...} }. The CLI automatically unwrapsdatabefore formatting.
Fields are passed through verbatim from the Langfuse Public API; the CLI never renames keys.
Error Handling & Exit Codes
- Success exits with code
0. - Any
Langfuse::CLI::Client::*Errorresults in exit code1after printing a human-readable message. - Specific messages:
-
Authentication Errorfor401. -
Rate limit exceededfor429. -
Trace/session/... not foundfor404. -
Request timed outwhen Faraday raises a timeout (usually after 2s).
-
- Use
--verboseorDEBUG=1for deeper context (e.g., stack traces, Faraday logs).
Troubleshooting & Automation Tips
-
Network issues: verify
LANGFUSE_HOSTby runninglf config showand hitting/healthwithcurl. -
Time parsing: install the
chronicgem to enable natural language ranges; otherwise pass ISO 8601 timestamps. -
CSV exports: always provide
--output file.csvto avoid large terminal dumps. -
Scripting: prefer
--format jsonto keep machine-readable structures. Most commands return arrays, so piping tojq '.[].id'works consistently. -
Profiles: store CI credentials under
LANGFUSE_PROFILE=ciand load them vialf ... -P cito keep human/dev credentials untouched. -
Retries: built-in Faraday retry middleware already backs off (
max: 3). For long-running scripts, wrap commands with shell retries instead of adding loops inside the CLI.
Development
Setup
git clone https://github.com/vicentereig/lf-cli.git
cd lf-cli
bundle installRun Tests
# Run all tests
bundle exec rspec
# Run with documentation format
bundle exec rspec --format documentation
# Run specific test file
bundle exec rspec spec/unit/commands/traces_spec.rbRun CLI Locally
./bin/lf help
./bin/lf config setupCode Structure
lib/langfuse/cli/
โโโ client.rb # API client with Faraday
โโโ config.rb # Configuration management
โโโ types.rb # Sorbet type definitions
โโโ formatters/ # Output formatters
โ โโโ table_formatter.rb
โ โโโ csv_formatter.rb
โ โโโ markdown_formatter.rb
โโโ commands/ # Command modules
โโโ traces.rb
โโโ sessions.rb
โโโ observations.rb
โโโ scores.rb
โโโ metrics.rb
โโโ config.rb
API Reference
This CLI uses the Langfuse Public API:
- API Documentation: https://api.reference.langfuse.com/
- OpenAPI Spec: https://cloud.langfuse.com/generated/api/openapi.yml
Valid enum values for metrics query:
-
View:
traces,observations,scores-numeric,scores-categorical -
Measure:
count,latency,value,tokens,cost -
Aggregation:
count,sum,avg,p50,p95,p99,min,max,histogram -
Granularity:
minute,hour,day,week,month,auto
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built with Thor CLI framework
- Uses Faraday for HTTP requests
- Type safety with Sorbet Runtime
- Inspired by the excellent Langfuse observability platform
Support
- ๐ Bug Reports: GitHub Issues
- ๐ฌ Questions: GitHub Discussions
- ๐ง Email: hey@vicente.services
Roadmap
- Add support for filtering by metadata
- Implement trace export with full observation trees
- Add watch mode for real-time trace monitoring
- Support for creating/updating scores via CLI
- Integration with other observability tools
Note: This is a community project. For official Langfuse support and documentation, visit langfuse.com.