← Blog Models & Routing 16 September 2026 9 min read

A usage meter for a vendor that has none.

Meta's Muse Code runs in Luminair as its own engine. Meta's API has no usage endpoint to ask. So the Muse meter is our own token tally, priced at Meta's own list rates and shown in dollars, rather than a percentage we would have had to make up.

Fig 01  Where the Muse meter's number comes fromSchematic · from engines/muse.js
ASKED FIRST · META'S API No meter to read usage paths404 billing paths404 account paths404 /modelsanswers Tried with a signed-in account's key, 15 Sep 2026. Dead end: nothing here feeds the meter. ON DISK · THE LAUNCHER'S CATALOG A price per model muse-spark-1.2 in $1.25 · out $4.25 per 1M IN LUMINAIR · TODAY'S TOKEN LOG Tokens per model muse-default in and out kept apart THE METER spark-1.2 · today $5.50 Dollars, not a percentage. Resets at local midnight. Flagged as an estimate. $5.50 is the worked example from the test suite, not anyone's real bill.
Drawn from the usage function in desktop/engines/muse.js and its comments. The catalog rates are the ones on this Mac's disk for muse-spark-1.2; the dollar figure is the test's example of one million input and one million output tokens.

The short version

  1. A usage meter answers one question: how much have I spent? Most vendors let an app ask. Meta does not: every usage, billing and account path we tried on its API answered 404.
  2. What Meta does publish is a price per model, in a catalog file its own launcher keeps on your disk.
  3. Luminair already logs tokens per model for every turn. Multiply the two and you get dollars. That is the Muse meter: one row per Meta model, reset at midnight, marked as an estimate.
  4. We show dollars, not a percentage, because there is no limit to be a percentage of.
02Meta's terminal agent

Meta ships a coding agent.

On 5 August 2026 Meta released Muse Code and Muse Spark 1.2. Meta's post calls Muse Code “a terminal coding agent powered by Muse Spark 1.2, our newest model”, installed on macOS or Linux with a single curl line. It describes a local event log “in which every model call, tool run, approval, and edit is appended”, so the agent can resume where it stopped after a crash.

The Register's write-up the next day, “Meta wants to get inside your terminal with its new coding agent”, put the price plainly: “Muse Spark's actual intelligence is metered at US$1.25 per million input tokens and US$4.25 per million output tokens.”

On Hacker News, the first comment was about a second price: “Meta is offering a 10x discount on input ($0.10 vs. $1.25/Mtok) and 20x discount on output ($0.20 vs. $4.25/Mtok) if you opt in to let them train on your data.” Hold on to that one. It matters twice in this story.

So Muse is pay per token. There is no monthly plan with a five-hour window, no weekly cap. You pay for what you use. That shapes what a useful meter looks like.

03One engine, one file

Muse as an engine, not a plugin.

In Luminair every model company is an engine, and every engine lives in one file. Meta's is desktop/engines/muse.js. Its opening comment calls Muse “engine number three”, and everything Luminair knows about Muse sits there: where the command lives, how it installs and updates itself, how a Meta sign-in becomes a Luminair account, and how its JSON stream turns into the events a session pane understands. The IPC for install, update and status is registered by the file itself, so main.js has no idea the engine exists.

A few things in that file are worth knowing if you use Muse through Luminair.

01

It keeps itself up to date

Meta's installer drops a small launcher at ~/.local/bin/muse. Luminair runs the launcher, not the versioned binary behind it, because the launcher checks Meta's release channel and pulls new builds on its own. The Connectors “Check for update” button just asks it to do that check now and wait for it.

02

One folder per account

muse login is a device-code sign-in that writes its credentials under XDG_CONFIG_HOME. Luminair gives each Meta account its own folder, so several Meta sign-ins sit side by side, the same shape it uses for Codex.

03

It pins the full-price model

This is the second place the discount matters. Meta's picker offers the same model on two terms, and the catalog on disk marks the discounted muse-spark-1.2-contributor as the default. Staying silent would have put every Meta turn on the data-sharing terms. So Luminair always passes --model muse-spark-1.2.

Meta also publishes a local model, Muse Glimmer, as open weights on the Ollama registry. Luminair runs it through Ollama on your Mac, and it only appears in the model picker once the weights are actually on disk. It costs nothing to run, which becomes relevant in a moment.

04Asking for a meter

Every path said 404.

The account menu in Luminair shows a usage line under every signed-in account: how much of Claude's five-hour window is gone, how much of a Codex month, and so on. When Meta accounts arrived, the obvious question was where Muse's line would come from.

The comment above the Muse meter records the answer. On 15 September 2026 we tried Meta's API with a signed-in account's key: it answered 404 on every usage, billing and account path. Only the models listing answered.

At that point there are two easy mistakes. One is to show nothing, and let a Meta account look as if it costs nothing. The other is to invent a percentage: pick a daily budget, divide by it, draw a bar. That bar would look exactly like Claude's and mean something completely different. Worse, it would look authoritative.

A percentage needs a limit. Meta sets none. So the honest unit is the one Meta bills in: dollars.
05The price list on disk

Meta already told us the rate.

While the API would not say what you had spent, the launcher does keep a price list. It caches Meta's model catalog under ~/.local/share/muse/model-catalog/, and every row carries a cost block in US dollars per million tokens. This is the real row for the model Luminair uses, read from the catalog on the Mac this post was written on, trimmed to the fields that matter here:

~/.local/share/muse/model-catalog/*.jsonone row, trimmed
{
  "model_id": "muse-spark-1.2",
  "release_date": "2026-08-05",
  "is_default": false,
  "context_limit": 1007997,
  "cost": { "input": "1.25", "output": "4.25", "cached": "0.15", "currency": "USD" }
}

Those are the same numbers The Register printed. The other half was already in Luminair. Since the token-attribution work in early August, every finished turn goes into a daily log, per model. In the same change as the Meta meter, recordTokenSpend in main.js started keeping input and output tokens apart per model, with a comment saying why: “a pay-per-token engine (Meta) prices them differently, and its meter is this tally times the catalog rate.”

The meter itself is about eighty lines at the end of the engine file. It reads every catalog file, takes today's log across every user scope on the computer, keeps only models whose id starts with muse-, and prices each one. Here is the case the test suite checks:

Fig 02  One day, pricedFrom engine-usage-meters.test.js
Model in today's logTokensRate per 1MRow
muse-defaultpriced as muse-spark-1.21,000,000 in
1,000,000 out
$1.25
$4.25
$1.25
$4.25
muse-glimmerruns on this Mac, costs nothing500,000noneno row
claude-opus-4-8another engine's model500,000noneignored
spark-1.2 · today2,000,000$5.50
Real test data, not a real bill. The test writes a catalog with the two Muse Spark rows, fills today's log, and asserts one row, $5.50, two million tokens, a null percentage, the estimate flag, and a reset time in the future. A second case asserts that a day with no Meta turns still shows one live $0.00 row.

A few rules sit inside that function, and each one is there to avoid a specific kind of wrong number:

  • Local, not Meta. Glimmer turns are skipped. They ran on your machine and Meta billed nothing.
  • Older days fall back gently. Log entries written before the input and output split exist only as a total. For those, the meter uses the day's overall input to output ratio rather than pretending all of it was cheap input.
  • A missing price is said out loud. If a Muse model has no row in the catalog, its line still appears with its token count and a note, “no price in the Meta catalog for” that model, rather than a guessed dollar figure.
  • An idle day is not a missing meter. With nothing run today, the account still shows one row reading $0.00, so you can tell “free today” from “broken”.

Each row carries percent: null, a dollar amount, a reset at local midnight and estimate: true. The account menu already knew how to draw a money-first row with no percentage, because Claude's extra usage credit arrives the same way. So the Meta row slots in without special UI:

Account menu · a Meta account
MMeta accountPay per token
spark-1.2 · today$5.509h

Empty strip: there is no limit to fill. The figure is the money; the short time is how long until the row resets at midnight.

Drawn from setLimLine and the account card code in desktop/renderer.js, with the test's $5.50 and an example reset time. In the app the card wears the Meta engine's colour; it is drawn in ink here.
06Three vendors, three meters

Each meter says what it is.

The Muse meter landed on 16 September 2026 in the same commit as two others, for engines whose vendors also publish no meter an app can call directly. Put side by side, they show why one shape does not fit every vendor.

Fig 03  Where each non-Claude meter reads fromFrom desktop/engines
Kimi
The vendor's own numbers

The Kimi command-line tool talks to a usage endpoint. Luminair calls it with the tool's own saved token and turns the weekly, five-hour and booster figures into rows.

30% · 25% · $5
Antigravity
The tool's own quota log

Google's agy prints its quota in a verbose log. When Google refuses a turn with a reset time, that one bucket is stamped full until the reset it named.

% per window
Meta Muse
Luminair's tally × Meta's price

No endpoint and no limit. Today's tokens per model, priced from the launcher's catalog, shown in dollars and flagged as an estimate.

$ per model, today
The Kimi values are the ones asserted in the test suite. The dashed outline marks the only meter of the three that Luminair computes itself. The Kimi meter was written from the CLI's source; the code notes no Kimi account was signed in to see a live payload.

That is the whole rule. A meter should be the vendor's number when there is one, the vendor's refusal when that is all there is, and, when there is neither, our own count in the vendor's own currency, labelled as ours.

Where it livesInstall Muse from Settings › Connectors › Models › Meta Muse. Once a Meta account is signed in, open the account menu: the Meta card shows one dollar line per Meta model you used today. Muse is not available on Windows yet; Meta distributes it with a POSIX install script.
07What we checked

Checked, and not claimed.

6/6
Usage-meter tests pass, including the Muse pricing case and its idle $0.00 row
$5.50
The test's day: one million input and one million output tokens at $1.25 and $4.25 per million
2
Rows in the Muse catalog on disk: the same model on full-price and contributor terms
404
What Meta's API answered on every usage, billing and account path, per the note in the engine file

What this post does not claim

  • That the meter matches your Meta invoice. It is a tally on this computer only, priced at list rates. Turns run elsewhere do not appear.
  • That cached input is priced. The catalog lists a cached rate, but the tally does not split cached tokens out, so the meter prices all input at the input rate.
  • That every Muse Spark turn reports its token counts. The meter can only price what the log holds; a turn that ends without counts is logged as a turn with no usage and adds nothing.
  • That Meta will never publish a usage endpoint. If it does, the engine file is the one place to switch to it.

Sources

For how Luminair holds many engines in one app, read One window for every model.

See what every model costs you

Sign in to Meta, Claude, Codex and more, and read each account's usage in one menu.

Download Luminair →