meroctl CLI Reference
meroctl is the operator CLI. It connects to a running merod node over its
RPC server and manages applications, namespaces, groups, contexts, blobs, and
method calls.
Global arguments
Section titled “Global arguments”| Flag | Type / values | Notes |
|---|---|---|
--home <PATH> | path | Directory for config and data. Env: CALIMERO_HOME. |
--node <ALIAS> | string | Use a pre-configured node alias. Conflicts with --api. |
--api <URL> | URL | API endpoint URL of the node to target. |
--output-format <FORMAT> | enum | Output format (e.g. JSON) — used by commands such as network status. |
When neither --node nor --api is given, meroctl uses the active node (set
with node use), falling back to http://127.0.0.1:2528.
Aliases
Section titled “Aliases”Almost every command accepts an alias wherever it accepts an id. An alias is
a human-readable name (max 50 characters) that the node resolves server-side to
a ContextId, an ApplicationId, or a member PublicKey. Aliases live on the
node, not in the CLI: they are created, looked up, and deleted through the
admin API alias endpoints, so
every client talking to the same node sees the same aliases.
Scoping is not uniform across the three target types:
| Alias target | Scope | Created with |
|---|---|---|
ContextId | Node-global | context alias add, or context create --name |
ApplicationId | Node-global | admin API alias/create/application |
PublicKey (identity) | Per context | context identity alias add (scoped to one context) |
Context and application aliases are unique across the whole node; an identity alias only has meaning within the context it was created in, so the same name can resolve to different keys in different contexts.
A reserved default alias exists for both contexts and identities. Commands
that take --context (or an executor identity) fall back to default when the
flag is omitted, and context use <CONTEXT> / context identity use <IDENTITY>
just point the default alias at a chosen target. The call --substitute
flag is a related but distinct feature: it resolves a comma-separated list of
identity aliases and templates them into the request payload wherever you
write {alias} (see call).
Command groups
Section titled “Command groups”| Group | Purpose |
|---|---|
app | Manage applications (install, list, versions, watch). |
context | Manage contexts, identities, aliases, and sync. |
group | Manage groups: members, contexts, metadata, upgrades, settings. |
namespace | Manage namespaces (root groups / application instances). Alias ns. |
blob | Upload, download, inspect, and delete blobs. |
call | Call a method on a context (mutation or view). |
dev | Developer workflow: build, install, create context, watch. |
network | Inspect libp2p networking state. |
peers | Return the number of connected peers. |
tee | TEE fleet-node commands. |
node | Manage node connections used by meroctl (local config). |
| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
get <APP_ID> | Fetch application details. | APP_ID |
install | Install an application. | --path/-p, --url/-u, --metadata/-m, --hash, --watch/-w, --package, --version |
list (ls) | List installed applications. | — |
uninstall <APP_ID> | Uninstall an application. | APP_ID |
versions <APP_ID> | List locally installed versions of an app. | APP_ID |
watch | Watch a WASM file and update all contexts using the app. | --path/-p, --metadata, --current-app-id, --package, --version |
list-packages | List all packages. | — |
list-versions <package> | List registry versions of a package. | package |
get-latest-version <package> | Get the latest version of a package. | package |
meroctl --node node1 app install --package com.example.myapp --version 1.0.0 --path ./my-app.wasmmeroctl --node node1 app ls--path and --url are mutually exclusive; --version defaults to 0.0.0.
context
Section titled “context”| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
list (ls) | List all contexts. | — |
create | Create a new context. | --application-id/-a, --group-id (required), --params/-p, --watch/-w <path>, --seed/-s, --as (identity alias), --name (context alias), --service, --identity-secret, --group-name, positional metadata (requires --watch) |
get <CONTEXT> | Fetch context details: info, client-keys, or storage. | CONTEXT, subcommand |
delete (del) <CONTEXT> | Delete a context. | CONTEXT, --requester |
update | Update the application in a context. | --context/-c, --application-id/-a, --path, --metadata, --watch/-w, --as (executor) |
watch (ws) | Stream context events, optionally run a command. | --context, -x/--exec, -n/--count |
sync | Explicitly request a sync. | --context/-c, --all |
invite-specialized-node | Invite a specialized (e.g. read-only TEE) node. | --context, --inviter |
identity | Manage context identities (see below). | subcommand |
alias | Manage context aliases: add, remove, get, list. | subcommand |
use <CONTEXT> | Set the default context. | CONTEXT, --force |
context identity
Section titled “context identity”| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
list (ls) | List identities in a context. | --context, --owned |
generate (new) | Generate a new identity keypair. | — |
use <IDENTITY> | Set the default identity for a context. | IDENTITY, --context, --force |
alias | Manage identity aliases. | subcommand |
grant | Removed. Parses but errors, pointing you to group members set-caps. | identity, capability, --context, --as |
revoke | Removed. Parses but errors, pointing you to group members set-caps. | identity, capability, --context, --as |
meroctl --node node1 context create --application-id <app_id> --group-id <group_id>meroctl --node node1 group members set-caps <group_id> <identity> --can-create-context| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
get <GROUP_ID> | Get information about a group. | GROUP_ID |
delete (del) <GROUP_ID> | Delete a group. | GROUP_ID, --requester |
update <GROUP_ID> | Update group settings. | GROUP_ID, --upgrade-policy, --requester |
members | Manage group members (see below). | subcommand |
contexts | List (list/ls) or detach contexts in a group. | subcommand |
metadata | Show / update a group’s metadata record. | subcommand |
member-metadata | Show / update a member’s metadata record. | subcommand |
context-metadata | Show / update a registered context’s metadata. | subcommand |
reparent <GROUP_ID> <NEW_PARENT_ID> | Atomically move a group to a new parent. | GROUP_ID, NEW_PARENT_ID, --requester |
subgroups <GROUP_ID> | List direct subgroups of a group. | GROUP_ID |
signing-key | Manage signing keys: register. | subcommand |
upgrade | trigger, status, or retry a group upgrade. | subcommand |
sync <GROUP_ID> | Sync a group from local state. | GROUP_ID, --requester |
join-context <CONTEXT_ID> | Join a context via group membership. | CONTEXT_ID |
leave-context <CONTEXT_ID> | Locally opt out of a context (no DAG op). | CONTEXT_ID |
leave <GROUP_ID> | Voluntarily leave a group (publishes MemberLeft). | GROUP_ID |
settings | Manage group-level default settings (see below). | subcommand |
group members
Section titled “group members”| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
list (ls) <GROUP_ID> | List all members of a group. | GROUP_ID |
add <GROUP_ID> <IDENTITY> | Add a member to a group. | --role, --requester |
remove <GROUP_ID> <IDENTITY...> | Remove members from a group. | identities, --requester |
set-role <GROUP_ID> <IDENTITY> <ROLE> | Update a member’s role. | --requester |
set-capabilities (set-caps) | Set capabilities for a member (admin-only). | GROUP_ID, IDENTITY, --can-* flags |
get-capabilities (get-caps) | Get a member’s capabilities. | GROUP_ID, IDENTITY |
check-access | Check if an identity can join a context. | GROUP_ID, identity |
group settings
Section titled “group settings”| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
get <GROUP_ID> | Get current default settings. | GROUP_ID |
set-default-capabilities (set-default-caps) | Set default capabilities for new members. | GROUP_ID, --can-* flags, --requester |
set-subgroup-visibility (set-subgroup-vis) | Set subgroup visibility (open/restricted). | GROUP_ID, --mode, --requester |
meroctl --node node1 group members list <group_id>meroctl --node node1 group reparent <group_id> <new_parent_id>meroctl --node node1 group signing-key register <group_id> <hex_signing_key>namespace
Section titled “namespace”Alias: ns. Namespaces are root groups (application instances).
| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
create | Create a new namespace. | --application-id, --upgrade-policy, --name, --app-key |
get <NAMESPACE_ID> | Get details about a namespace. | NAMESPACE_ID |
delete (del) <NAMESPACE_ID> | Delete a namespace. | NAMESPACE_ID, --requester |
invite <NAMESPACE_ID> | Create an invitation for a namespace. | NAMESPACE_ID, --requester, --expiration-timestamp, --recursive |
join <NAMESPACE_ID> <INVITATION> | Join a namespace using an invitation. | NAMESPACE_ID, invitation JSON |
leave <NAMESPACE_ID> | Leave a namespace (cascades through descendants). | NAMESPACE_ID |
groups <NAMESPACE_ID> | List direct groups under a namespace. | NAMESPACE_ID |
create-group <NAMESPACE_ID> | Create a child group in a namespace. | NAMESPACE_ID, --alias |
list (ls) | List all namespaces. | — |
identity (id) <NAMESPACE_ID> | Get this node’s identity for a namespace. | NAMESPACE_ID |
meroctl --node node1 namespace create --application-id <app_id>meroctl --node node2 namespace join <namespace_id> '<invitation_json>'| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
list (ls) | List all blobs. | — |
upload | Upload a blob from a file. | --file, --context-id |
download | Download a blob to a file. | --blob-id, --output, --context-id |
info | Get information about a blob. | --blob-id |
delete (rm) | Delete a blob by its ID. | --blob-id |
meroctl --node node1 blob upload --file /path/to/filemeroctl --node node1 blob download --blob-id <blob_id> --output /path/to/outputCall a method on a context. Whether a call mutates state or runs as a read-only
view is determined by the method’s own declaration (#[app::view]), not by a
CLI flag; the call executes under the context’s default identity.
| Arg / flag | Type / values | Default | Purpose |
|---|---|---|---|
<METHOD> | string | — | Method to call (omit with --interactive). |
--context/-c <CONTEXT> | context alias/id | default | Context to call the method on. |
--args <JSON> | JSON | {} | JSON arguments to pass to the method. |
--substitute <ALIAS> | comma-separated aliases | — | Aliases to substitute into the payload (reference them as {alias}). |
--id <ID> | string | — | JSON-RPC call id. |
--interactive/-i | bool | false | Open a persistent WebSocket shell and run many calls. |
--timeout <SECONDS> | u64 | 120 | Per-call timeout in the interactive shell (0 disables). |
meroctl --node <NODE> call <METHOD> --context <CONTEXT_ID> --args '<ARGS_JSON>'meroctl --node <NODE> call -i --context <CONTEXT_ID>| Subcommand | Purpose | Key args |
|---|---|---|
start <path> | Build, install, create/reuse a context, optionally watch. | --group-id (required), --watch/-w, --new, --params/-p, --seed/-s, --no-build, --metadata |
<path> may be a .wasm, a .mpk bundle, or a project directory with a
Cargo.toml (which is built with cargo build --target wasm32-unknown-unknown --release).
meroctl --node node1 dev start ./my-app --group-id <group_id> --watchnetwork
Section titled “network”| Subcommand | Purpose |
|---|---|
status | Dump swarm connectivity: listen/external addresses, relay reservations, rendezvous registrations, DCUtR upgrades, AutoNAT. |
meroctl --node node1 network statusmeroctl --output-format json --node node1 network statusNo subcommand — returns the number of connected peers.
meroctl --node node1 peers| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
fleet-join <GROUP_ID> | Announce this node as a TEE fleet member and auto-join contexts in the group once admitted. | GROUP_ID |
meroctl --node node1 tee fleet-join <GROUP_ID>node (connection management)
Section titled “node (connection management)”These commands manage meroctl’s local connection config — they do not call
a node. A node may be a local home directory or a remote URL.
| Subcommand (aliases) | Purpose | Key args |
|---|---|---|
add (connect) <NAME> <LOCATION> | Add or connect to a node. | LOCATION (path or URL), --access-token, --refresh-token |
remove (rm, disconnect) <NAME> | Remove a node connection. | NAME |
use <NAME> | Set a node as active (default for commands). | NAME |
list (ls) | List all configured nodes. | — |
identity (id) | Display the node’s peer ID (local nodes only). | — |
meroctl node add node1 /path/to/homemeroctl node add node3 http://public.node.commeroctl node use node1meroctl node lsFor a remote node that needs authentication, login starts automatically; pass
--access-token (and optionally --refresh-token) to skip it with explicit
JWTs.
meroctl’s own config (nodes.toml)
Section titled “meroctl’s own config (nodes.toml)”The node commands above read and write a single client-side config file at
~/.config/calimero/meroctl/nodes.toml (under your platform config dir). This
is meroctl’s own state — it is never sent to a node. It records:
- Each configured node connection under its connection name, as either a
local node (a
pathto a node home) or a remote node (aurl). active_node— the connection used when neither--nodenor--apiis given.- Per-node JWT access and refresh tokens, saved here after a login so subsequent commands reuse them.
Because it holds bearer tokens, the file is written with owner-only permissions
(0600) and re-written atomically with those permissions on every update. Treat
it as secret material:
active_node = "node1"
[nodes.node1]path = "/home/alice/.calimero"
[nodes.node1.jwt_tokens]access_token = "<jwt>"refresh_token = "<jwt>"
[nodes.prod]url = "https://node.example.com/"End-to-end session
Section titled “End-to-end session”A complete run from an installed WASM module to reading back state. Each command
below adds --output-format json so the ids you need to copy forward are
machine-readable; drop it to get the default human-readable table.
-
Install the application. The node returns an
applicationId:Terminal window meroctl --node node1 app install \--path ./kv_store.wasm \--package com.example.kvstore \--version 0.1.0 \--output-format json{"data":{"applicationId":"<app-id>"}} -
Create a namespace bound to that application id. A namespace is a root group; its id is the
--group-ida context attaches to:Terminal window meroctl --node node1 namespace create --application-id <app-id> \--output-format json{"data":{"namespaceId":"<namespace-id>"}} -
Create a context from the application id and the namespace id, giving it a memorable alias with
--name:Terminal window meroctl --node node1 context create \--application-id <app-id> \--group-id <namespace-id> \--name my-kv \--output-format json{"data":{"contextId":"<context-id>","memberPublicKey":"<public-key>"}} -
Call a mutating method. Whether a call mutates or only reads is decided by the method’s own
#[app::view]declaration, not a CLI flag —sethere writes a key. Refer to the context by its alias:Terminal window meroctl --node node1 call set \--context my-kv \--args '{"key": "hello", "value": "world"}' \--output-format jsonsetreturns(), so the result isnull:{"jsonrpc":"2.0","id":null,"result":{"output":null}} -
Read it back with a view method.
getis declared#[app::view], so the samecallcommand runs it read-only:Terminal window meroctl --node node1 call get \--context my-kv \--args '{"key": "hello"}' \--output-format json{"jsonrpc":"2.0","id":null,"result":{"output":"world"}}
The value you stored comes back under result.output.