Skip to main content
ChatCLI supports a plugin system to extend its functionality. A plugin is an executable that follows a specific contract, allowing ChatCLI to discover, execute, and interact with it securely. This lets you create custom commands (such as @kind, @deploy) that can orchestrate tools, interact with APIs, or perform any logic you can program.

For Users: Managing Plugins

List installed plugins

/plugin list
Shows all available plugin commands, including [builtin] plugins (such as @coder) and [remote] plugins (from connected servers).

Install a plugin

Install directly from a Git repository:
/plugin install https://github.com/usuario/meu-plugin-chatcli.git
ChatCLI will clone, compile (if it’s Go), and install the executable in ~/.chatcli/plugins/.
Security: Installing a plugin involves downloading and executing third-party code. Only install plugins from sources you trust.

View plugin details

/plugin show <plugin-name>

Uninstall a plugin

/plugin uninstall <plugin-name>

Reload plugins

ChatCLI automatically monitors ~/.chatcli/plugins/ and reloads when it detects changes (creation, removal, modification). A 500ms debounce prevents multiple reloads. To force a manual reload:
/plugin reload
Develop plugins iteratively: edit the code, recompile, send it to the plugins directory — ChatCLI will detect the change automatically.

For Developers: Creating a Plugin

The plugin contract

  1. Executable — The plugin must be an executable file (any language)
  2. Location — Placed in ~/.chatcli/plugins/
  3. Command name — The file name becomes the command. E.g., file kind = command @kind
  4. Metadata (--metadata) — Required. The executable must respond to this flag with JSON:
{
  "name": "@meu-comando",
  "description": "A brief description of what the plugin does.",
  "usage": "@meu-comando <subcommand> [--flag value]",
  "version": "1.0.0"
}
  1. Schema (--schema) — Optional. Describes the accepted parameters:
{
  "parameters": [
    {
      "name": "cluster-name",
      "type": "string",
      "required": true,
      "description": "Kubernetes cluster name"
    }
  ]
}
  1. Communication (stdout vs stderr):
    • stdout — Only the final result (returned to ChatCLI/AI)
    • stderr — Progress logs, status, and warnings (displayed in real time to the user)

Example: “Hello World” Plugin in Go

package main

import (
    "encoding/json"
    "flag"
    "fmt"
    "os"
    "time"
)

type Metadata struct {
    Name        string `json:"name"`
    Description string `json:"description"`
    Usage       string `json:"usage"`
    Version     string `json:"version"`
}

// logf sends progress messages to the user (via stderr).
func logf(format string, v ...interface{}) {
    fmt.Fprintf(os.Stderr, format, v...)
}

func main() {
    metadataFlag := flag.Bool("metadata", false, "Exibe os metadados do plugin")
    schemaFlag := flag.Bool("schema", false, "Exibe o schema de parâmetros")
    flag.Parse()

    if *metadataFlag {
        meta := Metadata{
            Name:        "@hello",
            Description: "Plugin de exemplo que demonstra o fluxo stdout/stderr.",
            Usage:       "@hello [seu-nome]",
            Version:     "1.0.0",
        }
        jsonMeta, _ := json.Marshal(meta)
        fmt.Println(string(jsonMeta))
        return
    }

    if *schemaFlag {
        schema := map[string]interface{}{
            "parameters": []map[string]interface{}{
                {
                    "name":        "nome",
                    "type":        "string",
                    "required":    false,
                    "description": "Nome da pessoa a ser cumprimentada",
                    "default":     "Mundo",
                },
            },
        }
        jsonSchema, _ := json.Marshal(schema)
        fmt.Println(string(jsonSchema))
        return
    }

    // Lógica principal
    logf("Plugin 'hello' iniciado!\n")
    time.Sleep(2 * time.Second)
    logf("   - Realizando uma tarefa demorada...\n")
    time.Sleep(2 * time.Second)

    name := "Mundo"
    if len(flag.Args()) > 0 {
        name = flag.Args()[0]
    }

    logf("Tarefa concluída!\n")

    // Resultado final vai para stdout
    fmt.Printf("Olá, %s! A hora agora é %s.", name, time.Now().Format(time.RFC1123))
}

Compilation and installation

# 1. Compile
go build -o hello ./hello/main.go

# 2. Make it executable
chmod +x hello

# 3. Create the plugins directory (if it doesn't exist)
mkdir -p ~/.chatcli/plugins/

# 4. Move the executable
mv hello ~/.chatcli/plugins/

# 5. Use in ChatCLI
/agent Hello, my name is John

Remote Plugins

When connecting to a server via chatcli connect, server plugins are discovered automatically:
  • They appear in /plugin list with the [remote] tag
  • They are executed on the server (not downloaded locally by default)
  • Local and remote plugins coexist without conflict