For the complete documentation index, see llms.txt. This page is also available as Markdown.

Building Custom Agents

Build, package, and register your own AI-powered agent plugins for Harness using the Drone plugin architecture; Go binaries in Docker containers, registered as pipeline templates.

Harness agent plugins follow the Drone plugin architecture, a Go-based pattern where each plugin is a Docker container that receives configuration via environment variables and executes autonomous workflows. This guide covers the full development lifecycle from project setup to registration in the Harness Agents catalog.

Language

Go

Architecture

Drone plugin pattern

Runtime

Docker container

Integration

Harness API

Plugin architecture

Each plugin is a Go binary that runs inside a Docker container. Configuration is passed via environment variables with a PLUGIN_ prefix, and the plugin implements a Plugin struct with an Exec() method.

Core components

  • CLI Framework (main.go): Uses urfave/cli for command-line argument parsing. Defines flags that map to PLUGIN_ prefixed environment variables.

  • Business Logic (plugin.go): Contains the Plugin struct with all configuration fields and the Exec() method that implements the agent's core workflow.

  • Agent Binaries (bin/): Pre-compiled AI agent binaries (e.g., ai-code-agent, remediation-agent) that the plugin orchestrates.

  • Docker Container: Multi-stage Dockerfile that builds the Go binary and packages it with runtime dependencies.

package main

import (
    "os"
    "os/exec"
    "github.com/pkg/errors"
    "github.com/sirupsen/logrus"
)

type Plugin struct {
    // Required fields
    WorkingDirectory string
    AnthropicAPIKey  string
    // Optional features
    DetailedLogging  bool
    // Harness API integration
    HarnessAPIKey      string
    HarnessAccountID   string
    HarnessOrgID       string
    HarnessProjectID   string
    HarnessPipelineID  string
    HarnessExecutionID string
    HarnessBaseURL     string
}

func (p *Plugin) Exec() error {
    // 1. Validate configuration
    if p.WorkingDirectory == "" {
        return errors.New("working directory is required")
    }
    if p.AnthropicAPIKey == "" {
        return errors.New("Anthropic API key is required")
    }

    // 2. Setup logging
    if p.DetailedLogging {
        logrus.SetLevel(logrus.DebugLevel)
    }

    // 3. Execute agent binary
    cmd := exec.Command("/root/bin/ai-code-agent",
        "--working-dir", p.WorkingDirectory,
    )
    cmd.Dir = p.WorkingDirectory
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.Env = append(os.Environ(),
        "ANTHROPIC_API_KEY="+p.AnthropicAPIKey,
    )

    if err := cmd.Run(); err != nil {
        return errors.Wrap(err, "agent execution failed")
    }
    return nil
}

DRONE PLUGIN PATTERN

The Drone plugin architecture is the standard pattern for all Harness CI plugins. If you've built Drone plugins before, the same patterns apply to agent plugins.


Project structure

File
Purpose

main.go

CLI entry point. Defines flags, maps to PLUGIN_ environment variables, constructs Plugin struct, and calls Exec()

plugin.go

Core business logic. Contains Plugin struct with configuration fields and the Exec() method

go.mod

Go module definition with required dependencies (urfave/cli, logrus, godotenv, pkg/errors)

Dockerfile

Multi-stage Docker build: compile Go binary, then copy to slim runtime image with agent binaries

Makefile

Build targets: build (local binary), build-docker (Docker image), push (Docker Hub)

bin/

Directory for pre-compiled agent binaries that the plugin orchestrates at runtime


Build the plugin

Required dependencies

Map environment variables

Each CLI flag maps to a PLUGIN_ prefixed environment variable. Harness also auto-populates platform context variables at runtime.

CLI Flag
Environment Variable
Description

--working-directory

PLUGIN_WORKING_DIRECTORY

Path to the cloned git repository

--anthropic-api-key

PLUGIN_ANTHROPIC_API_KEY

Anthropic API key for Claude AI

--detailed-logging

PLUGIN_DETAILED_LOGGING

Enable debug-level logging

--prompt

PLUGIN_PROMPT

Task prompt for the agent

(auto-populated)

HARNESS_ACCOUNT_ID

Harness account identifier

(auto-populated)

HARNESS_ORG_ID

Harness organization identifier

(auto-populated)

HARNESS_PROJECT_ID

Harness project identifier

(auto-populated)

HARNESS_EXECUTION_ID

Pipeline execution identifier

Build with Makefile

AUTO-POPULATED VARIABLES

Harness auto-populates HARNESS_ACCOUNT_ID, HARNESS_ORG_ID, HARNESS_PROJECT_ID, and HARNESS_EXECUTION_ID when running plugins in CI pipelines. You don't need to configure these manually.


Docker package

Agent plugins use a multi-stage Docker build. The first stage compiles the Go binary; the second creates a minimal runtime image.

Runtime dependencies: ca-certificates for HTTPS API calls, git for repository operations, bash for shell script execution. Agent binaries (ai-code-agent, remediation-agent) are ~24–27 MB each. Use debian:bookworm-slim as base and CGO_ENABLED=0 for a statically-linked Go binary. Most plugins target linux/arm64.


Harness API integration

Plugins can integrate with the Harness API to fetch pipeline execution data and retrieve logs from failed steps.

To find and diagnose failed steps, traverse the execution graph, look for steps with status Failed or IgnoreFailed, validate presence of failureInfo with error messages, and extract the logBaseKey field for log retrieval.

The Harness API key is passed as the x-api-key header. Ensure your API key has permissions to read pipeline executions and logs for the target project.


Template registration

Once your plugin image is pushed, register it as a Harness Agent by creating a template in the agents repository.

Step 1: Create a template directory

Step 2: Define metadata.json

Step 3: Define pipeline.yaml

Step 4: Write wiki.MD

Metadata validation rules

  • Directory names: lowercase with hyphens (e.g., my-custom-agent)

  • Metadata name: lowercase with spaces (e.g., "my custom agent")

  • Input names in pipeline.yaml: camelCase (e.g., anthropicKey)

  • Version: semantic versioning (e.g., "1.0.0")

AUTOMATED REVIEW

Submit your template as a pull request to the agents repository. Automated Claude Code review via GitHub Actions validates your template against naming conventions, security rules, and cross-file consistency requirements.


Testing & deployment

Local testing

Docker testing

Pipeline testing

Deployment checklist

  • Plugin binary builds without errors

  • Docker image builds and runs successfully

  • All required inputs are validated in Exec()

  • Sensitive values (API keys, tokens) are never logged

  • Agent works correctly in a Harness CI pipeline

  • Template passes metadata.json and pipeline.yaml validation

  • wiki.MD provides clear documentation

Plugin composition patterns

Pattern 1: Two-stage analysis + fix

Pattern 2: Standalone with custom prompt

Pattern 3: Multi-model pipeline

Shared containers

Container
Purpose
Used By

anewdocker25/mydockerhub:coding-agent

AI-powered code modification

Autofix, Code Review, Feature Flag Cleanup, React Upgrade

anewdocker25/mydockerhub:remediation-agent

Error analysis and diagnosis

Autofix, Manifest Remediator

himanshu6956/create-pr-plugin:latest

Multi-SCM pull request creation

Autofix, Code Coverage, React Upgrade

You can reuse these existing agent containers as building blocks. The coding-agent and create-pr-plugin containers are designed to be composed together in custom agent pipelines.

Last updated

Was this helpful?