Skip to content
Mohit Suman edited this page Aug 21, 2026 · 2 revisions

Harness CLI — FAQ

Questions we get most often, answered by the people who work on the CLI.

Don't see your question? Open a discussion or an issue. We triage every one.

In a hurry? Install, log in, and see everything you can do:

curl -fsSL https://raw.githubusercontent.com/harness/cli/main/install.sh | sh
harness auth login
harness list noun --matrix

Contents

Section What's inside
Getting started Install, upgrade, uninstall, version
Grammar and discovery Verbs, nouns, --help, list noun --matrix
Authentication and profiles Login, SSO, PAT/SAT, profiles, credential storage
Daily use Workflows, --set, -f, filters, scope
Harness Code PRs, reviews, merge, checks, review insights
Output, scripting, and shell integration Formats, exit codes, completion, NO_COLOR
Interactive TUI (--ui) Browsers, pickers, live log viewer
Comparisons vs. old CLIs, REST, Terraform, curl
AI agents Claude Code, Cursor, MCP, RBAC, blast radius
Extending and contributing Specs, plugins, local dev, issues
Trust and security curl | sh, cosign, telemetry, reporting
Troubleshooting Common errors and how to unstick

Getting started

How do I install it?

macOS / Linux

curl -fsSL https://raw.githubusercontent.com/harness/cli/main/install.sh | sh

Windows (PowerShell)

irm https://raw.githubusercontent.com/harness/cli/main/install.ps1 | iex

Places harness in ~/.local/bin on Unix or %LOCALAPPDATA%\Programs\harness on Windows. Override with --install-dir / -InstallDir. Prebuilt binaries for every release are on the releases page. The default installer also registers the har (Artifact Registry) plugin from the same bundle.

See docs/manual-install.md if you need to install from a downloaded archive or behind a proxy.

Which platforms are supported?

Platform Architectures Status
macOS arm64, amd64 Supported
Linux amd64, arm64 Supported
Windows amd64, arm64 Supported (native binary + PowerShell installer)

Homebrew, apt, and yum packages — coming soon.

How do I upgrade?

harness install cli                  # upgrade core + installed modules to latest
harness install cli --version v3.2.1 # pin a specific version
harness install cli --core-only      # upgrade harness only, skip module updates
harness install module har           # upgrade a single module/plugin

Re-running the curl | sh or irm | iex installer also works.

How do I uninstall?

rm ~/.local/bin/harness              # binary (Unix)
rm -rf ~/.harness                    # credentials + config (optional)

On Windows, remove the install directory you chose (default %LOCALAPPDATA%\Programs\harness) and delete %USERPROFILE%\.harness if you want to clear config.

What version am I running?

harness version
harness version --format json   # for scripts

↑ back to top


Grammar and discovery

What's the command shape?

harness <verb> <noun> [identifier] [flags]

Core verbs — list, get, create, update, delete, execute — plus push, pull, and configure for artifacts. Self-management commands (auth, install, version, debug) sit outside the grammar because they act on the CLI itself, not on a Harness resource.

Why only six verbs?

To keep the surface predictable. Every resource plugs into the same verbs — no deploy-with-canary, no pipeline-v2. When a resource needs a focused action, we add a qualified noun (execution:abort, pr:merge) instead of inventing a new verb.

How do I find the command for X?

harness list noun                    # every noun the CLI knows
harness get noun pipeline            # aliases, fields, commands for one noun
harness list module                  # loaded modules
harness get module code              # nouns and guides for a module
harness list noun --matrix           # full noun × verb matrix

Every command supports --help at every depth. Typos get "did you mean…?" suggestions.

For the full command catalog, see the Command Reference wiki page (or docs/Command-Reference.md in the repo).

What's a "qualified noun" like pr:merge or execution:abort?

A sub-operation on the same resource. Keeps the verb set closed:

harness list pr:mine                          # PRs you authored, across every repo
harness list pr:review_pending                # PRs awaiting your review, across every repo
harness execute pr:merge <repo>/<num>         # merge a PR
harness execute pr:review <repo>/<num>          # approve or request changes
harness execute execution:abort <exec-id>     # abort a running execution
harness get pipeline:summary <id>             # condensed pipeline view
harness get pr:insight <repo>/<num>           # AI risk summary for a PR

Everything after : is spec-defined, so --help on each variant lists its flags.

How many commands and modules are there today?

10 public modules, 276 commands, 86 nouns (as of CLI 3.x). Three additional modules (kg, aievals, fme) ship in the binary but are gated to harness.io accounts.

Module Commands What it covers
core 22 Auth, install, discovery, debug
platform 48 Orgs, projects, connectors, secrets, delegates, agents
pipeline 45 Pipelines, executions, logs, triggers, templates, approvals
cd 20 Services, environments, infrastructure
iacm 13 Terraform workspaces, Ansible
har 47 Artifact Registry (plugin binary)
code 41 Harness Code — repos, PRs, reviews, checks
gitops 27 GitOps agents, apps, clusters, repos
governance 11 OPA policies and policy sets
audit 2 Audit trail

Run harness list noun --matrix on your install for the live number — it always reflects what's loaded in your binary and profile.

↑ back to top


Authentication and profiles

How do I log in?

Interactive (PAT/SAT wizard)

harness auth login

Non-interactive (CI, scripting)

harness auth login \
  --api-url app.harness.io \
  --api-token <pat-or-sat> \
  --org <org> \
  --project <project> \
  --overwrite

Or skip profiles entirely and set HARNESS_API_KEY + HARNESS_ACCOUNT (see docs/auth.md).

Browser SSO

harness auth login --sso

Opens a browser OAuth flow. Tokens are stored in the OS keychain where available. Refresh with harness auth sso_refresh; check expiry with harness auth sso_status.

Both PAT (pat.…) and SAT (sat.…) tokens are supported. SATs may need manual scope after login:

harness auth setscope --org myorg --project myproject

How do I switch between accounts or environments?

Profiles.

harness auth login --profile prod
harness auth login --profile staging
harness auth setscope --profile prod --org acme --project checkout

harness auth profiles                       # list them
harness auth status                         # active profile + validation
export HARNESS_PROFILE=staging              # default for the shell session
harness --profile staging list pipeline       # override per invocation

There is no auth setdefault command — use HARNESS_PROFILE or --profile per invocation.

Which profile does the CLI pick?

Resolved in this order — the first match wins:

Priority Source
1 --profile flag
2 HARNESS_API_KEY env var (plus HARNESS_ACCOUNT, optional org/project)
3 HARNESS_PROFILE env var
4 CI runner env vars (auto-detected)
5 default profile from ~/.harness/config.yaml

When --profile is set, auth env vars are ignored entirely — no blending between modes.

Can I use the CLI without a Harness account?

No — every resource command hits the Harness API. You can install the CLI and run harness list noun without an account to browse the grammar; nothing else works offline.

↑ back to top


Daily use

Show me a real workflow — pipelines

Deploy a service, watch it, abort if it goes sideways:

# What's out there
harness list pipeline
harness get pipeline deploy-checkout

# Run it
harness execute pipeline deploy-checkout --set image_tag=v2.31.4

# Watch
harness list execution --filter pipeline_id=deploy-checkout --limit 5
harness get execution_log <pipeline-id>/<execution-id> --follow

# Or open the live log viewer (TTY required)
harness get execution_log <pipeline-id>/<execution-id> --ui

# Abort if needed
harness execute execution:abort <execution-id>

How do I pass structured input?

Two ways, and you can mix them:

# Inline
harness create secret my-token --set value=abc123

# From a YAML file (or stdin)
harness create secret -f secret.yaml
cat secret.yaml | harness create secret -f -

# From a file, with an override
harness update pipeline deploy-checkout -f pipeline.yaml --set variables.region=us-east-2

How do I filter and paginate a list?

harness list execution --limit 50
harness list execution --limit 50 --offset 100
harness list execution --all                     # walk every page
harness list execution --count                   # total only, no rows
harness list audit_event --since 24h

Note: --all is convenient but chatty on large collections. Add --filter or --limit first when exploring.

How do I change scope for one command?

harness --org acme list pipeline
harness --project checkout list pipeline
harness --level org list connector    # some nouns exist at multiple levels

Flags override the profile's default scope for that invocation only.

↑ back to top


Harness Code

Can I do my whole PR workflow from the terminal?

Yes — that's what the code module is for. A typical flow:

# See what's on your plate
harness list pr:mine --state open
harness list pr:review_pending

# Open and review
harness create pr my-repo --set title="fix: retry" source_branch=fix/retry
harness get pr my-repo/42
harness list pr_check my-repo/42              # checks tied to pipeline executions
harness execute pr:review my-repo/42 --decision approve
harness create pr_comment my-repo/42 -f review.md

# Merge
harness execute pr:merge my-repo/42 --method squash --delete-branch

Compound IDs use <repo>/<pr_number> — not separate --pr flags.

What are "review insights" commands?

Harness Code AI review surfaces risk summaries, suggested reviewers, and success criteria through the same CLI grammar:

harness get pr:insight <repo>/<pr>
harness get pr:review_group <repo>/<pr>
harness list pr_suggested_reviewer <repo>/<pr>
harness list pr_success_criterion <repo>/<pr>

How does --author work on list pr?

Pass an email, Harness UID, or numeric principal ID — the CLI resolves it automatically. You can also look up principals with harness list code_principal --search <name>.

↑ back to top


Output, scripting, and shell integration

What output formats are supported?

Format Default for Notes
table list Human-readable, terminal-width aware
text get Key: value lines
json Full API response (envelope included)
jsonl One record per line — best for streaming and agents
yaml get (some) Round-trippable with -f
csv, tsv For spreadsheets and Unix pipelines
markdown For dropping into docs, issues, or Slack

-o is a short alias for --format.

harness list pipeline --format json | jq '.[] | .identifier'
harness list execution --format jsonl | head -100
harness get pipeline my-pipe --yaml > pipe.yaml

On list, table/csv/tsv show projected columns only. On any verb, --format json returns the raw API envelope — use that when you need fields not shown in the table.

Is the JSON contract stable?

Field names on list/get output are covered by our compatibility contract and change only on a major version. Fields we add are additive.

How do I enable tab completion?

Zsh (recommended — live in shell)

source <(harness completion zsh)   # add to ~/.zshrc

Bash

source <(harness completion bash)   # add to ~/.bashrc

Fish

harness completion fish > ~/.config/fish/completions/harness.fish

Completion is live-API-backed where it makes sense — harness list pr <repo><TAB> calls the API and lists real PR numbers. Code commands use contextual completion sequences (repo → PR → comment).

Where does the CLI keep its files?

Everything under ~/.harness/:

Path Contents
config.yaml Profile metadata (no tokens)
credentials Tokens only
completions-cache/ Cached IDs for live tab completion
bin/ Installed plugin binaries (e.g. harness-har)
update-check.json Background update-check cache

Override the config location with HARNESS_CONFIG_HOME.

↑ back to top


Interactive TUI (--ui)

What does --ui do?

Opens a Bubble Tea TUI for browsing, picking, or watching — a middle ground between list output and the web UI.

harness list pipeline --ui         # paged, searchable browser
harness list execution --ui
harness list pr:mine --ui
harness get project --ui           # org-aware picker
harness get artifact_version --ui

# Live log viewer with a step graph
harness get execution_log <pipeline-id>/<execution-id> --ui

Every paged list command gets --ui for free — the flag is auto-wired from the spec, not hand-added per command.

When does --ui refuse to run?

--ui requires a TTY. It will not run in CI, under a pipe, or with redirected output. Use --follow and --format jsonl there instead.

Other restrictions:

  • Mutually exclusive with --format, --out, and shell redirection.
  • On the log viewer, don't combine with --stage/--step — use the <pipeline-id>/<execution-id> form and navigate inside the TUI.

For searching log output in scripts, redirect plain-text logs and use grep/rg/less:

harness get execution_log <id> --follow | grep -i error

Are keys configurable?

Not yet. Defaults follow common conventions:

Key Action
Arrows or hjkl Navigate
/ Filter (list browser)
enter Drill in
q or ctrl-c Quit
? Keybinding overlay

The live log viewer supports step selection, tab switching (logs/details/inputs/outputs), refresh, and save-to-file — see harness get execution_log --help.

↑ back to top


Comparisons

How is this different from the older Harness CLIs?

Most Harness modules never had a first-class CLI — the developer experience was fragmented. The legacy hc CLI is being deprecated in favor of this unified binary.

The new CLI is one grammar that covers every module through the same auth, discovery, and output conventions. Legacy tools keep working through a deprecation window — no same-day cutover.

How does Harness Code CLI compare to gh / glab?

The code module covers the core repo/PR loop (create, list, comment, review, merge, checks) with Harness-specific advantages: cross-repo queues (pr:mine, pr:review_pending), review insights, and PR checks that carry pipeline execution IDs natively. See docs/harness-cli-positioning.md for a detailed comparison.

Should I use the CLI or the REST API?

Use case Reach for
Interactive work, scripting, CI glue CLI — shorter, consistent auth and output
Building a service that talks to Harness REST API or language SDKs — the CLI isn't designed to be embedded

Should I use the CLI or the Terraform provider?

Different jobs.

Tool Best for
Terraform provider Declarative infrastructure — state files, plan/apply, drift detection
Harness CLI Imperative work — one-shot commands, exploration, incident response, ad-hoc CI steps

Most teams use both.

Why not just use curl and jq?

You can. Things the CLI does that curl doesn't, unless you rebuild them:

  • One auth flow across every Harness endpoint, including SSO refresh
  • Live tab completion of real resource IDs
  • Consistent --format, filtering, and paging on every list endpoint
  • Interactive TUI for browsing and live log viewing
  • Self-describing grammar (list noun --matrix) for humans and agents

For a one-off request, curl is fine. For anything you'd re-run, the CLI ends up shorter.

↑ back to top


AI agents

Can I hand this to Claude Code / Cursor / Copilot CLI?

Yes — this is one of the two audiences we designed for. Point the agent at:

harness list noun --matrix --format json
harness get module code --format json
harness get noun pr --format json

… and it has the entire action surface as structured data. Ask it to prefer harness <verb> <noun> over raw REST. The Command Reference and cheat sheet section are written for agent consumption.

The CLI also detects and reports the coding agent in telemetry (Claude Code, Cursor, Codex, Cline, and others) so operators know how the CLI is being driven.

Does the CLI enforce RBAC when an agent runs it?

The CLI doesn't enforce anything — the Harness API does. Every request goes through the same auth, RBAC, and audit path as the web UI. An agent using the CLI is a client with a token; whatever that token can do, the agent can do. No side channel, no "AI mode."

Give agents scoped tokens the same way you'd give a service account one — project-scoped PATs or SATs, not admin tokens.

Is there an MCP server?

Yes, for Cursor and compatible hosts — the official Harness Cursor plugin ships consolidated MCP tools (harness_list, harness_get, harness_create, etc.) that cover 160+ resource types.

A native CLI MCP server (harness mcp serve) is on the roadmap but not shipped yet. Until then, use the plugin MCP or point agents at harness list noun --matrix + --format json.

Can an agent break something in production?

An agent with a production token can do whatever that token permits — same as any script. Controls to reach for:

  • Scoped PATs/SATs (project-scoped or role-scoped) instead of admin tokens
  • Confirmation promptsdelete and some execute variants require explicit confirmation; instruct the agent never to bypass them
  • The audit trailharness list audit_event catches everything after the fact

↑ back to top


Extending and contributing

Where's the source?

github.com/harness/cli. Apache 2.0. All development on main, in the open.

How do I add a new command?

For most nouns, add or edit a spec file under pkg/spec/ — declarative YAML that describes the verb, noun, HTTP endpoint, flags, and output shape. No Go code needed for the common case.

For commands with custom logic (artifact push/pull, the log viewer, PR merge body builders), write a handler under modules/<module>/ and reference it from the spec. Full walkthrough in AGENTS.md.

Can I write a plugin or a whole module?

Yes. The Artifact Registry (har) already ships as a companion binary — same grammar, separate go.mod, installed via harness install plugin har. See docs/plugins.md for the plugin packaging model.

harness install plugin har                             # by name
harness install plugin https://example.com/foo.tar.gz  # from a tarball URL
harness install plugin ./foo.tar.gz                    # from a local tarball
harness list plugin                                    # what's installed

If you have a use case, open a discussion so we know what you need before the SDK freezes.

How do I run the CLI locally against my changes?

git clone https://github.com/harness/cli
cd cli
task build                              # requires go-task: brew install go-task
cp bin/harness ~/.local/bin/harness     # active binary path
harness list noun

task build:main skips the HAR plugin for faster iteration when you're not touching artifact code. go test ./... runs unit tests.

Where do I file bugs or requests?

Channel Use for
Issues Bugs, feature requests, "what does this flag do?"
Discussions Design conversations, ideas

We triage every issue.

↑ back to top


Trust and security

What does curl … | sh actually run?

The installer script at install.sh. It:

  1. Detects your OS/arch.
  2. Downloads the matching binary and checksum from GitHub releases.
  3. Verifies the checksum. If cosign is on your PATH, verifies the signature too.
  4. Moves the binary into the install directory.
  5. Optionally registers the har plugin and shell completions.

It doesn't touch anything outside the install directory, doesn't require root, and doesn't modify shell configs unless you pass --modify-shell.

Read it before you run it: curl -fsSL https://raw.githubusercontent.com/harness/cli/main/install.sh | less

Can I verify releases with cosign?

Yes. Every release binary is signed with keyless Sigstore. See BUILD.md for verification commands.

Report security issues to security@harness.io, not the public tracker.

↑ back to top


Troubleshooting

--ui requires an interactive terminal (TTY)

You're running in an environment without a TTY on stdin or stdout (CI, a pipe, a headless container). Drop --ui and use --format jsonl / --follow instead.

authentication failed (exit 2)

Run harness auth status. Common causes:

  • PAT/SAT expired or was rotated → re-run harness auth login.
  • HARNESS_API_KEY set to a stale value → unset HARNESS_API_KEY if you meant to use a profile.
  • Wrong account → harness --profile <name> auth status.
  • SSO token expired → harness auth sso_refresh or re-run harness auth login --sso.

not logged in / SAT can't list orgs

Service account tokens are often scoped to specific resources. Log in with the SAT, then set scope manually:

harness auth login --api-token sat.xxx --overwrite
harness auth setscope --org myorg --project myproject

Or use --no-validate during login if validation fails due to limited SA permissions, then verify with harness auth status.

resource not found (exit 3) on something I can see in the UI

Almost always a scope mismatch. Check harness auth status for the active org/project, and try adding --org and --project explicitly. Some resources live at account or org level and won't appear under a project scope.

Command exists in docs but not on my install

Run harness version and compare to releases. Some modules (kg, aievals, fme) are hidden unless your profile is on a harness.io account. Run harness list module to see what's loaded for you.

↑ back to top

Clone this wiki locally