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 Go and the Drone plugin architecture.

Learn how to build, package, and register your own AI-powered agent plugins for 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.

Go

Primary language

Drone

Plugin architecture

Docker

Containerized runtime

Harness API

Native integration


Plugin Architecture

Harness agent plugins follow the standard Drone 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

If you've built Drone plugins before, the same patterns apply to agent plugins.


Project Structure

Each agent plugin follows a standard directory layout:

File
Purpose

main.go

CLI entry point. Defines flags, maps to PLUGIN_ env vars, 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/

Pre-compiled agent binaries that the plugin orchestrates at runtime


Building the Plugin

Required Dependencies

Environment Variable Mapping

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

AUTO-POPULATED VARIABLES

Harness automatically injects HARNESS_ACCOUNT_ID, HARNESS_ORG_ID, HARNESS_PROJECT_ID, and HARNESS_EXECUTION_ID when running plugins in CI pipelines — no manual configuration needed.

Build with Makefile


Docker Packaging

Agent plugins are packaged as Docker containers using a multi-stage 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.

Image size notes: Agent binaries are ~24–27 MB each. Use debian:bookworm-slim as the base and CGO_ENABLED=0 for a statically-linked Go binary.


Harness API Integration

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

Failed step detection: traverse the execution graph, look for steps with status Failed or IgnoreFailed, validate failureInfo for error messages, then extract the logBaseKey field for log retrieval.


Template Registration

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

Step 1: Create 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. GitHub Actions runs automated Claude Code review to validate naming conventions, security rules, and cross-file consistency.


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

Agents can be composed from multiple plugins in a single pipeline.

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

REUSABLE BUILDING BLOCKS

The coding-agent and create-pr-plugin containers are designed to be composed together in custom agent pipelines — you don't need to build them from scratch.

Last updated

Was this helpful?