diff --git a/README.md b/README.md
index 199d215..8ec40ed 100644
--- a/README.md
+++ b/README.md
@@ -550,6 +550,8 @@ index - manage indicies
create - create a new index template
update - update a new index template
delete - delete an index template
+license - manage cluster license
+ show - show details about the cluster license
node - manage nodes
list - list nodes
show - show details about a node
@@ -571,7 +573,7 @@ task - manage tasks
version - show esctl version information
debug - developer only
help-jsonpath - show jsonpath help
-help-command-overview - show overview of all available commands
+help-usage - show overview of all available commands
```
# Development
diff --git a/cmd/license.go b/cmd/license.go
new file mode 100644
index 0000000..faea608
--- /dev/null
+++ b/cmd/license.go
@@ -0,0 +1,49 @@
+/*
+Copyright © 2026 Thomas von Dein
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+package cmd
+
+import (
+ "context"
+
+ "codeberg.org/scip/esctl/pkg/cfg"
+ "codeberg.org/scip/esctl/pkg/es"
+
+ "github.com/urfave/cli/v3"
+)
+
+func License(conf *cfg.Config) *cli.Command {
+ return &cli.Command{
+ Name: "license",
+ Usage: "manage cluster license",
+
+ Commands: []*cli.Command{
+ LicenseShow(conf),
+ },
+ }
+}
+
+func LicenseShow(conf *cfg.Config) *cli.Command {
+ return &cli.Command{
+ Name: "show",
+ Aliases: []string{"sh"},
+ Usage: "show details about the cluster license",
+
+ Action: func(ctx context.Context, cmd *cli.Command) error {
+ return es.LicenseShow(conf)
+ },
+ }
+}
diff --git a/cmd/root.go b/cmd/root.go
index d250741..4f95c8c 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -108,6 +108,7 @@ func Main() int {
Doc(conf),
Ilm(conf),
Index(conf),
+ License(conf),
Node(conf),
Roles(conf),
Search(conf),
diff --git a/pkg/es/license.go b/pkg/es/license.go
new file mode 100644
index 0000000..e1987ff
--- /dev/null
+++ b/pkg/es/license.go
@@ -0,0 +1,59 @@
+/*
+Copyright © 2026 Thomas von Dein
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+package es
+
+import (
+ "context"
+ "fmt"
+ "log/slog"
+
+ "codeberg.org/scip/esctl/pkg/cfg"
+ "codeberg.org/scip/esctl/pkg/printer"
+)
+
+func LicenseShow(conf *cfg.Config) error {
+ res, err := conf.DefaultCluster.ES().License.Get().
+ Do(context.Background())
+ if err != nil {
+ return fmt.Errorf("failed to get license: %s", esErrorString(err))
+ }
+
+ slog.Debug("license show", "license", res)
+
+ table := printer.NewTableEmpty(conf).WithHeaders("license setting", "value")
+
+ lic := res.License
+
+ var maxnodes = "infinite"
+
+ if lic.MaxNodes != nil {
+ maxnodes = fmt.Sprintf("%d", *lic.MaxNodes)
+ }
+
+ table.Entries = [][]string{
+ {"UID", lic.Uid},
+ {"Issued to", lic.IssuedTo},
+ {"Expires", lic.ExpiryDate.(string)},
+ {"Issued", lic.IssueDate.(string)},
+ {"Max nodes", maxnodes},
+ {"Max resource units", fmt.Sprintf("%d", *lic.MaxResourceUnits)},
+ {"Type", lic.Type.Name},
+ {"Status", lic.Status.Name},
+ }
+
+ return table.Print()
+}
diff --git a/pkg/printer/table.go b/pkg/printer/table.go
index 977a2f4..363c97f 100644
--- a/pkg/printer/table.go
+++ b/pkg/printer/table.go
@@ -53,6 +53,24 @@ func NewTable(conf *cfg.Config, columns, rows int) *Table {
return &table
}
+func NewTableEmpty(conf *cfg.Config) *Table {
+ table := Table{Mode: conf.Output, maxwidth: cfg.GetTermWidth()}
+ table.alignInts = conf.AlignInts
+ return &table
+}
+
+func (table *Table) WithHeaders(headers ...string) *Table {
+ count := len(headers)
+
+ table.Entries = [][]string{}
+ table.lenHeaders = make([]int, count)
+ table.Headers = make([]string, count)
+
+ table.Addheaders(headers...)
+
+ return table
+}
+
func (data *Table) Print() error {
switch data.Mode {
case "markdown", "md":