Skip to content

Helper CLI

The Overwatch Helper CLI is an optional local agent that runs on your machine and executes approved shell commands suggested by the AI Chat. It bridges the gap between AI-powered diagnosis and direct infrastructure interaction, allowing you to investigate and resolve incidents without leaving the Overwatch interface.

When the AI Chat determines that a diagnostic command would help (for example, kubectl get pods -n production), it presents the command in the conversation. You approve it, and Helper executes it locally, captures the output, and sends the results back to the AI for further analysis.

AI Chat suggests command
|
v
You review and approve
|
v
Helper validates against allowlist
|
v
Helper executes locally with timeout
|
v
Output captured and returned to AI
|
v
AI analyzes results, suggests next steps

The Helper never executes commands without your explicit approval. Every command is validated against a strict security allowlist before execution.

Download the Helper binary for your platform from the Overwatch dashboard or directly via the API.

Terminal window
curl -L "https://your-overwatch-instance/api/v1/helper/download?platform=macos-arm64" \
-o overwatch-helper
chmod +x overwatch-helper

The download endpoint fetches the latest release (currently v0.4.3) from GitHub Releases.

Terminal window
overwatch-helper --version
# overwatch-helper 0.4.3
  1. Start the Helper

    Run the binary from your terminal:

    Terminal window
    overwatch-helper

    You should see output confirming startup and environment detection:

    Starting Overwatch Helper
    Detecting environment...
    Environment detected
    Listening on http://127.0.0.1:9876
  2. Open Overwatch in your browser

    Navigate to the Overwatch dashboard or open the Chrome extension. The extension auto-detects when Helper is running on localhost port 9876.

  3. Start an AI Chat session

    When you interact with the AI Chat during an incident, the AI can now suggest commands that run on your local machine. You will see each command displayed in the chat before it runs --- nothing executes without your approval.

  4. Approve and review commands

    Click to approve a suggested command. The Helper executes it, captures the output, and the AI continues its analysis with the results.

On macOS and Linux, you can start Helper as a background daemon:

Terminal window
overwatch-helper --background
# Overwatch Helper started in background (PID: 48291)
# Stop with: kill 48291

On startup, Helper probes your local environment in parallel and caches the results for 5 minutes. This context is shared with the AI Chat so it can suggest commands appropriate for your setup.

ContextWhat is detectedExample
PlatformOperating systemmacos, linux, windows
KubernetesCurrent context and namespaceminikube / default
AWSProfile, region, account IDoverwatch-biz / us-east-1
GCPProject and regionmy-project / us-central1
DockerContext and client versiondefault / 24.0.7
RailwayProject, environment, serviceoverwatch / production

Helper checks for the presence of the following tools:

kubectl, aws, gcloud, docker, curl, dig, nslookup, helm, terraform, pulumi, ping, traceroute, netstat, railway, gh, git, stripe

The AI uses this information to avoid suggesting commands for tools that are not installed.

Helper implements a defense-in-depth security model. Commands must pass through multiple validation layers before execution.

Every command is checked against an explicit allowlist. If a command does not match an allowed prefix, it is rejected --- even if it appears harmless. This is a “default deny” approach.

Sessions are created with one of three permission levels, which control which commands are available:

LevelDescriptionExamples
Read-OnlyDiagnostic and inspection commands onlykubectl get pods, aws ecs describe-services, git status
LimitedRead-only commands plus safe write operationskubectl rollout restart, git push, gh pr create
FullAll read-only and limited commands (same set as Limited)Same as Limited

These commands are available at all permission levels:

Kubernetes: kubectl get, kubectl describe, kubectl logs, kubectl top, kubectl config current-context, kubectl cluster-info

AWS: aws sts get-caller-identity, aws ec2 describe-*, aws ecs describe-*, aws ecs list-*, aws logs get-log-events, aws cloudwatch get-metric-*

GCP: gcloud config get-value, gcloud container clusters list, gcloud compute instances list

Docker: docker ps, docker logs, docker inspect, docker images, docker version

Git: git status, git log, git diff, git branch, git show, git blame

GitHub CLI: gh pr list, gh pr view, gh issue list, gh run list, gh api, gh search code

Railway: railway status, railway logs, railway variables, railway whoami

Infrastructure: helm list, helm status, terraform show, terraform state list, pulumi preview, pulumi stack

Diagnostics: curl, ping, dig, nslookup, traceroute, df -h, free -m, ps aux

Stripe: stripe status, stripe events list, stripe customers list, stripe balance

These are available at the Limited and Full permission levels, in addition to all read-only commands:

Kubernetes: kubectl rollout restart, kubectl scale, kubectl rollout undo

Docker: docker restart

Git: git add, git commit, git push, git pull, git checkout, git merge, git rebase

GitHub CLI: gh pr create, gh pr merge, gh issue create, gh release create

Railway: railway up, railway down, railway redeploy, railway connect

Stripe: stripe trigger

Regardless of permission level, the following are always rejected:

  • rm -rf, rm -r, rmdir --- destructive file removal
  • sudo, su --- privilege escalation
  • drop table, drop database, truncate table --- destructive database operations
  • chmod 777 --- insecure file permissions
  • wget, eval, exec, source --- arbitrary code execution
  • mkfs, dd if= --- disk-level operations
  • passwd, apikey=, api_key= --- credential exposure
  • Shell metacharacters: ;, &&, ||, `, $(, >>, <<

Commands with pipes (|) are supported when:

  1. The first segment passes normal allowlist validation
  2. All subsequent segments use safe filter commands: grep, head, tail, sort, uniq, wc, cut, awk, sed, jq, yq, and others
Terminal window
# Allowed: safe pipe chain
kubectl get pods -n production | grep CrashLoopBackOff | wc -l
# Blocked: unsafe pipe target
kubectl get pods | bash

Each session is limited to 15 commands per minute by default. This uses a sliding window approach --- if you hit the limit, wait a few seconds for the window to advance.

  • Maximum capture size: 1 MB per command
  • Truncation for AI: Large outputs are automatically truncated to 48 KB before being sent to the AI Chat, keeping the context window manageable

Helper binds to 127.0.0.1 (localhost only) by default. It is not accessible from other machines on your network.

Only the following origins can communicate with Helper:

  • Chrome extension origins (chrome-extension://...)
  • Localhost development (http://localhost:*, http://127.0.0.1:*)

Understanding the full lifecycle of a command helps clarify the security boundaries:

  1. AI suggests a command

    Based on the incident context and your detected environment, the AI Chat suggests a specific command (for example, kubectl get pods -n production --field-selector=status.phase!=Running).

  2. You review and approve

    The command is displayed in the chat interface. You read it and click approve. Nothing runs until you explicitly grant permission.

  3. Session validation

    Helper verifies your session token is valid and not expired. Sessions use cryptographic tokens and have a configurable expiry (default: 60 minutes).

  4. Rate limit check

    The request is checked against the per-session rate limit (15 commands/minute). If the limit is exceeded, the command is rejected with an error.

  5. Command validation

    The command string is checked against the blocklist and then the allowlist for your permission level. Shell metacharacters are rejected. Pipe segments are validated independently.

  6. Execution

    For simple commands, Helper parses the command into a program and arguments directly (no shell interpreter). For piped commands, sh -c is used. A timeout is enforced (default: 30 seconds, maximum: 120 seconds).

  7. Output capture and return

    stdout and stderr are captured (up to 1 MB each), and the result (exit code, output, duration) is returned to the caller.

  8. Audit logging

    The command, exit code, duration, session ID, and permission level are written to a local audit log file.

  9. AI analysis

    The output is sent back to the AI Chat, which analyzes the results and either suggests further diagnostic commands or provides resolution guidance.

Every command executed through Helper is recorded in a local audit log.

Audit logs are stored in your platform’s local data directory by default:

PlatformDefault path
macOS~/Library/Application Support/overwatch-helper/audit/
Linux~/.local/share/overwatch-helper/audit/
Windows%LOCALAPPDATA%\overwatch-helper\audit\

Override the location with the --audit-dir flag or the OVERWATCH_HELPER_AUDIT_DIR environment variable.

Logs are written as newline-delimited JSON, one entry per command, organized into daily files (audit-YYYY-MM-DD.log):

{
"timestamp": "2026-02-23T14:30:05+00:00",
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"command": "kubectl get pods -n production",
"exit_code": 0,
"duration_ms": 342,
"permission_level": "read_only",
"success": true
}
  • Timestamp (ISO 8601)
  • Session ID (anonymized UUID, not your user identity)
  • Full command string
  • Exit code
  • Execution duration in milliseconds
  • Permission level of the session
  • Success/failure boolean

All configuration options can be set via command-line flags or environment variables.

FlagEnvironment VariableDefaultDescription
--portOVERWATCH_HELPER_PORT9876Port to listen on
--hostOVERWATCH_HELPER_HOST127.0.0.1Host to bind to
--default-timeout-secs---30Default command timeout
--max-timeout-secs---120Maximum allowed timeout
--rate-limit-per-minute---15Max commands per minute per session
--max-sessions---5Maximum concurrent sessions
--log-levelOVERWATCH_HELPER_LOG_LEVELinfoLog level (trace, debug, info, warn, error)
--audit-dirOVERWATCH_HELPER_AUDIT_DIRPlatform-specificDirectory for audit log files
--background, -b---falseRun as background daemon (Unix only)
Terminal window
overwatch-helper \
--port 9877 \
--rate-limit-per-minute 30 \
--default-timeout-secs 60 \
--log-level debug

Helper exposes a local HTTP API on 127.0.0.1:9876. These endpoints are used by the Chrome extension and are documented here for reference.

Returns Helper version, detected capabilities, and environment information.

{
"version": "0.4.3",
"capabilities": ["kubectl", "aws", "docker", "shell"],
"environment": {
"platform": "macos",
"kubernetes": { "context": "minikube", "namespace": "default" },
"aws": { "profile": "overwatch-biz", "region": "us-east-1", "account_id": "331860160301" },
"docker": { "context": "default", "version": "24.0.7" },
"available_tools": ["kubectl", "aws", "docker", "curl", "git", "gh"]
}
}

Returns only the detected environment information (same data as the environment field in /health).

Creates a new session. Requires a backend authentication token.

Request body:

{
"token": "your-backend-auth-token",
"duration_minutes": 60,
"permission_level": "read_only"
}

Response:

{
"session_token": "a1b2c3d4..."
}

Ends an active session. Requires the X-Session-Token header.

Executes a validated command. Requires the X-Session-Token header.

Request body:

{
"command": "kubectl get pods -n production",
"timeout_seconds": 30,
"capture_output": true
}

Response:

{
"success": true,
"exit_code": 0,
"stdout": "NAME READY STATUS RESTARTS AGE\napi-7d4b8c6f9-x2k4l 1/1 Running 0 2d\n",
"stderr": "",
"duration_ms": 342
}

Symptoms: The AI Chat does not offer to run commands locally.

  1. Verify Helper is running: open http://127.0.0.1:9876/health in your browser.
  2. Check that the port is not blocked by a firewall or occupied by another process.
  3. Restart the Chrome extension after starting Helper.

Symptoms: A command you expect to work is rejected.

  • The command may not be on the allowlist. Helper uses a strict allowlist; only explicitly permitted command prefixes are accepted.
  • Check for hidden shell metacharacters (;, &&, backticks) in the command string.
  • Verify your session’s permission level matches the command requirements (for example, kubectl rollout restart requires Limited or Full permissions, not Read-Only).

Symptoms: Commands are rejected after rapid successive execution.

The default limit is 15 commands per minute per session. Wait a few seconds for the sliding window to advance, or increase the limit with --rate-limit-per-minute.

Symptoms: Helper fails to start with “Failed to bind” error.

Terminal window
# Check what is using port 9876
lsof -i :9876 # macOS/Linux
netstat -ano | findstr :9876 # Windows

Use --port to select a different port if needed.

Symptoms: Commands fail with a session expired error.

Sessions expire after their configured duration (default: 60 minutes). The Chrome extension handles session renewal automatically. If you encounter this issue, reload the Overwatch page to establish a new session.

Symptoms: Command output appears incomplete.

Helper truncates output at 1 MB. For commands that produce very large output, add filters via pipes (for example, kubectl get pods -A | grep CrashLoop) to reduce the output volume before capture.

  • In-App Help: Press ? for keyboard shortcuts and contextual help
  • Troubleshooting: See Common Issues
  • Support: Contact your system administrator

Last updated: February 2026 | Edit this page