npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mostly-good-metrics/cli

v0.1.4

Published

CLI for MostlyGoodMetrics analytics

Readme

MostlyGoodMetrics CLI

The command-line interface for MostlyGoodMetrics. Use it to manage analytics projects, inspect events and dashboards, run product analyses, and operate experiments from a terminal, script, or coding agent.

Install

Requires Node.js 18 or later.

npm install -g @mostly-good-metrics/cli
mgm --version

Get started

Authenticate, create or select a project, then inspect its dashboard:

# Opens the MostlyGoodMetrics sign-in flow in your browser.
mgm login

# Creates a project and a bundle-restricted API key, then writes .mgm.json.
mgm init --project "My iOS App" --sdk swift --allow com.example.app

# Reads the project in .mgm.json.
mgm dashboard --range 30d

Project-scoped commands use the .mgm.json file in the current directory. To work without one, pass --project <project-id> or set MGM_PROJECT_ID.

mgm projects list
mgm dashboard --project prj_123 --range 7d

Common workflows

Explore your product data

# See the events your project has received.
mgm events types --project prj_123
mgm events list --project prj_123 --range 7d

# Define an event before it is first sent, so it is ready for funnels and dashboards.
# This creates metadata only; it does not emit an analytics event.
mgm events define checkout_completed \
  --description "A customer completes checkout" \
  --project prj_123

# Run an ad-hoc funnel.
mgm funnels execute \
  --steps "app_open,add_to_cart,purchase" \
  --range 30d \
  --project prj_123

# Break out unique users by day.
mgm queries execute \
  --metric unique_users \
  --group-by date \
  --breakdown-by platform \
  --range 7d \
  --project prj_123

# Power-user escape hatch: use the full safe MGM query definition.
mgm queries execute \
  --definition '{"metric":"count_events","group_by":"date","breakdown_by":"prop:screen","event_filter":["ios_screen_viewed"],"date_range":"30d"}' \
  --project prj_123

Query definition

--metric, --group-by, --breakdown-by, --granularity, --range, --events, --platforms, --environments, and --exclude-lifecycle-events cover the common cases. --definition takes the same object those flags build and is the only way to reach country/region/city filters and custom property operators. Explicit flags override keys in --definition.

{
  "metric": "unique_users",          // count_events, unique_users, unique_sessions, dau
  "event_filter": ["purchase"],      // event names to count
  "group_by": "date",                // dimension below, or "prop:<name>"
  "breakdown_by": "platform",        // second dimension; only when group_by is "date"
  "granularity": "day",              // day, week, month; only when group_by is "date"
  "date_range": "30d",               // see below
  "exclude_lifecycle_events": true,  // drop auto-tracked $ events
  "filters": { "platforms": ["iOS"] }
}

Dimensions for group_by and breakdown_by: date (group_by only), platform, app_version, app_build_number, os_version, environment, device_manufacturer, locale, timezone, country, region, city, event_name, or prop:<property_name>.

Date ranges: 1d, 7d, 30d, 90d, 365d, custom:YYYY-MM-DD:YYYY-MM-DD, or seasonal forms month:11, months:11,12, quarter:4, quarters:1,4, compare:month:11, compare:quarter:4, compare:wow:4.

filters

A flat object. Dimension keys are platforms, event_names, environments, app_versions, countries, regions, and cities; the singular spellings environment, app_version, country, region, and city mean the same thing. Each takes a string or an array of strings. Values inside one key are OR'd; separate keys are AND'd. Run mgm dashboard filters to see the values a project actually has.

Custom properties use a prop:<name> key:

"prop:plan": "pro"                               // shorthand for IN ["pro"]
"prop:plan": ["pro", "team"]                     // IN
"prop:plan": { "op": "neq", "value": "free" }    // one clause
"prop:revenue": { "op": "gt", "type": "number", "value": 100 }
"prop:plan": [                                   // several clauses, OR'd
  { "op": "contains", "value": "ent" },
  { "op": "is_set" }
]

A clause takes op (default eq), type (string default, number, boolean, datetime, enum), and value or values. Operators depend on type:

| type | Operators | | --- | --- | | any | is_set, is_not_set | | string, enum | eq, neq, in, not_in, contains, not_contains, starts_with, ends_with | | number | eq, neq, in, not_in, gt, gte, lt, lte, between | | boolean | eq | | datetime | before, after, on_or_before, on_or_after, between |

Set type when you want numeric or chronological comparison; the default string compares lexically. in, not_in, and between read values. Clauses within one prop: key are OR'd; different prop: keys are AND'd.

A prop: filter is answered from raw events rather than daily aggregates, so it is slower than a dimension filter. Prefer a dimension filter when one covers what you need.

Funnel steps are a different shape. mgm funnels create --steps takes comma-separated event names; per-step property filters use {"property": ..., "op": ..., "value": ...} with the smaller operator set eq, neq, contains, not_contains, gt, gte, lt, lte.

Manage saved analysis

mgm funnels create --name "Checkout" --steps "app_open,checkout_started,purchase"
mgm retention create --name "Weekly retention" --cohort-event signup --retention-event app_open
mgm queries create --name "Daily active users" --metric unique_users --group-by date

mgm funnels list
mgm retention list
mgm queries list

Run an experiment

mgm experiments create \
  --name "New paywall" \
  --variants "control,treatment" \
  --goal purchase

mgm experiments start exp_123
mgm experiments results exp_123
mgm experiments stop exp_123 --yes

Manage access and dashboards

mgm orgs list
mgm projects create "My App" --org acme
mgm keys create "iOS Production" --project prj_123 --allow com.example.app
mgm keys create "Private relay" --project prj_123 --unrestricted --yes
mgm widgets list --project prj_123
mgm widgets add funnel --funnel fun_123 --project prj_123

Creating an API key requires an explicit access choice. Use one or more --allow values for Apple bundle IDs, Android package names, or web domains. Use --unrestricted only when the caller cannot send a stable identifier; unrestricted creation requires interactive confirmation or the global --yes flag. After restricted creation, the CLI verifies that the server applied the requested environment and complete allowlist before revealing the one-time key. The same access choice is required by mgm init; its key environment defaults to development and can be changed with --environment.

Automation and agents

The CLI is designed to be discoverable and safe in non-interactive environments.

# Inspect the entire command tree or the contract for one command.
mgm commands --json
mgm schema experiments update --json

# Produce JSON and select exactly the values a script needs.
mgm experiments list --project prj_123 --json --jq '.[] | .id'

# Run without a browser or local project file.
MGM_TOKEN="…" MGM_PROJECT_ID="prj_123" mgm experiments list --json

# Explicitly authorize destructive work in CI.
mgm experiments delete exp_123 --project prj_123 --no-input --yes --json

Agent skills

MGM ships skills for instrumentation, metric analysis, funnel diagnosis, and weekly reviews. The CLI uses the standard npm-delivered skills installer, so the same command works for Codex, Claude Code, and other supported agents.

# See the four available MGM skills.
mgm skills list

# Install interactively in the current project.
mgm skills install

# Install all MGM skills globally for Codex without prompts.
mgm skills install --global --agent codex --yes

# Install only the instrumentation skill for Claude Code.
mgm skills install --agent claude-code --skill instrument-my-app

| Option | Purpose | | --- | --- | | --json | Emit machine-readable JSON where supported. | | --jq <expression> | Filter JSON output with the standard jq executable. | | --no-input | Fail instead of opening a browser or prompting. | | -y, --yes | Confirm destructive operations such as deletion, key revocation, widget reset, and stopping an experiment. |

For scripts, use MGM_TOKEN rather than mgm login --token, because command-line arguments can be visible to other local processes. MGM_API_URL and MGM_APP_URL can point the CLI at a local development environment.

Command reference

Run mgm <command> --help for flags and examples. The main command groups are:

| Area | Commands | | --- | --- | | Account | login, signup, logout, whoami | | Organizations and projects | orgs, projects, init | | Credentials | keys | | Product data | dashboard, events, widgets | | Analysis | funnels, retention, queries | | Experiments | experiments | | Discovery | commands, schema |

Use mgm commands --json for the complete command tree, including all subcommands and flags.

Credentials and local files

Interactive credentials are stored in the operating system credential store when available (macOS Keychain, Windows Credential Manager, or the Linux secret service). If no native store is available, the fallback config file is restricted to the current user.

mgm init writes .mgm.json in the current directory with the selected project context. Treat API keys printed by mgm keys create as secrets and store them in your CI secret manager. Human-readable mgm keys list output reports only whether each key is restricted; use --json when you need the full identifier allowlist.

Development

git clone https://github.com/Mostly-Good-Metrics/cli.git
cd cli
npm install
npm run build
npm test
node bin/mgm.js --help

CI runs the build, tests, and a CLI smoke test on Node 20 and 22 for every pull request.

Releasing

Publishing is automated through npm trusted publishing. Create a version bump commit, then tag and push it:

git tag v0.2.0
git push origin v0.2.0

The release.yml workflow builds, tests, and publishes from GitHub Actions using OIDC—no long-lived npm token is stored in the repository. npm automatically attaches provenance to trusted-publisher releases.

License

MIT