CLI reference
Use one mr-data command to work with the hosted backend and receive structured output under –json.
Install
Section titled “Install”pip install mostlyright-datamr-data --version# mr-data 0.19.2The wheel installs mr-data and nothing else. Every command runs on a bare CPython 3.11+ with no compiled extension, because the engine, the readers and the worker image live on the backend. The wheel also carries the mr-data-build agent skill, and the first invocation that finds it missing places it under ~/.claude/skills/mr-data-build and ~/.codex/skills/mr-data-build.
mr-data login signs this machine in once. It stores the credential at ~/.mostlyright/credentials, mode 0600, and never prints it.
Conventions every command shares
Section titled “Conventions every command shares”Every command accepts --json. It writes one JSON object to stdout and nothing else, no progress lines and no prose. Human mode prints the same payload as lines. Every hosted payload carries schema_version (prefix mostlyright-thin-client-), a status word and "lane": "hosted". Three of the four portable commands carry their own mr-data-* schema versions: auth, login and whoami. clarify, the fourth, carries none.
Errors go to stderr. With --json, an error is one object:
{ "schema_version": "mr-data-error.v1", "code": "THIN_REQUEST_INVALID", "error": "mr-data query needs the question to ask: mr-data query RUN \"SELECT ...\"", "headline": "mr-data query needs the question to ask: mr-data query RUN \"SELECT ...\"", "remediation": ["…one line per step…"]}A refusal with a Studio retry window also includes retry_after_seconds.
checks, download, peek, promote, query, receipt, recipe, run and clarify report one line to the dataset page while they work. The report never fails a command. --no-activity turns it off for one invocation. MR_DATA_NO_ACTIVITY=1 turns it off for a whole schedule, which cannot pass a flag.
mr-data download --output takes a relative or absolute folder and expands ~. --output defaults to run-artifacts in the current directory, and it never overwrites anything already there.
--hosted is accepted and stripped in silence. Every invocation already runs on the hosted backend. There is no --local.
Exit codes
Section titled “Exit codes”| Code | What it means |
|---|---|
0 |
The command did what it says. |
1 |
A no that is not a fault. clarify rejected the gate. table archive or demote did not move every table it was given. An auth payload includes a status that is none of the success words and none of unsupported, not_implemented or refused, which leaves error and recovery_required. |
2 |
Every typed error, a THIN_* object on stderr, and the derived gates in the next table. |
Commands that derive a non-zero exit from a successful payload:
| Command | Exits 2 when |
|---|---|
run |
status is run_awaiting_confirmation. The run is held at the confirmation gate and has not started. |
status |
the run’s own status is failed. |
watch |
the terminal event was run_failed. |
checks |
checks_failed is non-zero, or the run failed. |
verify |
findings is non-empty. |
query |
status is query_still_running. This command stopped waiting. The query did not stop. |
probe |
status is anything but probe_answered. |
auth tokens list / auth tokens revoke |
always. status is unsupported. |
table archive and demote take a list and never stop at the first error. They exit 1 when counts.refused + counts.unreachable is non-zero.
Environment variables
Section titled “Environment variables”| Variable | Effect |
|---|---|
MOSTLYRIGHT_CLOUD_URL |
The cloud origin to sign in against and resolve credentials for. https://mostlyright.md when unset. It must be an absolute HTTPS URL with no user information, no fragment and no trailing slash. A path or a query is accepted. A hosted command refuses THIN_CONFIG_INVALID for a URL that is not, and mr-data login refuses LOGIN_CONFIG_INVALID. |
MOSTLYRIGHT_API_KEY |
The legacy v1 shared key. Setting it makes it the effective authority. Receipts then carry "environment_authority": "remains_effective", so a logout that cannot revoke it says so. |
MOSTLYRIGHT_ATTENDED |
Exactly 1 says a person is here to answer a clarifying question. Exactly 0 says nobody is, and that 0 vetoes any --attended flag. mr-data reads any other value as unattended and reports unreadable_environment. |
MR_DATA_NO_ACTIVITY |
1 turns off the automatic dataset-page activity report for every command in that environment. |
MOSTLYRIGHT_SKILL_AUTOINSTALL |
0 stops the wheel placing the mr-data-build agent skill. |
CLAUDE_CONFIG_DIR, CODEX_HOME |
Where the wheel places that skill. Default ~/.claude and ~/.codex. |
CLAUDECODE, CLAUDE_CODE_SESSION, CODEX_SESSION |
A non-empty value means a conversation with somebody in it. mr-data never reads the value. |
CI, GITHUB_ACTIONS |
Either one beside an agent-host variable makes the session headless. An agent host on a runner has nobody to ask. |
Every command
Section titled “Every command”| Command | What it does | Page |
|---|---|---|
catalog |
ask the public-source catalogue what might answer a question | Recipes and sources |
checks |
report how each check the recipe declared came out for one run | Runs |
connections |
list saved connections available for recipes | Recipes and sources |
cover |
generate and attach one branded cover image to a dataset | Datasets |
dataset |
create the page, correct it, write its record, say who can read it, and retire it | Datasets |
demote |
ask Studio to withdraw the live pointer from one table or many | Tables |
diff |
compare two runs and say what changed | Runs |
download |
bring one run’s artifacts back here and check each one’s digest | Reading a table |
keys |
store a source credential by name, name the stored ones, and withdraw one | Recipes and sources |
note |
write one cell of this run’s decision record, or list what is written | Runs |
open |
hand this terminal’s session to the browser as a single-use address | Signing in |
parts |
list one table version’s parts, so a training loader can shard them across workers | Reading a table |
peek |
print the columns, types and first rows of the preview one run wrote | Reading a table |
pin |
ask Studio to pin the live pointer and report the returned state | Tables |
probe |
ask one source one question and print what it answered | Recipes and sources |
promote |
record how often one table refreshes and why. A first succeeded run goes live without it | Tables |
query |
ask one bounded read-only question of the table one run produced | Reading a table |
receipt |
print the receipt, the record of how one run was built | Runs |
recipe |
register or inspect recipe revisions, including incremental-refresh readiness | Recipes and sources |
reschedule |
change how often one table refreshes, without starting a run | Tables |
run |
start one run against a registered recipe, under stated ceilings | Runs |
runs |
report this workspace’s own runs, narrowed by status and by mode | Runs |
status |
report what one run is doing, what it delivered, and why it failed | Runs |
stream |
record a public wss venue and name the recording a build reads | Streams |
table |
report, resync, rename or retire a table | Tables |
unpin |
ask Studio to remove a pin and report the returned pointer state | Tables |
verify |
check one run’s table against its manifest, part by part with --deep |
Runs |
watch |
stream one run’s live progress, resuming across stream cuts | Runs |
auth |
validate the effective device key with Cloud and explain the token boundary, on a bare interpreter with nothing installed beyond this wheel | Signing in |
clarify |
check whether a person is available to answer one question, then format the answer as a record. It contacts no external service unless you name a dataset | Signing in |
login |
sign in and store a device credential | Signing in |
whoami |
the compatibility alias for auth status, which validates against the remote |
Signing in |
Commands that should be hosted and are not yet
Section titled “Commands that should be hosted and are not yet”mr-data <name> refuses THIN_COMMAND_HOSTED_PENDING with the reason and exits 2.
acquire-slicesacquire-slices does not run on the backend yet. The hosted request contract accepts one URL. A slice order needs two origin-bound locators, an ordered plan, and N+2 requests sharing one DNS epoch, which one hosted session each would break.
Backend operator steps, which are never run from here
Section titled “Backend operator steps, which are never run from here”export-hosted-candidateexport-hosted-candidate refuses THIN_COMMAND_IS_WORKER_INTERNAL. It packages a finished Build for the backend to ingest, and the backend runs it on its own artifacts.
Any other word refuses THIN_UNKNOWN_COMMAND, a misspelling and a retired name alike. mr-data --help prints the whole list, and there is no second list of retired names.
Refusal codes this client raises before the network
Section titled “Refusal codes this client raises before the network”A THIN_* code is a stable token a script may branch on. None of them carries a credential.
| Code | What happened |
|---|---|
THIN_UNKNOWN_COMMAND |
The first non-flag token is not a command, or nothing named a command. |
THIN_COMMAND_HOSTED_PENDING |
The name exists and does not run on the backend yet. |
THIN_COMMAND_IS_WORKER_INTERNAL |
The name is a backend operator step. |
THIN_COMMAND_HAS_NO_HOSTED_LANE |
--hosted sits in front of one of those two names. |
THIN_COMMAND_FAILED |
An exception this client does not type. Report it. |
THIN_REQUEST_INVALID |
The contract does not accept the request this invocation assembled. A missing recipe, a sample with no ceiling, a backfill with no window. |
THIN_ARGUMENT_INVALID |
One stated value falls outside a closed vocabulary this client holds. A run identifier that is not one, or a --mode or --status naming a word the contract does not have. The message alone says how to correct it. |
THIN_CONFIG_INVALID |
MOSTLYRIGHT_CLOUD_URL is not a usable HTTPS origin. |
THIN_RESPONSE_INVALID |
Studio returned a body this client will not render. A required member missing, a URL that is not HTTPS, or a narrative cell that did not declare itself unsealed. |
THIN_RESPONSE_TOO_LARGE |
A JSON response exceeded the byte ceiling for its route (1 MiB). |
THIN_AUTHENTICATION_FAILED |
Cloud rejected the stored device credential. Run mr-data login. |
THIN_AUTHORIZATION_DENIED |
The Studio token does not carry the authority this call needs. The sentence quotes Studio’s own code and the HTTP status. |
THIN_NOT_FOUND |
Studio has no such resource. A run in another workspace reads like one that does not exist. |
THIN_RATE_LIMITED |
Cloud asked this command to retry later. retry_after_seconds is on the refusal. |
THIN_STUDIO_UNREACHABLE |
Studio did not answer at all. |
THIN_STUDIO_UNAVAILABLE |
Cloud could not create a Studio token. |
THIN_STUDIO_REFUSED |
Studio returned an error status without its own code. |
THIN_STUDIO_<CODE> |
Studio returned its own code, carried through verbatim. THIN_STUDIO_CONFIRM_REQUIRED, THIN_STUDIO_NOTHING_TO_PROMOTE, THIN_STUDIO_QUERY_TOO_MANY_PARTS and the rest all follow this one rule. |
Per-command codes sit on the page for the command that raises them, among them THIN_DOWNLOAD_DIGEST_MISMATCH, THIN_NO_CHECK_RESULTS, THIN_SECRET_MATERIAL_INVALID and THIN_NARRATIVE_CELL_TOO_LARGE.
Where to go next
Section titled “Where to go next”- Signing in:
login,auth,whoami,open,clarify - Datasets:
dataset,cover - Recipes and sources:
recipe,probe,catalog,connections,keys - Runs:
run,runs,status,watch,checks,receipt,note,diff,verify - Reading a table:
peek,query,download,parts - Tables:
table,promote,reschedule,pin,unpin,demote - Streams:
stream