For a conceptual overview of how CLI, gRPC, and REST fit together in a Cosmos SDK app, see CLI, gRPC & REST.
Overview
autocli generates CLI commands and flags for each method defined in your gRPC service. By default, it generates a command for each gRPC service method. The commands are named based on the name of the service method.
For example, given the following protobuf definition for a service:
autocli package will generate a command named my-method for the MyMethod method. The command will have flags for each field in the MyRequest message.
It is possible to customize the generation of transactions and queries by defining options for each service.
Application Wiring
Here are the steps to use AutoCLI:- Ensure your app’s modules implement the
appmodule.AppModuleinterface. - (optional) Configure how
autoclibehaves during command generation, by implementing thefunc (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptionsmethod on the module. - Call
app.AutoCliOpts()to get anautocli.AppOptionspopulated from the module manager, then setClientCtxon it to wire in the keyring. - Call
EnhanceRootCommand()to add the generated CLI commands to your root command.
Keyring
AutoCLI resolves key names and signs transactions using the keyring fromclient.Context. At runtime, it reads the keyring from the command’s live context (set by SetCmdClientContextHandler in PersistentPreRunE — see Root Command Setup) and adapts it to the cosmossdk.io/client/v2/autocli/keyring interface via keyring.NewAutoCLIKeyring internally.
If no keyring is provided, AutoCLI-generated commands can still query the chain but cannot sign transactions.
Signing
autocli supports signing transactions with the keyring.
The cosmos.msg.v1.signer protobuf annotation defines the signer field of the message.
This field is automatically filled when using the --from flag or defining the signer as a positional argument.
Module wiring & Customization
TheAutoCLIOptions() method on your module allows to specify custom commands, sub-commands or flags for each service, as it was a cobra.Command instance, within the RpcCommandOptions struct. Defining such options will customize the behavior of the autocli command generation, which by default generates a command for each method in your gRPC service.
Specifying Subcommands
By default,autocli generates a command for each method in your gRPC service. However, you can specify subcommands to group related commands together. To specify subcommands, use the autocliv1.ServiceCommandDescriptor struct.
For a real-world example, see the gov module’s autocli.go in the Cosmos SDK. It demonstrates ServiceCommandDescriptor with RpcCommandOptions, PositionalArgs, SubCommands, EnhanceCustomCommand, and GovProposal all in one file.
Positional Arguments
By defaultautocli generates a flag for each field in your protobuf message. However, you can choose to use positional arguments instead of flags for certain fields.
To add positional arguments to a command, use the autocliv1.PositionalArgDescriptor struct, as seen in the example below. Specify the ProtoField parameter, which is the name of the protobuf field that should be used as the positional argument. In addition, if the parameter is a variable-length argument, you can specify the Varargs parameter as true. This can only be applied to the last positional parameter, and the ProtoField must be a repeated field.
For a real-world example, see the auth module’s autocli.go in the Cosmos SDK. It shows positional args wired for every query method, with address as a positional argument on the Account method.
After wiring positional args, the command can be used as follows, instead of having to specify the --address flag:
Flattened Fields in Positional Arguments
AutoCLI also supports flattening nested message fields as positional arguments. This means you can access nested fields using dot notation in theProtoField parameter. This is particularly useful when you want to directly set nested
message fields as positional arguments.
For example, if you have a nested message structure like this:
Customizing Flag Names
By default,autocli generates flag names based on the names of the fields in your protobuf message. However, you can customize the flag names by providing a FlagOptions. This parameter allows you to specify custom names for flags based on the names of the message fields.
For example, if you have a message with the fields test and test1, you can use the following naming options to customize the flags:
Combining AutoCLI with Other Commands Within A Module
AutoCLI can be used alongside other commands within a module. For example, thegov module uses AutoCLI for its query commands while also keeping hand-written tx commands for submit-proposal, weighted-vote, and similar.
Set EnhanceCustomCommand: true on each ServiceCommandDescriptor where you want AutoCLI to add generated commands alongside existing ones:
EnhanceCustomCommand is not set to true, AutoCLI skips command generation for any service that already has commands registered via GetTxCmd() or GetQueryCmd().
Skip a command
AutoCLI checks thecosmos_proto.method_added_in protobuf annotation and skips commands that were introduced in a newer SDK version than the one currently running.
Additionally, a command can be manually skipped using the autocliv1.RpcCommandOptions:
Use AutoCLI for non module commands
It is possible to useAutoCLI for non-module commands. The pattern is to add the options directly to autoCliOpts.ModuleOptions after calling AutoCliOpts():
AutoCliOpts() only picks up modules registered with the module manager — non-module commands always need to be added to ModuleOptions manually, as the example chain does with nodeservice.NewNodeCommands().
For a more complete example of this pattern, see client/grpc/cmtservice/autocli.go and client/grpc/node/autocli.go in the Cosmos SDK.
Root Command Setup
For AutoCLI-generated commands (and hand-written commands) to work correctly — signing transactions, querying the chain, reading configuration — the root command must set up theclient.Context and server.Context in a PersistentPreRunE function. This runs before every subcommand and makes both contexts available to all child commands. See simapp/simd/cmd/root.go for a complete example.
The two key calls inside PersistentPreRun are:
SetCmdClientContextHandlerreads persistent flags viaReadPersistentCommandFlags, creates aclient.Context, and sets it on the command context. This is what AutoCLI and hand-written commands use to sign transactions and connect to a node.InterceptConfigsPreRunHandlercreates theserver.Context, loadsapp.tomlandconfig.tomlfrom the node home directory, and binds them to the server context’s viper instance. This is what makes application configuration available at startup.
Custom logger
By default,InterceptConfigsPreRunHandler sets the default SDK logger. To use a custom logger, use InterceptConfigsAndCreateContext instead and set the logger manually:
Environment Variables
Every CLI flag is automatically bound to an environment variable. The variable name is the app’sbasename in uppercase followed by the flag name, with - replaced by _. For example, --node for an app with basename GAIA binds to GAIA_NODE.
This lets you pre-configure common flags instead of passing them on every command:
Hand-Written Commands
AutoCLI covers the standard case: one protobuf RPC method maps to one CLI command. For commands that don’t fit that model, you can write Cobra commands manually and combine them with AutoCLI usingEnhanceCustomCommand: true.
Common reasons to write a command manually:
- Complex argument parsing — multiple positional args that require custom validation or coin parsing before the message is built
- Commands that span multiple RPC calls — e.g., building a transaction from inputs that require a preceding query
- Non-standard UX — interactive prompts, offline signing flows, or commands that generate output rather than broadcast
Pattern
A manual transaction command usesclient.GetClientTxContext to retrieve the signing context, constructs a message, and passes it to tx.GenerateOrBroadcastTxCLI:
client.GetClientTxContext(cmd)retrieves the client context (signer, node connection, codec)flags.AddTxFlagsToCmd(cmd)adds standard transaction flags (--from,--fees,--gas, etc.)tx.GenerateOrBroadcastTxCLIhandles both--generate-only(offline) and live broadcast modes