Extend ChatCLI with custom plugins. Create, install, and manage executables that add new commands.
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.
Tool plugin or provider plugin? This page covers tool plugins: commands the model calls during a conversation. To add a whole LLM provider — a corporate gateway or an internal SDK that ChatCLI talks to instead of a built-in vendor — see Provider Plugins.
ChatCLI will clone, compile (if it’s Go), and install the executable in ~/.chatcli/plugins/, signed with this machine’s local key so it loads with signature enforcement on.Or install a prebuilt, signed binary — from disk or from a release URL:
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.
Executable — The plugin must be an executable file (any language)
Location — Placed in ~/.chatcli/plugins/
Command name — The file name becomes the command. E.g., file kind = command @kind
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"}
Schema (--schema) — Optional. Describes the accepted parameters:
# 1. Compilego build -o hello ./hello/main.go# 2. Make it executablechmod +x hello# 3. Create the plugins directory (if it doesn't exist)mkdir -p ~/.chatcli/plugins/# 4. Move the executablemv hello ~/.chatcli/plugins/# 5. Use in ChatCLI/agent Hello, my name is John
Plugins can expose capabilities through optional Go interfaces. Legacy plugins that don’t implement them keep working unchanged — every interface is fail-closed (conservative default). When implemented, the plugin participates in orchestrator optimizations:
Interface
Method
Purpose
ReadOnlyAware
IsReadOnly(args []string) bool
Enables the capability security gate (auto-allow) and participation in parallel batches
ConcurrencySafeAware
IsConcurrencySafe(args []string) bool
Signals that multiple calls can run in parallel
DescriberWithInput
DescribeCall(args []string) string
Dynamic spinner label (“Reading: main.go” instead of “RUNNING: @read”)
A plugin runs only when it is signed by a key this machine trusts: an Ed25519 signature over the binary’s SHA-256, in a detached <plugin>.sig next to it. The publisher’s public key can travel with the plugin as <plugin>.pub, but a bundled key is never trusted on its own — anyone can sign a binary with their own key and ship that key along, so trusting it automatically would make the signature prove nothing. A key becomes trusted through a decision made outside the bundle, in one of three ways:
Trust on first use
The first install from a publisher shows the key’s fingerprint and asks once. The key is trusted and pinned to that plugin: updates install silently, a different key is refused.
Managed keys
An administrator places the publisher’s key next to managed.env. Every user of the machine trusts it, with nothing to copy.
Built from source
/plugin install <git-url> builds on your machine after you confirm, and signs the result with this machine’s own key.
Compare the fingerprint ChatCLI shows with the one the publisher announces — on the release page or the internal portal — before you trust it. That comparison is what makes trust on first use safe.
chatcli plugin keygen --output ~/acme-signing# plugin-signing.key (0600, keep it secret) and plugin-signing.pub,# plus the fingerprint to announce: SHA256:…
Put the publisher’s .pub in the managed trusted-keys directory, next to managed.env:
OS
Directory
macOS, Linux
/etc/chatcli/trusted-keys/
Windows
%ProgramData%\chatcli\trusted-keys\
Every user of the machine then trusts that publisher, including users who never created a trusted-keys directory of their own. The directory is owned by the administrator, so a user cannot remove the key.
/plugin install <git-url> clones and builds the plugin on your machine after you confirm the install. The resulting binary is signed with a local machine key — created in ~/.chatcli/local-signing/ on first use and trusted as local-machine — so it loads with signature enforcement on, with no keygen or trust step.
The plugins directory uses 0o700 permissions (owner-only read, write, and execute). ChatCLI checks permissions on startup and warns if they are more permissive.