# Argo CD Plugin Development and Integration: CLI and Config-Management Plugin Guide

> Master Argo CD plugin development and integration. Learn to build custom CLI plugins and Config-Management Plugins (CMP) to extend Argo CD functionality for enhanced CI/CD workflows.

- Repository: [Argo Project/argo-cd](https://github.com/argoproj/argo-cd)
- Tags: how-to-guide
- Published: 2026-07-14

---

**Argo CD supports two distinct extension mechanisms: CLI plugins that add subcommands via executables named `argocd-<name>`, and Config-Management Plugins (CMP) that run as gRPC services on the server to generate manifests and discover repositories.**

The `argoproj/argo-cd` repository provides a flexible plugin architecture that enables you to customize both the command-line interface and the server-side manifest generation process. Whether you need to add custom subcommands to the `argocd` binary or support alternative configuration management tools beyond Helm and Kustomize, Argo CD plugin integration follows well-defined conventions backed by concrete protocol buffer definitions and service implementations.

## Understanding Argo CD Plugin Architecture

Argo CD distinguishes between client-side extensions that enhance the CLI and server-side extensions that customize manifest generation.

### CLI Plugins (Client-Side Extensions)

CLI plugins are standalone executables that extend the `argocd` command-line tool. When a user runs `argocd foo`, the CLI searches `$PATH` for an executable named `argocd-foo` and invokes it directly. According to the source in [`cmd/argocd/commands/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmd/argocd/commands/plugin.go), the CLI does not parse global flags before passing arguments to the plugin; the binary receives all arguments after the subcommand unchanged.

This mechanism relies on a simple naming convention: any executable on the host's `$PATH` prefixed with `argocd-` automatically becomes available as a subcommand.

### Config-Management Plugins (Server-Side Extensions)

Config-Management Plugins (CMP) are sophisticated server-side extensions defined by the `ConfigManagementPlugin` custom resource. These plugins run inside the Argo CD control plane and communicate via gRPC. The protobuf definition in `cmpserver/plugin/plugin.proto` specifies four primary RPCs: `GenerateManifest`, `MatchRepository`, `GetParametersAnnouncement`, and `CheckPluginConfiguration`.

The core service implementation lives in [`cmpserver/plugin/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/plugin.go), where the CMP server handles manifest generation, repository discovery, and dynamic parameter exposure.

## Developing Config-Management Plugins

CMP development involves creating a [`plugin.yaml`](https://github.com/argoproj/argo-cd/blob/main/plugin.yaml) configuration and understanding the gRPC service lifecycle.

### Plugin Configuration Structure

Each CMP requires a configuration file named [`plugin.yaml`](https://github.com/argoproj/argo-cd/blob/main/plugin.yaml) placed alongside the application source. The structure is defined by `PluginConfig` and `PluginConfigSpec` in [`cmpserver/plugin/config.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/config.go), which `ReadPluginConfig` parses at runtime.

A minimal configuration specifies:

- **generate**: The command that produces Kubernetes manifests
- **discover**: Rules determining which repositories the plugin can handle
- **init**: Optional setup commands run before generation

### The CMP gRPC Service Implementation

The CMP server implements the `ConfigManagementPluginService` defined in `cmpserver/plugin/plugin.proto`. The service architecture in [`cmpserver/plugin/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/plugin.go) processes requests through several key functions:

- **getTempDirMustCleanup**: Creates isolated working directories for safe execution
- **runCommand**: Executes the configured init and generate commands
- **matchRepository** (lines 324-368): Evaluates discovery rules against repository contents

When Argo CD needs manifests, it streams application files to the `GenerateManifest` RPC, which orchestrates the execution flow and splits output using `kube.SplitYAMLToString`.

### Manifest Generation and Parameter Handling

The manifest generation flow follows a strict sequence:

1. Optional initialization via `spec.Init.Command`
2. Execution of `spec.Generate.Command` in the application directory
3. Parsing stdout into individual YAML documents
4. Returning the manifest list to the Argo CD application controller

For dynamic UI integration, CMPs expose parameters through `GetParametersAnnouncement`. The plugin can define static parameters or execute a `Dynamic` command that outputs `apiclient.ParameterAnnouncement` messages, enabling custom input forms in the Argo CD UI.

## Building CLI Plugins for Argo CD

Creating a CLI plugin requires no compilation or registration beyond placing an executable on the system path.

```bash
#!/usr/bin/env bash

# Save as argocd-hello on $PATH and make executable

if [[ "$1" == "world" ]]; then
    echo "Hello from Argo CD plugin!"
else
    echo "Usage: argocd hello world"
fi

```

After running `chmod +x argocd-hello` and ensuring the file is in `$PATH`, the command `argocd hello world` invokes the script. The discovery logic in [`cmd/argocd/commands/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmd/argocd/commands/plugin.go) uses `exec.LookPath` to locate the binary and `os.Exec` to run it with the provided arguments.

## Practical Example: Helm Config-Management Plugin

Below is a complete CMP configuration that treats repositories containing [`Chart.yaml`](https://github.com/argoproj/argo-cd/blob/main/Chart.yaml) as Helm charts.

```yaml
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
  name: helm-cmp
spec:
  version: v1
  generate:
    command: ["helm", "template", "."]
  discover:
    fileName: "Chart.yaml"

```

The server-side execution in [`cmpserver/plugin/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/plugin.go) processes this configuration:

```go
func (s *Service) generateManifest(ctx context.Context, appDir string, envEntries []*apiclient.EnvEntry) (*apiclient.ManifestResponse, error) {
    // Run optional initialization
    if len(s.initConstants.PluginConfig.Spec.Init.Command) > 0 {
        if _, err := runCommand(ctx, s.initConstants.PluginConfig.Spec.Init, appDir, env); err != nil {
            return nil, err
        }
    }
    
    // Execute the generation command from plugin.yaml
    out, err := runCommand(ctx, s.initConstants.PluginConfig.Spec.Generate, appDir, env)
    if err != nil {
        return nil, err
    }
    
    // Split combined output into individual manifests
    manifests, err := kube.SplitYAMLToString([]byte(out))
    if err != nil {
        return nil, err
    }
    return &apiclient.ManifestResponse{Manifests: manifests}, nil
}

```

Register the plugin by applying the custom resource to your cluster: `kubectl apply -f helm-plugin.yaml`. Argo CD automatically routes matching applications to this CMP based on the discovery rules.

## Testing and Validation

The `argoproj/argo-cd` repository includes comprehensive testing infrastructure for plugin development:

- **Unit tests** for CMP logic reside in [`cmpserver/plugin/plugin_test.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/plugin_test.go), covering repository matching and command execution
- **Integration tests** in `test/e2e/` validate end-to-end plugin workflows using actual plugin configurations
- Run `make test` before submitting changes to ensure no regressions in the plugin subsystem

When testing locally, verify that your [`plugin.yaml`](https://github.com/argoproj/argo-cd/blob/main/plugin.yaml) syntax matches the `PluginConfig` struct in [`cmpserver/plugin/config.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/config.go) to avoid runtime unmarshaling errors.

## Summary

Argo CD plugin development provides two powerful extension paths:

- **CLI plugins** extend the `argocd` binary through executable files named `argocd-<command>` discovered in `$PATH`, implemented in [`cmd/argocd/commands/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmd/argocd/commands/plugin.go)
- **Config-Management Plugins** run as gRPC services in [`cmpserver/plugin/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/plugin.go), handling manifest generation via `GenerateManifest`, repository discovery via `MatchRepository`, and dynamic parameters via `GetParametersAnnouncement`
- CMP configurations use [`plugin.yaml`](https://github.com/argoproj/argo-cd/blob/main/plugin.yaml) files processed by [`cmpserver/plugin/config.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/config.go) to define generation commands, init steps, and discovery rules
- Both mechanisms support comprehensive testing through unit tests in [`cmpserver/plugin/plugin_test.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/plugin_test.go) and end-to-end test suites

## Frequently Asked Questions

### What is the difference between CLI plugins and Config-Management Plugins?

CLI plugins are client-side executables that add new subcommands to the `argocd` CLI tool, running on the user's machine wherever the binary is installed. Config-Management Plugins are server-side gRPC services that run within the Argo CD control plane to generate Kubernetes manifests, discover repository types, and expose application parameters. CLI plugins handle user interactions, while CMPs handle manifest generation logic.

### How does Argo CD discover which CMP to use for a repository?

Argo CD invokes the `MatchRepository` RPC defined in `cmpserver/plugin/plugin.proto` to determine plugin suitability. The evaluation logic in [`cmpserver/plugin/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/plugin.go) (lines 324-368) checks the `Discover` section of your [`plugin.yaml`](https://github.com/argoproj/argo-cd/blob/main/plugin.yaml), which can specify file names, glob patterns, or custom commands. If the discovery criteria match the repository contents, Argo CD selects that CMP for manifest generation.

### Can CMPs run initialization commands before generating manifests?

Yes. The `ConfigManagementPlugin` spec supports an optional `Init` field that specifies commands to run before the `Generate` step. According to the implementation in [`cmpserver/plugin/plugin.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/plugin.go), the server executes init commands via `runCommand` within the same isolated working directory used for generation, allowing you to download dependencies or prepare templates before manifest creation.

### Where should the plugin.yaml file be located for a CMP to work?

The [`plugin.yaml`](https://github.com/argoproj/argo-cd/blob/main/plugin.yaml) file must reside in the application source repository, typically at the root or alongside the application manifests. The CMP server reads this configuration via `ReadPluginConfig` in [`cmpserver/plugin/config.go`](https://github.com/argoproj/argo-cd/blob/main/cmpserver/plugin/config.go) when processing the repository. Additionally, you must register the plugin with Argo CD by creating a `ConfigManagementPlugin` custom resource that references the configuration.