Mithrl-1 CLI
Mithrl, an easy to use command line interface.
KG-primitive commands print compact TSV by default and accept --json; workflow and management commands print machine-readable JSON. Commands print a trace of their backing operation on stderr. Payloads carrying a result_id can be replayed with mithrl results or composed with mithrl filter and mithrl export without recomputing.
For the complete upload → run → monitor → download lifecycle, see Running and managing Inference.
Exit codes: 0 success, 1 error (a structured {"error": {...}} on stderr), 2 bad usage, 3 incomplete (the command worked but the work it was asked to do is demonstrably still unfinished — e.g. filter/export cut short by their drain's --timeout/page limit; see each command's own constraints). For mithrl run in its default blocking mode, 3 means the bounded wait elapsed with the run still active: it still prints its normal payload, carrying the run_id and the mithrl status <run_id> --watch command to reattach with, so a script must not read it as success and must not re-submit.
4 remote failure (the command worked, and the run it was reporting on reached a terminal failed or cancelled state). mithrl run, mithrl status and mithrl run-results all exit 4 in that case, print their normal payload on stdout, and spell the server's failure block — code, stage, category, message — out on stderr. 4 is deliberately distinct from 1: 1 means the CLI could not complete its own call (no credentials, no network, a 5xx) and is often worth retrying verbatim, while 4 means the call succeeded and the answer is that the work failed, which never is.
mithrl status exits 0 while a run is still active — including when its own bounded watch expires first — so read data.run.status to tell those two apart; the exit code distinguishes only "still going" (0) from "finished and failed" (4).
Argument values are trimmed of surrounding whitespace, so a value pasted with a stray leading or trailing space behaves exactly like a clean one — most visibly for mithrl api set, where an untrimmed URL previously persisted verbatim and then failed to match the URL recorded at login. This applies to file-path arguments too (mithrl upload, mithrl validate): a path whose name deliberately begins or ends with a space no longer resolves, and must be renamed to be passed on the command line.
Introspection
Emit the machine-readable spec the other CLI surfaces are generated from.
mithrl spec
Emit the machine-readable mithrl command/flag spec — the single source of truth --help and the /mithrl skill are generated from. Scoped by default: an index of every command, with one command's full flags, constraints and caveats a mithrl spec <command> away.
Constraints
Depth follows scope: a scoped call (a command, a group, or --section) prints every field of what it selected, while an unscoped call prints the index -- every command's name, one-line help, section, status and param count.
--fulland--briefoverride that in either direction, and are mutually exclusive.A selector and --section name different scopes and can't be combined. A selector matches a full command name first (
keys create), then a group prefix (keys); an unknown one fails asnot_foundwith the closest command names.--fullprints the pre-scoping payload --{"commands": [...]}with every field -- unchanged. The index addsbrief: trueand anextobject naming the scoped forms, and carries every command, so a caller reading onlynamesees the same list it always did.
Arguments
command
str, repeatable
no
A command or group to scope the output to, typed exactly as you would type the command itself (mithrl spec keys create, mithrl spec keys).
Options
--section
str
no
—
Scope to one documentation section instead of one command, e.g. --section 'KG primitives'. Case-insensitive; the index names them.
--full
bool
no
False
Emit every field of every selected command. Unscoped, this is the whole spec (~24k tokens for 39 commands) -- prefer a scoped call.
--brief
bool
no
False
Emit the index shape (name, help, section, status, param count) even when scoped.
Examples
Auth & local infra
Sign in, manage API keys, and install the agent-facing tooling.
mithrl login
Browser-based sign-in (interactive; human-only).
Options
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl logout
Clear locally stored credentials.
Examples
mithrl keys add
Register an API key locally from keys create's own JSON output (piped via stdin).
Constraints
Reads a JSON object from stdin -- pipe
mithrl keys create's own output straight in.
Examples
mithrl keys use
Activate a locally-registered API key (from keys add) instead of an interactive login session.
Constraints
Exactly one of -p/--prefix or -n/--name is required.
Options
-p, --prefix
str
no
—
The key's prefix (from keys add/keys list, e.g. ltk_live_ab12cd34ef56).
-n, --name
str
no
—
The key's name (from keys create --name), if it uniquely identifies one added key.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl keys create
Create a scoped, read-only API key for headless/agent use.
Options
--name
str
no
—
Label for the new key.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl keys list
List existing API keys.
Options
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl keys revoke
Revoke an API key.
Arguments
key_id
str
yes
The key's prefix (from keys list, e.g. ltk_live_ab12cd34ef56) or its numeric id.
Options
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl keys rotate
Rotate an API key.
Arguments
key_id
str
yes
The key's prefix (from keys list, e.g. ltk_live_ab12cd34ef56) or its numeric id.
Options
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl api set
Configure the platform admin API's base URL (persisted locally).
Constraints
Optional: the CLI has a built-in default deployment. Run this only to point it at a different one, such as a self-hosted deployment.
Arguments
url
str
yes
Base URL of the platform admin API, e.g. https://platform.example.com.
Examples
mithrl api default
Point mithrl at the production deployment.
Examples
mithrl api show
Show the platform admin API base URL in effect, and whether it came from local configuration or the built-in default.
Examples
mithrl api clear
Remove the locally configured API base URL, reverting to the built-in default.
Examples
mithrl skill install
Register the /mithrl skill for coding agents.
Examples
mithrl update
Signature-verified self-update (binary + snapshot).
Constraints
--check, --rollback, and --reset-ratchet are mutually exclusive.
Applying an update requires a packaged install; elsewhere the command reports the available version and points at your package manager instead.
Applying an update and --rollback are not supported on Windows yet, because a running executable cannot replace itself there.
--check works on every platform and install type.
Options
--check
bool
no
False
Check for an available update without applying it.
--rollback
bool
no
False
Restore the previously installed version.
--reset-ratchet
bool
no
False
Clear the locally-stored last-verified-update-version downgrade/freeze check.
Examples
KG primitives
Query the knowledge graph directly: resolve names, read nodes, walk edges, find paths.
mithrl search
Resolve a name/exact/regex/substring query to typed nodes.
Constraints
A resolved result is not proof the query matches the real question. A generic term (a disease name standing in for the actual drug candidate, a bare gene symbol standing in for a specific allele, one gene standing in for a whole gene set) returns real nodes/edges just as cleanly as a fully specified one -- confirm the query names the actual compound/structure, target, organism and strain, allele, gene set, or model before treating its result as the answer.
Read the matchType column before treating a result as the entity named. Only EXACT_NAME, EXACT_CURIE, EXACT_SYNONYM and EQUIVALENT_CURIE identify that entity; XREF, NAME_SUBSTRING and SYNONYM are approximations, and a matched alternative name FRAGMENT can belong to a broader or narrower concept whose own name shares no word with the query. Matching is literal throughout -- there is no fuzzy, phonetic or semantic matching -- so an unexpected result came through one of those arms, not through a similarity score.
Results are ordered by, in this priority: whether the entity comes from a curated vocabulary rather than from free text lifted out of a corpus (a clinical-trial record, a publication title); then how strongly it matched (an exact name, then an exact alternative name, then a fragment of either); then whether its PRIMARY category is the one --type asked for and whether it is human. Corroboration across sources and name length only break ties. So a trial arm literally named "Glucose" ranks below the CHEBI metabolite that carries
glucoseas an alternative name, and a human gene symbol ranks above its rodent ortholog when the capitalisation differs. Nothing is excluded by this -- every match is still returned, and a query that only a trial or a paper matches still finds it.Same symbol, different species: human gene symbols collide with their rodent orthologs (EGFR, TP53, BRCA1, ...), and
--type/--type-a/--type-bcannot separate a collision where every candidate is a Gene.--organism(aka--taxon) is what resolves it -- pass--organism humanwhenever a bare gene symbol is the identifier and the question is about human biology. It narrows the candidates a NAME resolves to; against an already-CURIE identifier it is checked instead, and a CURIE belonging to another species fails astaxon_mismatchrather than answering for the wrong organism. A candidate that reports no organism is never excluded (a disease or pathway has none), so one flag is safe onpath's two endpoints. On a name whose every candidate belongs to another species the command failsnot_foundnaming those species, never an empty result.On
search, --organism narrows the query itself, in the graph store, BEFORE --limit is applied -- so a page holds --limit matches in that organism rather than however few of a mixed-species page survived. The command says on stderr (and underorganismNotein --json) how many matches the filter removed and which species they belonged to, counted over every match and not just this page.--countreturns the size of one bounded page, not a server-side total --searchhas no total-count mode and no cursor, socandidateCountis capped by--limit, or by the API's own default of 20 when--limitis omitted.--limitis itself clamped to 100 server-side -- a--limitabove that is not honored, and search reports no signal of its own when the clamp fires. Below that ceiling, a count landing exactly on --limit/the default means "at least this many" (the payload's ownnotesays so) -- raise--limit, up to the ceiling, until the count comes back under it before reporting the number as a total. A count that lands at the 100 ceiling itself can never be confirmed as a total fromsearch-- it means "at least 100", full stop, and a different route (e.g. a narrower --type, or a source with a real total-count mode) is needed for the actual number.The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.
Arguments
query
str
yes
Name, exact/regex/substring query, or CURIE.
Options
--type
str
no
—
Filter candidates by category.
--organism, --taxon
str
no
—
Restrict to one species, e.g. --organism human (also --taxon). Accepts human, mouse, rat, zebrafish, fly, worm, yeast, an NCBITaxon CURIE (NCBITaxon:9606), or a bare taxon id (9606). This is the fix for a gene symbol that resolves to several species' orthologs -- --type cannot separate those, since every one of them is a Gene. Entities that carry no organism at all (a disease, a pathway, a chemical) are never filtered out by it. Distinct from --species, which filters on an edge's species_context qualifier -- the organism the experiment was run in, not the organism of the entities the edge connects.
-n, --limit
int
no
—
Maximum number of candidates to return. Clamped to 100 server-side -- a value above that is not honored, and search reports no signal of its own when the clamp fires.
-c, --count
bool
no
False
Return only the candidate count (capped by --limit/the API's own default -- not a true server-side total).
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl lookup
Fetch one node by name or CURIE.
Constraints
A resolved result is not proof the query matches the real question. A generic term (a disease name standing in for the actual drug candidate, a bare gene symbol standing in for a specific allele, one gene standing in for a whole gene set) returns real nodes/edges just as cleanly as a fully specified one -- confirm the query names the actual compound/structure, target, organism and strain, allele, gene set, or model before treating its result as the answer.
A CURIE is accepted as given -- a well-formed identifier for the wrong entity resolves exactly as cleanly as the right one, and returns a complete, credible result for it. Read the
resolved:line this prints to stderr (canonical name, CURIE, category, organism) and confirm it is the entity you meant before using the result; pass--expect <name>to have that checked for you rather than by eye.--typeis checked too in this case (it otherwise only narrows candidates while resolving a bare name, which a CURIE skips entirely) -- a CURIE of the wrong category fails ascategory_mismatchrather than silently ignoring--type. An identifier that is resolved and its node fetched fails asnot_foundwhen the active build holds no node for it, whether or not--expect/--typewas passed -- sono edgesandno path foundare answers about the graph rather than about a name it does not have. Forms that make no per-identifier node lookup (--batch, and--depth 0where offered) are outside that guarantee and can still report an empty result for an identifier the build does not hold.Same symbol, different species: human gene symbols collide with their rodent orthologs (EGFR, TP53, BRCA1, ...), and
--type/--type-a/--type-bcannot separate a collision where every candidate is a Gene.--organism(aka--taxon) is what resolves it -- pass--organism humanwhenever a bare gene symbol is the identifier and the question is about human biology. It narrows the candidates a NAME resolves to; against an already-CURIE identifier it is checked instead, and a CURIE belonging to another species fails astaxon_mismatchrather than answering for the wrong organism. A candidate that reports no organism is never excluded (a disease or pathway has none), so one flag is safe onpath's two endpoints. On a name whose every candidate belongs to another species the command failsnot_foundnaming those species, never an empty result.The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.
Arguments
name
str
yes
Name or CURIE to look up.
Options
--type
str
no
—
Filter candidates by category.
--organism, --taxon
str
no
—
Restrict to one species, e.g. --organism human (also --taxon). Accepts human, mouse, rat, zebrafish, fly, worm, yeast, an NCBITaxon CURIE (NCBITaxon:9606), or a bare taxon id (9606). This is the fix for a gene symbol that resolves to several species' orthologs -- --type cannot separate those, since every one of them is a Gene. Entities that carry no organism at all (a disease, a pathway, a chemical) are never filtered out by it. Distinct from --species, which filters on an edge's species_context qualifier -- the organism the experiment was run in, not the organism of the entities the edge connects.
--xrefs
bool
no
False
Include cross-references to other vocabularies.
--expect
str
no
—
Assert which entity the identifier names, e.g. --expect RALGDS. Matched against the resolved node's canonical name and synonyms, case-insensitively; a mismatch fails the command instead of answering for the wrong entity. Use it whenever the identifier came from outside this CLI (memory, a paper, another tool) rather than from search/lookup.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl members
Bulk gene-to-pathway and gene-to-disease set membership.
Constraints
Exactly one of the positional <term>, --of, or --batch is required.
--in is always required (the membership query needs a predicate either way); must be pathways or diseases.
--batch reads newline-separated gene names/CURIEs from stdin; blank lines are skipped.
A --batch entry that fails to resolve (ambiguous or not found) never aborts the others -- membership() runs once over whatever did resolve, and every unresolved entry is reported in a per-entry
errorslist instead, in the same exit-0 response (even when none resolve). The unresolved names, with their reason, are also named on stderr in the default output, so finding out which inputs were lost does not cost a second run of the whole batch.--batch resolves its whole input in one call per 100 names (duplicate lines are asked once), so a 100-gene panel costs one resolution round-trip rather than 100. Progress is reported on stderr for a batch of 25 or more. The result note counts lines, distinct inputs and resolved entities separately -- two names can resolve to one entity, and membership() is keyed by entity.
A positional argument is read as a term when it is itself a pathway or disease, and as a participant otherwise; --of and --batch are always read as participants.
Pathway membership spans both stored orientations of the relation, so an entity is reported as belonging to a pathway whether the edge runs entity-to-pathway (participates_in) or pathway-to-entity (has_participant).
A positional argument that is not in the build is reported as not_found rather than as an empty set.
A returned list is a window on the real set: memberCount reports the true size, memberOffset where the window starts, truncated whether members lie beyond it, and the output prints a banner naming the next --offset. Walk a large set with --limit and --offset on this command; successive offsets partition the set with no overlap and no gaps, in CURIE order. (Paging with
mithrl results <id> --page Npages the SETS this command returned, not the members inside them.)--expect applies to the single-entity forms only; it is rejected alongside --batch.
--type only filters a bare-name --batch line; rejected alongside --batch if any line is already a CURIE, rather than silently skipping the filter for just that line.
--organism behaves exactly as --type does on --batch: it filters every bare-name line, and is rejected if any line is already a CURIE. A batch of bare human gene symbols is the form it is for -- pass --organism human to keep symbols that also name a rodent ortholog from failing as ambiguous.
Same symbol, different species: human gene symbols collide with their rodent orthologs (EGFR, TP53, BRCA1, ...), and
--type/--type-a/--type-bcannot separate a collision where every candidate is a Gene.--organism(aka--taxon) is what resolves it -- pass--organism humanwhenever a bare gene symbol is the identifier and the question is about human biology. It narrows the candidates a NAME resolves to; against an already-CURIE identifier it is checked instead, and a CURIE belonging to another species fails astaxon_mismatchrather than answering for the wrong organism. A candidate that reports no organism is never excluded (a disease or pathway has none), so one flag is safe onpath's two endpoints. On a name whose every candidate belongs to another species the command failsnot_foundnaming those species, never an empty result.A CURIE is accepted as given -- a well-formed identifier for the wrong entity resolves exactly as cleanly as the right one, and returns a complete, credible result for it. Read the
resolved:line this prints to stderr (canonical name, CURIE, category, organism) and confirm it is the entity you meant before using the result; pass--expect <name>to have that checked for you rather than by eye.--typeis checked too in this case (it otherwise only narrows candidates while resolving a bare name, which a CURIE skips entirely) -- a CURIE of the wrong category fails ascategory_mismatchrather than silently ignoring--type. An identifier that is resolved and its node fetched fails asnot_foundwhen the active build holds no node for it, whether or not--expect/--typewas passed -- sono edgesandno path foundare answers about the graph rather than about a name it does not have. Forms that make no per-identifier node lookup (--batch, and--depth 0where offered) are outside that guarantee and can still report an empty result for an identifier the build does not hold.The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.
Arguments
term
str
no
Entity or term to query membership for. A pathway or disease is read as a term (its members are listed); anything else is read as a participant (the terms it belongs to are listed). The output states which of the two it did.
Options
--of
str
no
—
Query as a participant, listing the terms it belongs to. Skips the inference above.
--in
str
no
—
Membership kind: pathways or diseases.
--type
str
no
—
Filter candidates by category (applies to <term>/--of/every bare-name --batch line; rejected if any --batch line is already a CURIE).
--organism, --taxon
str
no
—
Restrict to one species, e.g. --organism human (also --taxon). Accepts human, mouse, rat, zebrafish, fly, worm, yeast, an NCBITaxon CURIE (NCBITaxon:9606), or a bare taxon id (9606). This is the fix for a gene symbol that resolves to several species' orthologs -- --type cannot separate those, since every one of them is a Gene. Entities that carry no organism at all (a disease, a pathway, a chemical) are never filtered out by it. Distinct from --species, which filters on an edge's species_context qualifier -- the organism the experiment was run in, not the organism of the entities the edge connects.
--batch
bool
no
False
Read a gene set from stdin (one name/CURIE per line) instead of <term>/--of, resolving the whole set in a single bulk membership() call.
--limit
int
no
—
Members returned per set. Omitted means the API's own ceiling; a request above it is clamped, not rejected. This bounds one window, not the set -- walk the rest with --offset.
--offset
int
no
0
Skip this many members of each set before returning --limit of them. Page 2 of a --limit 100 walk is --offset 100; the truncation banner prints the next offset to use, and memberCount says when to stop.
--expect
str
no
—
Assert which entity the identifier names, e.g. --expect RALGDS. Matched against the resolved node's canonical name and synonyms, case-insensitively; a mismatch fails the command instead of answering for the wrong entity. Use it whenever the identifier came from outside this CLI (memory, a paper, another tool) rather than from search/lookup.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl scan
Stream an unranked graph slice for sweeps and piping.
Constraints
The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.
Options
--predicate, -p
str
yes
—
Predicate to scan for, e.g. regulates or interacts_with.
--type
str
no
—
Filter by category (the edges' object category).
--source
str, at most one
no
—
Filter by contributing knowledge source. Case-insensitive. Limited: edges(...) takes a single source, not a list — a second --source is rejected.
--qualifier
str, repeatable
no
—
Filter on an edge qualifier as key=value (e.g. --qualifier object_aspect=phosphorylation), repeatable. The same key repeated ORs its values; distinct keys AND.
--direction
str, repeatable
no
—
Filter to a signed direction of effect (increased/decreased/upregulated/downregulated), repeatable. Sugar for --qualifier object_direction=...; each value also matches its cross-vocabulary spelling (increased also matches upregulated, and vice versa). Object-side only -- sources that write the signed effect on subject_direction instead (e.g. perturbseq's CRISPRi knockdowns) are not matched; use --qualifier subject_direction=... for those.
--tissue
str, repeatable
no
—
Filter to an anatomical context by CURIE (e.g. --tissue UBERON:0002107), repeatable. Sugar for --qualifier anatomical_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet. Also matches only the ontology your CURIE's prefix names: anatomical_context spans MESH (ctd), CL (perturbseq), and BTO/CL/UBERON (signor), so a single --tissue UBERON:... reaches signor's rows for that tissue but not ctd's or perturbseq's -- there is no cross-ontology expansion yet, so a correct CURIE can still return a small fraction of the matching edges with no error.
--species
str, repeatable
no
—
Filter to a species context by CURIE (e.g. --species NCBITaxon:9606), repeatable. Sugar for --qualifier species_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet. This is the organism the EXPERIMENT was run in, recorded on the edge -- NOT the organism of the entities at its ends, which is what the separate --organism/--taxon flag filters (offered by ls and tree, not by scan/match -- check the command's own --help). An edge between human entities that was measured in mouse matches --organism human and --species NCBITaxon:10090 at once, so neither flag substitutes for the other. Edges whose source records no experimental organism carry no species_context and are dropped by this filter.
--cell-line
str, repeatable
no
—
Filter to a cell-line context by CURIE (e.g. --cell-line cellosaurus:CVCL_0004), repeatable. Sugar for --qualifier cell_line_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl cat
Print a node's properties/edges/citations.
Constraints
A CURIE is accepted as given -- a well-formed identifier for the wrong entity resolves exactly as cleanly as the right one, and returns a complete, credible result for it. Read the
resolved:line this prints to stderr (canonical name, CURIE, category, organism) and confirm it is the entity you meant before using the result; pass--expect <name>to have that checked for you rather than by eye.--typeis checked too in this case (it otherwise only narrows candidates while resolving a bare name, which a CURIE skips entirely) -- a CURIE of the wrong category fails ascategory_mismatchrather than silently ignoring--type. An identifier that is resolved and its node fetched fails asnot_foundwhen the active build holds no node for it, whether or not--expect/--typewas passed -- sono edgesandno path foundare answers about the graph rather than about a name it does not have. Forms that make no per-identifier node lookup (--batch, and--depth 0where offered) are outside that guarantee and can still report an empty result for an identifier the build does not hold.Same symbol, different species: human gene symbols collide with their rodent orthologs (EGFR, TP53, BRCA1, ...), and
--type/--type-a/--type-bcannot separate a collision where every candidate is a Gene.--organism(aka--taxon) is what resolves it -- pass--organism humanwhenever a bare gene symbol is the identifier and the question is about human biology. It narrows the candidates a NAME resolves to; against an already-CURIE identifier it is checked instead, and a CURIE belonging to another species fails astaxon_mismatchrather than answering for the wrong organism. A candidate that reports no organism is never excluded (a disease or pathway has none), so one flag is safe onpath's two endpoints. On a name whose every candidate belongs to another species the command failsnot_foundnaming those species, never an empty result.Every section validates its node identically -- an ambiguous name, an unknown one, or an identifier absent from the build fails the same way in all three -- and all three accept --expect/--type on the same terms.
/provenance reports what the node's OWN record cites: the knowledge sources that contributed the entity and the publications that record names. It is not the union of provenance across the node's edges -- for that, page
<node>/edges --provenance, which reports it per assertion. Many nodes are minted from edge data and carry neither, which the command states rather than leaving as blank cells.--limit bounds one page of the /edges section only; on /meta and /provenance it is rejected rather than ignored. Reach the rest of a large neighborhood with
results <id> --page Norexport <id>, exactly as withls.The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.Section shape decides what --full/--provenance do: /edges is edge-shaped and both widen it; the default /meta section is a single node, which --full widens and --provenance has no envelope to widen; /provenance already shows the node's sources and publications, so --provenance is redundant there and --full adds the rest of the record.
Arguments
target
str
yes
Node, optionally suffixed with /meta (its record), /edges (a page of its edges), or /provenance (the sources and publications its own record cites). All three are backed by real operations.
Options
--type
str
no
—
Filter candidates by category.
--organism, --taxon
str
no
—
Restrict to one species, e.g. --organism human (also --taxon). Accepts human, mouse, rat, zebrafish, fly, worm, yeast, an NCBITaxon CURIE (NCBITaxon:9606), or a bare taxon id (9606). This is the fix for a gene symbol that resolves to several species' orthologs -- --type cannot separate those, since every one of them is a Gene. Entities that carry no organism at all (a disease, a pathway, a chemical) are never filtered out by it. Distinct from --species, which filters on an edge's species_context qualifier -- the organism the experiment was run in, not the organism of the entities the edge connects.
--limit
int
no
—
Edges per page for the /edges section (default 50, the API's own). At most 100 per page: a larger value is clamped, and the header says so. results <id> --page 1 fetches the rest. Rejected on /meta and /provenance, which return a single record.
--expect
str
no
—
Assert which entity the identifier names, e.g. --expect RALGDS. Matched against the resolved node's canonical name and synonyms, case-insensitively; a mismatch fails the command instead of answering for the wrong entity. Use it whenever the identifier came from outside this CLI (memory, a paper, another tool) rather than from search/lookup.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl ls
List a node's neighbors/edges, filtered by relation. Returns one page: a hub node with more edges than --limit reports the total and is continued with mithrl results <id> --page 2 (or exported whole with mithrl export <id>).
Constraints
A resolved result is not proof the query matches the real question. A generic term (a disease name standing in for the actual drug candidate, a bare gene symbol standing in for a specific allele, one gene standing in for a whole gene set) returns real nodes/edges just as cleanly as a fully specified one -- confirm the query names the actual compound/structure, target, organism and strain, allele, gene set, or model before treating its result as the answer.
A CURIE is accepted as given -- a well-formed identifier for the wrong entity resolves exactly as cleanly as the right one, and returns a complete, credible result for it. Read the
resolved:line this prints to stderr (canonical name, CURIE, category, organism) and confirm it is the entity you meant before using the result; pass--expect <name>to have that checked for you rather than by eye.--typeis checked too in this case (it otherwise only narrows candidates while resolving a bare name, which a CURIE skips entirely) -- a CURIE of the wrong category fails ascategory_mismatchrather than silently ignoring--type. An identifier that is resolved and its node fetched fails asnot_foundwhen the active build holds no node for it, whether or not--expect/--typewas passed -- sono edgesandno path foundare answers about the graph rather than about a name it does not have. Forms that make no per-identifier node lookup (--batch, and--depth 0where offered) are outside that guarantee and can still report an empty result for an identifier the build does not hold.Same symbol, different species: human gene symbols collide with their rodent orthologs (EGFR, TP53, BRCA1, ...), and
--type/--type-a/--type-bcannot separate a collision where every candidate is a Gene.--organism(aka--taxon) is what resolves it -- pass--organism humanwhenever a bare gene symbol is the identifier and the question is about human biology. It narrows the candidates a NAME resolves to; against an already-CURIE identifier it is checked instead, and a CURIE belonging to another species fails astaxon_mismatchrather than answering for the wrong organism. A candidate that reports no organism is never excluded (a disease or pathway has none), so one flag is safe onpath's two endpoints. On a name whose every candidate belongs to another species the command failsnot_foundnaming those species, never an empty result.The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.
Arguments
node
str
yes
Node to list neighbors of.
Options
--rel
str
no
—
Filter by relation/predicate -- a closed vocabulary, listable with mithrl schema --predicates.
--type
str
no
—
Filter candidates by category.
--organism, --taxon
str
no
—
Restrict to one species, e.g. --organism human (also --taxon). Accepts human, mouse, rat, zebrafish, fly, worm, yeast, an NCBITaxon CURIE (NCBITaxon:9606), or a bare taxon id (9606). This is the fix for a gene symbol that resolves to several species' orthologs -- --type cannot separate those, since every one of them is a Gene. Entities that carry no organism at all (a disease, a pathway, a chemical) are never filtered out by it. Distinct from --species, which filters on an edge's species_context qualifier -- the organism the experiment was run in, not the organism of the entities the edge connects.
--limit
int
no
50
Edges per page. At most 100 per page: a larger value is clamped, and the header says so; results <id> --page 1 fetches the rest. This bounds one page, not the result — use results --page N or export to reach a node's whole neighborhood.
--qualifier
str, repeatable
no
—
Filter on an edge qualifier as key=value (e.g. --qualifier object_aspect=phosphorylation), repeatable. The same key repeated ORs its values; distinct keys AND.
--direction
str, repeatable
no
—
Filter to a signed direction of effect (increased/decreased/upregulated/downregulated), repeatable. Sugar for --qualifier object_direction=...; each value also matches its cross-vocabulary spelling (increased also matches upregulated, and vice versa). Object-side only -- sources that write the signed effect on subject_direction instead (e.g. perturbseq's CRISPRi knockdowns) are not matched; use --qualifier subject_direction=... for those.
--tissue
str, repeatable
no
—
Filter to an anatomical context by CURIE (e.g. --tissue UBERON:0002107), repeatable. Sugar for --qualifier anatomical_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet. Also matches only the ontology your CURIE's prefix names: anatomical_context spans MESH (ctd), CL (perturbseq), and BTO/CL/UBERON (signor), so a single --tissue UBERON:... reaches signor's rows for that tissue but not ctd's or perturbseq's -- there is no cross-ontology expansion yet, so a correct CURIE can still return a small fraction of the matching edges with no error.
--species
str, repeatable
no
—
Filter to a species context by CURIE (e.g. --species NCBITaxon:9606), repeatable. Sugar for --qualifier species_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet. This is the organism the EXPERIMENT was run in, recorded on the edge -- NOT the organism of the entities at its ends, which is what the separate --organism/--taxon flag filters (offered by ls and tree, not by scan/match -- check the command's own --help). An edge between human entities that was measured in mouse matches --organism human and --species NCBITaxon:10090 at once, so neither flag substitutes for the other. Edges whose source records no experimental organism carry no species_context and are dropped by this filter.
--cell-line
str, repeatable
no
—
Filter to a cell-line context by CURIE (e.g. --cell-line cellosaurus:CVCL_0004), repeatable. Sugar for --qualifier cell_line_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet.
--expect
str
no
—
Assert which entity the identifier names, e.g. --expect RALGDS. Matched against the resolved node's canonical name and synonyms, case-insensitively; a mismatch fails the command instead of answering for the wrong entity. Use it whenever the identifier came from outside this CLI (memory, a paper, another tool) rather than from search/lookup.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl tree
Expand an N-hop neighborhood (fan-out capped).
Constraints
A CURIE is accepted as given -- a well-formed identifier for the wrong entity resolves exactly as cleanly as the right one, and returns a complete, credible result for it. Read the
resolved:line this prints to stderr (canonical name, CURIE, category, organism) and confirm it is the entity you meant before using the result; pass--expect <name>to have that checked for you rather than by eye.--typeis checked too in this case (it otherwise only narrows candidates while resolving a bare name, which a CURIE skips entirely) -- a CURIE of the wrong category fails ascategory_mismatchrather than silently ignoring--type. An identifier that is resolved and its node fetched fails asnot_foundwhen the active build holds no node for it, whether or not--expect/--typewas passed -- sono edgesandno path foundare answers about the graph rather than about a name it does not have. Forms that make no per-identifier node lookup (--batch, and--depth 0where offered) are outside that guarantee and can still report an empty result for an identifier the build does not hold.Same symbol, different species: human gene symbols collide with their rodent orthologs (EGFR, TP53, BRCA1, ...), and
--type/--type-a/--type-bcannot separate a collision where every candidate is a Gene.--organism(aka--taxon) is what resolves it -- pass--organism humanwhenever a bare gene symbol is the identifier and the question is about human biology. It narrows the candidates a NAME resolves to; against an already-CURIE identifier it is checked instead, and a CURIE belonging to another species fails astaxon_mismatchrather than answering for the wrong organism. A candidate that reports no organism is never excluded (a disease or pathway has none), so one flag is safe onpath's two endpoints. On a name whose every candidate belongs to another species the command failsnot_foundnaming those species, never an empty result.--depth 0 resolves nothing (it makes no API call), so it prints no
resolved:line and --expect/--type/--organism are all rejected there.The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.--depth 2 returns a subgraph, which has no compact TSV view: it prints the JSON envelope whether or not --json is passed, so --full/--provenance are inert there too. Depths 0 and 1 return an edge list and widen normally.
A --depth 2 subgraph is capped: truncated/truncatedNodes/truncatedEdges say so, nodeCount/edgeCount report what was RETURNED rather than the neighbourhood's size, and a truncated result prints a banner on stderr. subgraph() has no cursor or page size, so narrowing with --rel, or walking hop by hop with the cursor-paginated
mithrl ls <node>, is the only way to see more.--depth 2 calls subgraph(...), which has no qualifier filter at all, so --qualifier/--direction/--tissue/--species/--cell-line are all rejected there.
--depth 2 also rejects --organism: subgraph(...) has no organism filter, so the flag would narrow only the seed lookup while the expansion stayed cross-species. Use --depth 1 for an organism-filtered walk.
Arguments
node
str
yes
Node to expand.
Options
--depth
int
no
1
Neighborhood depth.
--rel
str
no
—
Filter by relation/predicate -- a closed vocabulary, listable with mithrl schema --predicates.
--type
str
no
—
Filter candidates by category.
--organism, --taxon
str
no
—
Restrict to one species, e.g. --organism human (also --taxon). Accepts human, mouse, rat, zebrafish, fly, worm, yeast, an NCBITaxon CURIE (NCBITaxon:9606), or a bare taxon id (9606). This is the fix for a gene symbol that resolves to several species' orthologs -- --type cannot separate those, since every one of them is a Gene. Entities that carry no organism at all (a disease, a pathway, a chemical) are never filtered out by it. Distinct from --species, which filters on an edge's species_context qualifier -- the organism the experiment was run in, not the organism of the entities the edge connects.
--qualifier
str, repeatable
no
—
Filter on an edge qualifier as key=value (e.g. --qualifier object_aspect=phosphorylation), repeatable. The same key repeated ORs its values; distinct keys AND.
--direction
str, repeatable
no
—
Filter to a signed direction of effect (increased/decreased/upregulated/downregulated), repeatable. Sugar for --qualifier object_direction=...; each value also matches its cross-vocabulary spelling (increased also matches upregulated, and vice versa). Object-side only -- sources that write the signed effect on subject_direction instead (e.g. perturbseq's CRISPRi knockdowns) are not matched; use --qualifier subject_direction=... for those.
--tissue
str, repeatable
no
—
Filter to an anatomical context by CURIE (e.g. --tissue UBERON:0002107), repeatable. Sugar for --qualifier anatomical_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet. Also matches only the ontology your CURIE's prefix names: anatomical_context spans MESH (ctd), CL (perturbseq), and BTO/CL/UBERON (signor), so a single --tissue UBERON:... reaches signor's rows for that tissue but not ctd's or perturbseq's -- there is no cross-ontology expansion yet, so a correct CURIE can still return a small fraction of the matching edges with no error.
--species
str, repeatable
no
—
Filter to a species context by CURIE (e.g. --species NCBITaxon:9606), repeatable. Sugar for --qualifier species_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet. This is the organism the EXPERIMENT was run in, recorded on the edge -- NOT the organism of the entities at its ends, which is what the separate --organism/--taxon flag filters (offered by ls and tree, not by scan/match -- check the command's own --help). An edge between human entities that was measured in mouse matches --organism human and --species NCBITaxon:10090 at once, so neither flag substitutes for the other. Edges whose source records no experimental organism carry no species_context and are dropped by this filter.
--cell-line
str, repeatable
no
—
Filter to a cell-line context by CURIE (e.g. --cell-line cellosaurus:CVCL_0004), repeatable. Sugar for --qualifier cell_line_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet.
--expect
str
no
—
Assert which entity the identifier names, e.g. --expect RALGDS. Matched against the resolved node's canonical name and synonyms, case-insensitively; a mismatch fails the command instead of answering for the wrong entity. Use it whenever the identifier came from outside this CLI (memory, a paper, another tool) rather than from search/lookup.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl match
Find edges matching a single-edge pattern; for multi-hop, use path instead.
Constraints
The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.
Arguments
pattern
str
yes
A single-edge pattern, e.g. '<Gene> regulates <Gene>' — category names are case-sensitive and PascalCase (e.g. Gene, Disease, ChemicalEntity); list them with mithrl schema --categories.
Options
--source
str, at most one
no
—
Filter by contributing knowledge source. Case-insensitive. Limited: edges(...) takes a single source, not a list — a second --source is rejected.
--qualifier
str, repeatable
no
—
Filter on an edge qualifier as key=value (e.g. --qualifier object_aspect=phosphorylation), repeatable. The same key repeated ORs its values; distinct keys AND.
--direction
str, repeatable
no
—
Filter to a signed direction of effect (increased/decreased/upregulated/downregulated), repeatable. Sugar for --qualifier object_direction=...; each value also matches its cross-vocabulary spelling (increased also matches upregulated, and vice versa). Object-side only -- sources that write the signed effect on subject_direction instead (e.g. perturbseq's CRISPRi knockdowns) are not matched; use --qualifier subject_direction=... for those.
--tissue
str, repeatable
no
—
Filter to an anatomical context by CURIE (e.g. --tissue UBERON:0002107), repeatable. Sugar for --qualifier anatomical_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet. Also matches only the ontology your CURIE's prefix names: anatomical_context spans MESH (ctd), CL (perturbseq), and BTO/CL/UBERON (signor), so a single --tissue UBERON:... reaches signor's rows for that tissue but not ctd's or perturbseq's -- there is no cross-ontology expansion yet, so a correct CURIE can still return a small fraction of the matching edges with no error.
--species
str, repeatable
no
—
Filter to a species context by CURIE (e.g. --species NCBITaxon:9606), repeatable. Sugar for --qualifier species_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet. This is the organism the EXPERIMENT was run in, recorded on the edge -- NOT the organism of the entities at its ends, which is what the separate --organism/--taxon flag filters (offered by ls and tree, not by scan/match -- check the command's own --help). An edge between human entities that was measured in mouse matches --organism human and --species NCBITaxon:10090 at once, so neither flag substitutes for the other. Edges whose source records no experimental organism carry no species_context and are dropped by this filter.
--cell-line
str, repeatable
no
—
Filter to a cell-line context by CURIE (e.g. --cell-line cellosaurus:CVCL_0004), repeatable. Sugar for --qualifier cell_line_context=...; takes a CURIE only, not a name -- there is no name index for these qualifier values yet.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl path
Shortest path between two entities (up to 5 hops, default 2).
Constraints
A CURIE is accepted as given -- a well-formed identifier for the wrong entity resolves exactly as cleanly as the right one, and returns a complete, credible result for it. Read the
resolved:line this prints to stderr (canonical name, CURIE, category, organism) and confirm it is the entity you meant before using the result; pass--expect <name>to have that checked for you rather than by eye.--typeis checked too in this case (it otherwise only narrows candidates while resolving a bare name, which a CURIE skips entirely) -- a CURIE of the wrong category fails ascategory_mismatchrather than silently ignoring--type. An identifier that is resolved and its node fetched fails asnot_foundwhen the active build holds no node for it, whether or not--expect/--typewas passed -- sono edgesandno path foundare answers about the graph rather than about a name it does not have. Forms that make no per-identifier node lookup (--batch, and--depth 0where offered) are outside that guarantee and can still report an empty result for an identifier the build does not hold.Same symbol, different species: human gene symbols collide with their rodent orthologs (EGFR, TP53, BRCA1, ...), and
--type/--type-a/--type-bcannot separate a collision where every candidate is a Gene.--organism(aka--taxon) is what resolves it -- pass--organism humanwhenever a bare gene symbol is the identifier and the question is about human biology. It narrows the candidates a NAME resolves to; against an already-CURIE identifier it is checked instead, and a CURIE belonging to another species fails astaxon_mismatchrather than answering for the wrong organism. A candidate that reports no organism is never excluded (a disease or pathway has none), so one flag is safe onpath's two endpoints. On a name whose every candidate belongs to another species the command failsnot_foundnaming those species, never an empty result.Structural hops are excluded by default: an intermediate node may not be an organism taxon, a clinical trial or a study, and
in_taxon/chemically_similar_tohops are not walked (a direct one between the two endpoints included). The endpoints themselves are never excluded. Pass --include-structural to walk them; with --predicate, the predicate set you name is what is walked, structural or not.--organism is a single flag covering BOTH endpoints, unlike --type-a/--type-b: a cross-species path is not a question anyone asks, and an endpoint that carries no organism (a disease, a pathway) is never excluded by it -- so
--organism humannarrows the gene endpoint and leaves the other alone.pathtakes two identifiers, so --expect is spelled --expect-from / --expect-to here; each is optional and checked independently.--hops is a maximum, not an exact length: a 2-hop route is returned by --hops 4. Out-of-range values are rejected, never clamped, so a result is always at the depth asked for. Deeper searches are strongly worth pairing with --predicate: without it, a 5-hop route is merely connected rather than mechanistically meaningful.
aandbeach run resolve, then the in-build check, then --expect/--type verification, but the two arguments are never staggered against each other: a failure inaat ANY of those three stages does not stopbfrom being carried through all three too, and both arguments' failures (whichever stage each hit) come back together in one error, not one at a time across repeated calls.Error contract: a failing
a/breportserror.code == "unresolved_arguments"at the top level -- even when only one of the two fails -- with each argument's ownambiguous/not_found/category_mismatch/type_unverified/taxon_mismatch/expect_unverified/entity_mismatchcode nested aterror.errors[i].codeinstead, unlikelookup/members/cat/ls/tree, which report that code aserror.codeitself. A caller parsingpath's stderr JSON for one of those bareerror.codevalues needs to checkerror.errors[].codeinstead.The three output flags have a precedence, and the CLI names on stderr any flag that did not change the output.
--jsonsupersedes both widening flags: the JSON envelope carries every field unconditionally, so--full/--provenancechange nothing alongside it.--fullsupersedes--provenance: it prints every field, the provenance envelope included.--provenancewidens edge-shaped results only -- a node- or membership-shaped result has no provenance envelope to widen, andcat NODE/provenancealready shows the node's own sources and publications without it.--fullwidens any result with a compact view except a membership set, whose compact view is already the complete record. A result with no compact view at all (tree --depth 2,search --count) prints as the JSON envelope whether or not--jsonis passed, so both widening flags are inert there. None of these combinations is an error, and none of them changes which rows come back or what the record contains -- only which fields are printed.
Arguments
a
str
yes
Source entity (name or CURIE).
b
str
yes
Target entity (name or CURIE).
Options
--predicate
str, repeatable
no
—
Restrict every hop to this predicate (repeatable). A path with a hop outside the set is not returned.
--hops
int
no
—
Maximum path length, 1-5 (default 2). Depth 5 needs a build carrying the integer-id artifacts; a build without them refuses the search rather than quietly searching shallower.
--type-a
str
no
—
Filter entity a's candidates by category.
--type-b
str
no
—
Filter entity b's candidates by category.
--include-structural
bool
no
False
Also walk structural hops. By default a path's intermediate nodes exclude organism taxa, clinical trials and studies, and in_taxon / chemically_similar_to hops are not walked: they connect almost everything to everything and carry no mechanism. The two endpoints are never excluded.
--organism, --taxon
str
no
—
Restrict to one species, e.g. --organism human (also --taxon). Accepts human, mouse, rat, zebrafish, fly, worm, yeast, an NCBITaxon CURIE (NCBITaxon:9606), or a bare taxon id (9606). This is the fix for a gene symbol that resolves to several species' orthologs -- --type cannot separate those, since every one of them is a Gene. Entities that carry no organism at all (a disease, a pathway, a chemical) are never filtered out by it. Distinct from --species, which filters on an edge's species_context qualifier -- the organism the experiment was run in, not the organism of the entities the edge connects.
--expect-from
str
no
—
Source endpoint. Assert which entity the identifier names, e.g. --expect RALGDS. Matched against the resolved node's canonical name and synonyms, case-insensitively; a mismatch fails the command instead of answering for the wrong entity. Use it whenever the identifier came from outside this CLI (memory, a paper, another tool) rather than from search/lookup.
--expect-to
str
no
—
Target endpoint. Assert which entity the identifier names, e.g. --expect RALGDS. Matched against the resolved node's canonical name and synonyms, case-insensitively; a mismatch fails the command instead of answering for the wrong entity. Use it whenever the identifier came from outside this CLI (memory, a paper, another tool) rather than from search/lookup.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--full
bool
no
False
Widen compact TSV output to every field (still TSV, not JSON). No effect alongside --json, which already prints every field.
--provenance
bool
no
False
Widen compact TSV output to the full provenance envelope -- knowledgeSources, publications, knowledgeLevel, agentType, publicationsInfo, properties -- instead of the one-line summary shown by default. Edge-shaped results only; ignored by search/lookup/members (path is edge-shaped now -- each hop widens too). No effect alongside --json or --full, both of which already print these fields.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl score
Rank targets along a curated metapath by calibrated DWPC. z ranks; z is not a p-value.
Constraints
A CURIE is accepted as given: a well-formed identifier for the WRONG entity scores exactly as cleanly as the right one. Read the
resolved:line this prints to stderr (canonical name, CURIE, category, organism) and confirm it is the entity you meant before using the ranking. An identifier the active build holds no node for fails asnot_foundrather than returning an empty ranking, sono targetsis an answer about the graph and not about a name it does not have. The source must hold the metapath's starting category -- a compound, for a compound-first metapath -- or nothing is reached.z RANKS; z IS NOT A p-VALUE. Do not convert it to a probability, a significance level, or a false-discovery rate, and do not read z = 2 as any particular tail. The permutation null is strongly right-skewed, so normal-tail arithmetic does not apply to it -- an observed score of exactly 0.0 sits at a median z of -0.57, where a normal null would require -inf. Use z to order candidates against each other; nothing more.
A null z is WITHHELD, never zero and never a low score: it means the pair could not be calibrated at all. Those rows render their reason CODE in the z column (e.g.
withheld:CELL_INSUFFICIENT) rather than a number, a dash or a blank, and their dwpc must not be compared against another row's z. The graph's own sentence for each code is printed under the table and carried in --json aszWithheld.detail.Read targetDegree beside z, always. The top of a z ranking is dominated by TINY-DEGREE targets -- a disease associated with a single gene, where the source happens to bind that gene, scores z around 20. Those are real excursions under the null, not artifacts, but whether they are biologically interesting is a judgement calibration cannot make. No minimum-support floor is applied; the column is how you apply your own.
When no null table applies, the response says so and the ranking falls back to RAW dwpc -- which is degree-confounded (measured rank correlation with target degree +0.567, against the calibrated score's -0.043), so the order is substantially an order on popularity. The command states this outright rather than rendering an uncalibrated table that looks like a calibrated one.
--paths requires --target and --path-limit requires --paths: routes are enumerated for a single pair, and both flags are ignored by the API otherwise. Both are refused rather than silently dropped.
Ranked results have no cursor -- the ranking is computed whole and then trimmed by --limit, so a truncated table is recovered with a bigger --limit, never with
results --page 2.Neither widening flag is offered here, and neither is needed: the compact view already carries every field the API returns for a ranked row, which is the same claim
schemamakes for its own rows. --provenance would be inert regardless -- the provenance envelope belongs to edges, and a ranked row is not one.
Arguments
source
str
yes
Entity to score from (name or CURIE).
Options
--metapath
str
no
COMPOUND_BINDS_GENE_ASSOCIATED_WITH_DISEASE
Which curated mechanism to walk. Metapaths are named, not author-supplied: each has a permutation null table provisioned against the serving build, which is what makes z available at all. Catalogue: COMPOUND_BINDS_GENE_ASSOCIATED_WITH_DISEASE.
--target
str
no
—
Score this one target instead of ranking all of them. A pair reached by no route scores an exact 0.0 -- a measurement, not a failure.
--limit
int
no
—
How many ranked targets to return (server default 100, clamped to 500). The ranking is computed over every reached target and then trimmed.
--paths
bool
no
False
List the concrete routes behind the score. Needs --target.
--path-limit
int
no
—
How many routes --paths lists (server default 20, clamped to 200).
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl schema
List the vocabularies the active build carries — the valid predicates (--rel/--predicate), categories (--type), and knowledge sources (--source) — plus the build pin every result is reproducible against.
Constraints
The three narrowing flags are additive, and passing none of them lists all three vocabularies -- so a value whose vocabulary you don't yet know can be found without picking one first.
Rows are
kind<TAB>value<TAB>version; only a source row carries a version.These are the vocabularies the ACTIVE BUILD carries, which is a subset of what the schema accepts -- a predicate the schema allows but this build has no edges for is absent here rather than listed as something to query.
Predicates and categories are case-sensitive. A value outside these lists is refused as
invalid_inputbefore any query is sent, with a suggestion where one is close enough to name; it is never retried and never reported as an upstream outage.--full/--provenance are not offered here: the compact view already carries every field a vocabulary row has, and there is no provenance envelope to widen.
Options
--predicates
bool
no
False
List only the predicates (the values --rel/--predicate accept).
--categories
bool
no
False
List only the categories (the values --type/--type-a/--type-b and a match pattern accept).
--sources
bool
no
False
List only the contributing knowledge sources, with the version of each.
--json
bool
no
False
Print the full machine-readable JSON envelope instead of compact TSV. Supersedes --full/--provenance -- the envelope already carries every field they widen.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
Workflow triggering
List and trigger the analysis workflows that run behind the API.
mithrl tox-endpoints
List the curated toxicity endpoints a Tox run can be scoped to. Each id is a value for run <tox workflow> --param scope=<id> (comma-separate several; omit scope for all).
Constraints
The list is a committed, version-pinned artifact served whole -- there is nothing to page. The MONDO and GO release pins it was materialized from are reported on stderr (and in --json), because an endpoint's size moves with them.
curie_countcounts DISTINCT CURIES, not genes. An endpoint's gene set is whatever has edges to those CURIEs, so this is a proxy for how broad the endpoint is and must not be read as the size the statistics were computed over.An unknown scope id fails the run rather than being skipped -- asking for an endpoint that does not exist and silently getting a smaller family back is the shape of a typo that survives into a published q-value. The failure names the valid ids.
Options
--json
bool
no
False
Print the full JSON envelope -- each endpoint's description and per-source provenance counts, plus the MONDO/GO release pins -- instead of compact TSV.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl workflows
List available workflows or inspect one workflow's graph, required file inputs, and params.
Constraints
Several presets are near-duplicates within a family, and the shorter name is not always the better analysis. The tox family (
compound-tox-card/compound-tox-profile/toxicity-endpoint-analysis) and the pathway family (pathway-participants/pathway-lookup/canonical-pathway-analysis) each have the same answer:toxicity-endpoint-analysisandcanonical-pathway-analysisare the ones that run a statistical background test; the other two names in each family are listings with no test behind them -- pick the tested preset when you want evidence rather than a ranking, and name the id you ran when you report the result. These two families are not the whole catalog:mithrl workflowsalso listsupstream-regulator-analysis,overrepresentationandregulator-breakdowndirectly, so list it rather than treating this prose as exhaustive.Each param reports
effective-- the value the run uses if you pass nothing -- alongsidedefault, which is the part's own fallback and may differ.effective_sourcesays where it came from:workflowfor a value the workflow pinned,part_defaultfor one it left alone, andworkflow_placeholderfor a BLANK pin -- a visible prompt, not a choice:required: truesays you must supply that one or submit rejects the run. Where several nodes declare the same param with different values,effectiveis null andeffective_by_nodecarries them. Readeffective, notdefault, to know what a run will do.
Options
--id
str
no
—
Workflow ID to inspect in detail.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl run
Trigger an analysis workflow (URA / Pathways / Tox) through the API to the Workflow Engine.
Constraints
mithrl workflowsis the only authority on what exists. A workflow family named in a plan, a paper, or this CLI's own prose is not an id: run the catalog first and pick an id out of it, rather than guessing at a name (an unknown one failsnot_found, listing what is actually available).Several presets are near-duplicates within a family, and the shorter name is not always the better analysis. The tox family (
compound-tox-card/compound-tox-profile/toxicity-endpoint-analysis) and the pathway family (pathway-participants/pathway-lookup/canonical-pathway-analysis) each have the same answer:toxicity-endpoint-analysisandcanonical-pathway-analysisare the ones that run a statistical background test; the other two names in each family are listings with no test behind them -- pick the tested preset when you want evidence rather than a ranking, and name the id you ran when you report the result. These two families are not the whole catalog:mithrl workflowsalso listsupstream-regulator-analysis,overrepresentationandregulator-breakdowndirectly, so list it rather than treating this prose as exhaustive.Blocking by default: if the bounded wait elapses with the run still active, the payload reports
data.poll_exhausted: truewith the run_id anddata.next_command, and the command exits 3 (incomplete) rather than 0.--no-waitreturns the acceptance envelope and exits 0.File inputs are CSV with a header row. The feature table (
omics_csv, andbackground_csvwhere a preset takes one) is read by itsentitycolumn unless you say otherwise: pass--param entity_column=<your column>to use a file you already have, or rename the column toentity.--param effect_column=and--param significance_column=bind the optional effect-size and significance columns the same way. A column that does not exist is refused at submit, naming the file, the column asked for, and the columns the file actually has.Exits 4 (remote failure), not 0, when the run it waited for reached
failedorcancelled. The payload is still printed in full and the server'sfailureblock (code, stage, category, message) is named on stderr.--no-waitis unaffected: an acceptance envelope is that invocation's success.
Arguments
workflow
str
yes
Workflow to trigger: an id from mithrl workflows (e.g. upstream-regulator-analysis) or a custom wf_... id.
Options
--input
str, repeatable
no
—
Bind a workflow FILE input as name=@local-file or name=existing-file_ref (repeatable). Scalar values, including CURIEs, go on --param instead.
--param
str, repeatable
no
—
A workflow parameter as key=value (repeatable). mithrl workflows --id <id> lists every param and which ones are required.
--label
str
no
—
Run label. Reuse the same label to retry idempotently; omit it for a unique default.
--no-wait
bool
no
False
Return the acceptance envelope immediately; reattach with mithrl status <id> --watch.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl upload
Stage a local file for workflow reuse and print its file_ref.
Arguments
file
str
yes
Local file to upload.
Options
--resume
str
no
—
Resume an interrupted upload by upload_id.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl status
Inspect an existing workflow run and optionally watch it to a terminal state.
Constraints
Exits 4 (remote failure), not 0, when the run reached
failedorcancelled. The full run record is still printed, and the server'sfailureblock (code, stage, category, message) is named on stderr.--watchis bounded so the command always terminates. If it elapses with the run still active, the payload reports the run's current state withdata.next_commandto resume watching, and the command exits 3 (incomplete) rather than 0. Without--watcha run that is merely still running exits 0 — a point-in-time read waited for nothing and so cannot be incomplete.A run that is still queued reports how long it has been waiting, and approximately what position it holds, on stderr and in
data.run.queue. The position is approximate — it is derived from queue timestamps — and the queue is shared across all organizations, so a run can wait behind work that is not yours.
Arguments
run_id
str
yes
Workflow run ID.
Options
--watch
bool
no
False
Poll with bounded backoff until terminal or reattach.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl runs
List workflow runs with optional status filtering and page-based pagination.
Options
--status
str
no
—
Filter by lifecycle status.
--page
int
no
1
Page number (1-based).
--per
int
no
50
Runs per page (1-200).
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl cancel
Request cooperative cancellation of an active workflow run.
Arguments
run_id
str
yes
Workflow run ID.
Options
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl rerun
Fork a completed workflow run with the same resolved inputs and configuration.
Arguments
run_id
str
yes
Parent workflow run ID.
Options
--idempotency-key
str
no
—
Reuse a printed key to retry one fork idempotently; omit it to fork a new run.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl retry
Retry a failed retryable workflow run from its recovery boundary.
Arguments
run_id
str
yes
Failed workflow run ID.
Options
--idempotency-key
str
no
—
Reuse a printed key to retry one fork idempotently; omit it to fork a new run.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl run-results
Fetch workflow findings and optionally stream durable artifacts to disk.
Constraints
Exits 4 (remote failure), not 0, when the run reached
failedorcancelled. The results payload is still printed, and the server'sfailureblock (code, stage, category, message) is named on stderr.A run that succeeded with an empty result (
is_empty: true) still exits 0; the emptiness is reported on stderr, and anywarningson the payload are where a cause would be recorded.
Arguments
run_id
str
yes
Workflow run ID.
Options
--download
str
no
—
Directory for direct presigned artifact downloads.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl validate
Dry-run validation of an inline workflow graph without creating a run.
Arguments
graph_file
str
yes
Path to a workflow graph document in JSON or YAML format.
Options
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
Composability layer
Replay, narrow, and serialize a stored result set without recomputing it.
mithrl results
Replay/page/reformat a stored result set without recompute.
Constraints
totalcounts the rows fetched so far, not the size of the result set. It is a high-water mark: paging further into a continuable result (a hub node's neighborhood) fetches more rows, so the same result id reports a largertotalon a later page than on the first.rows_fetchedis the same number under that name, andtruncatedis what says whether rows exist beyond them.columnsechoes the --columns request and is empty when no projection was asked for;body_columnsis what the servedbodyactually carries, in order -- for --format tsv it is the header row.
Arguments
id
str
yes
Result ID to replay.
Options
--page
int
no
1
Page number.
--per
int
no
—
Results per page.
--format
str
no
tsv
Output format: tsv, jsonld, graphml, or cypher.
--columns
str, repeatable
no
—
Columns to include (repeatable).
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl filter
Narrow a result set with a structured predicate (no NL). Filters the stored rows; if the source result was left incomplete (a hub node's later pages), the missing pages are fetched first, with progress on stderr and bounded by --timeout.
Constraints
Exits 3 (incomplete), not 0, when the missing-pages fetch above is cut short by --timeout or its own page limit -- the payload on stdout still carries the real matches found so far, but matches may exist in rows not yet retrieved (see the payload's note). A genuine upstream cap (the source itself ran out of pages) still exits 0.
Arguments
id
str
yes
Result ID to filter.
Options
--where
str
yes
—
A single '<field> <op> <value>' predicate: ==, !=, >, >=, <, <= (dot-path fields like properties.combined_score work). <value> is coerced to int, then float, then left as a string — quote it (e.g. '007') to force a literal string comparison against a numeric-looking value.
--timeout
float
no
—
Seconds to spend fetching the source result's missing pages before answering with what was fetched. Default is sized from the result's row count (about 1.5s per 100-row page, up to a 300s ceiling), falling back to 30s when the size is unknown. Progress is printed to stderr while fetching, and the payload's note says so when this budget is what stopped the fetch. Fetched pages are cached, so a re-run resumes rather than starting over.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
mithrl export
Serialize a result set/subgraph, escaped per format.
Constraints
Writes the serialized document to stdout, so
mithrl export <id> --format tsv > rows.tsvproduces a file a TSV reader can open. --json prints the JSON envelope instead, with the document insidebodyas a JSON string.Exits 3 (incomplete), not 0, when the missing-pages fetch above is cut short by --timeout or its own page limit -- the document on stdout is still a valid prefix of the result (--json's
notesays how to resume). A genuine upstream cap (the source itself ran out of pages) still exits 0.
Arguments
id
str
yes
Result ID to export.
Options
--format
str
yes
—
tsv, jsonld, graphml, or cypher.
--timeout
float
no
—
Seconds to spend fetching the source result's missing pages before answering with what was fetched. Default is sized from the result's row count (about 1.5s per 100-row page, up to a 300s ceiling), falling back to 30s when the size is unknown. Progress is printed to stderr while fetching, and the payload's note says so when this budget is what stopped the fetch. Fetched pages are cached, so a re-run resumes rather than starting over.
--json
bool
no
False
Print the JSON envelope (result_id, format, truncated, note) with the serialized document inside body, instead of writing the document itself to stdout.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
Feedback
Tell us how mithrl is working for you.
mithrl feedback
Send us your feedback on mithrl, optionally with a 0-3 rating.
Constraints
Run with no arguments at all to be prompted for both fields; give any argument and the message becomes required.
Message is capped at 4000 characters.
Arguments
message
str
no
Your feedback, as a quoted string. Required unless you run the command with no arguments at all, which prompts for it instead. Max 4000 characters.
Options
-r, --rating
int
no
—
How you'd rate mithrl: 0-Poor, 1-Fine, 2-Good, 3-Great. Optional everywhere.
--debug
bool
no
False
Print raw request/response headers and payloads to stderr (secrets redacted).
Examples
Last updated
Was this helpful?