Go CLI for Groundcover APIs.
It uses the official github.com/groundcover-com/groundcover-sdk-go where that SDK has a stable contract, and keeps HAR-derived raw commands for webapp endpoints the SDK does not expose.
brew tap paymog/tap
brew install groundcoverThe formula builds from source, so Homebrew installs a Go toolchain as a build dependency.
Go install:
go install github.com/paymog/groundcover-cli/cmd/groundcover@latestLocal build:
go build ./cmd/groundcoverThe simplest setup is environment variables (recommended for CI):
export GROUNDCOVER_API_KEY=...
export GROUNDCOVER_BACKEND_ID=...Also accepted: GC_API_KEY, GC_BACKEND_ID, GROUNDCOVER_TENANT_UUID, GC_TENANT_UUID, GROUNDCOVER_BASE_URL, GC_BASE_URL, GROUNDCOVER_GRAFANA_SERVICE_ACCOUNT_TOKEN, GC_GRAFANA_SERVICE_ACCOUNT_TOKEN.
For day-to-day use you can store credentials in named profiles. The API key is
kept in your OS keyring (macOS Keychain, Linux libsecret/secret-service, Windows
Credential Manager); only non-secret metadata (backend ID, base URL, tenant UUID)
is written to ~/.config/groundcover/profiles.yaml (XDG-aware; %AppData% on
Windows).
groundcover auth login # prompts for the API key; profile "default"
groundcover auth login prod --backend-id my-backend --key lin_...
groundcover auth list # table; * marks the default
groundcover auth default prod # set the default profile
groundcover --profile prod monitors list # use a profile for one command
groundcover auth status # show which source resolved
groundcover auth token # print the resolved API key
groundcover auth logout prod # remove a profile (-f to skip confirm)login validates the key against the API before saving it. The first profile
added becomes the default.
Credential precedence (highest first):
--api-keyflag /GROUNDCOVER_API_KEYenv var--profile <name>→ stored profile- default profile → stored profile
Combining an explicit key with --profile is rejected as ambiguous. If no keyring
is available, fall back to GROUNDCOVER_API_KEY.
Defaults (override the env or flag for your own backend/tenant):
- Base URL:
https://api.groundcover.com - Backend ID:
groundcover(GROUNDCOVER_BACKEND_ID/--backend-id) - Tenant UUID: none. Set
GROUNDCOVER_TENANT_UUID/--tenant-uuidto sendX-Tenant-UUIDon raw HAR-derived requests; the SDK transport already implies tenant from the API key. - Grafana service account token: none. The embedded Grafana (
raw grafana …) endpoints are session-gated and ignore the API key, so they need a Grafana service account token (glsa_…). SetGROUNDCOVER_GRAFANA_SERVICE_ACCOUNT_TOKEN/--grafana-token. It is only used forraw grafana …commands. Running one without a token prints setup steps; generate a token with groundcover's official CLI (~/.groundcover/bin/groundcover auth generate-service-account-token, needs tenant admin).
groundcover dashboards list
groundcover dashboards get <id>
groundcover dashboards create --body-file dashboard.json
groundcover dashboards update <id> --body-file dashboard.json
groundcover dashboards delete <id>
groundcover monitors list --query 'monitor_name = "cpu"'
groundcover monitors get <id>
groundcover monitors create --body-file monitor.yaml
groundcover monitors update <id> --body-file monitor.yaml
groundcover monitors delete <id>
groundcover silences list --active
groundcover silences create --body-file silence.json
groundcover silences delete <id>
groundcover dashboards archive <id>
groundcover dashboards restore <id>
groundcover recurring-silences list
groundcover recurring-silences create --body-file silence.json
groundcover connected-apps list --query 'type:slack-webhook'
groundcover connected-apps get <id>
groundcover connected-apps create --body-file app.json
groundcover connected-apps update <id> --body-file app.json
groundcover connected-apps delete <id>
groundcover notification-routes list --query 'prod'
groundcover notification-routes get <id>
groundcover notification-routes create --body-file route.json
groundcover notification-routes update <id> --body-file route.json
groundcover notification-routes delete <id>
# Auth / RBAC
groundcover api-keys list
groundcover api-keys create --body-file key.json
groundcover service-accounts list
groundcover service-accounts create --body-file sa.json
groundcover ingestion-keys list
groundcover policies list
groundcover policies apply --body-file policy.json
groundcover policies audit-trail <id>
# Synthetics, secrets, workflows
groundcover synthetics list
groundcover synthetics create --body-file test.json
groundcover secrets create --body-file secret.json
groundcover secrets hash <id>
groundcover workflows list
groundcover workflows create --body-file workflow.yaml
# Pipeline configs (singleton get/create/update/delete)
groundcover logs-pipeline get
groundcover metrics-pipeline get
groundcover traces-pipeline get
groundcover metrics-aggregator get
# Integrations (typed)
groundcover integrations list
groundcover integrations describe <type>
groundcover integrations create <type> --body-file config.json
groundcover integrations update <type> <id> --body-file config.json
# Read/query
groundcover logs search --body-file search.json
groundcover traces search --body-file search.json
groundcover metrics query --body-file query.json
groundcover metrics names --body-file body.json
groundcover search discovery --body-file body.json
groundcover k8s clusters --body-file body.json
groundcover k8s workloads --body-file body.json
groundcover k8s events-search --body-file body.jsongroundcover raw list
groundcover raw list k8s
groundcover raw k8s clusters list
groundcover raw dashboards get --dashboard-id <id>
groundcover raw metrics query-range --body-file body.json
groundcover raw prometheus api query --query query='up'
groundcover raw grafana dashboards get --dashboard-uid <uid>
groundcover raw grafana dashboards save --body-file dashboard.json
groundcover raw grafana folders list
groundcover raw grafana ds query --body-file query.jsonStorage management uses one endpoint per data type:
groundcover raw storage-management get --data-type logs --raw \
| jq '{retention,version,cold_move_duration,cold_volume,custom_rules:(.custom_rules // [])}' \
> storage.json
# Edit storage.json, preserving every writable field and the complete rule list.
groundcover raw storage-management update --data-type logs --body-file storage.jsonSupported data types are logs, traces, events, measurements, and monitor_instance. Updates use optimistic concurrency and replace the writable settings document: start from get, pass its current version, and preserve retention, cold_move_duration, cold_volume, and the full custom_rules list. Omitting custom_rules removes existing rules.
Raw commands support:
--body-json '<json>'--body-file path.json--body-file path.yaml--set dotted.path=value--query key=value- path flags generated from captured UUIDs, for example
--dashboard-id <id> --raw
go run ./scripts/generate-commands.go ~/Downloads/app.groundcover.com.harGenerated commands are written to internal/raw/commands_generated.go.
internal/sdkcmd: first-class commands backed by the official SDK.internal/raw: best-effort command registry and runner for HAR-derived endpoints.internal/config: shared auth, base URL, timeout, and SDK transport setup.
This repo ships a Claude Code skill that teaches the
agent how to drive the CLI (auth, the SDK-vs-raw split, and ready-made request-body
templates for logs/traces/metrics/k8s). It lives in skills/groundcover-cli.
Install it with npx skills (Vercel's agent-skills tool):
# install into the current project (.claude/skills/)
npx skills add paymog/groundcover-cli
# or install globally for your user, skipping prompts
npx skills add paymog/groundcover-cli --global --yesUseful flags: --list to preview without installing, --skill groundcover-cli to target it
explicitly, -a claude-code to pick the agent.
Or install manually:
git clone https://github.com/paymog/groundcover-cli
cp -r groundcover-cli/skills/groundcover-cli ~/.claude/skills/groundcover-cliThen ask Claude Code to query logs, manage monitors, debug a prod issue, etc., and it will
invoke groundcover.
Releases are tag-driven:
git tag v0.1.0
git push origin v0.1.0GitHub Actions runs GoReleaser, then updates the source-build formula in paymog/homebrew-tap. The workflow pushes to the tap over SSH using a deploy key stored as the HOMEBREW_TAP_DEPLOY_KEY secret (the public half is a read-write deploy key on the tap repo).