CLI Reference
@kill-switch/cli — monitor cloud spending, kill runaway services, and cap coding-agent spend from the terminal. Designed for both developers and AI agents.
Install
# From npm
npm install -g @kill-switch/cli
# From source
git clone https://github.com/divinci-ai/kill-switch.git
cd kill-switch/packages/cli
npm install && npm run build
npm link # makes `kill-switch` and `ks` available globally
kill-switch command can also be run as ks. For example: ks onboard, ks check, ks accounts list.
Quick Start
# 1. Authenticate (browser device flow — or pass --api-key)
ks auth setup
# 2. One-command setup (connects provider + applies shields + sets up alerts)
ks onboard --provider cloudflare \
--account-id YOUR_ACCOUNT_ID \
--token YOUR_API_TOKEN \
--name "Production" \
--shields cost-runaway,ddos \
--alert-email you@example.com
# 3. Run a monitoring check
ks check
# 4. View results
ks accounts list
Authentication
The CLI authenticates with personal API keys (prefixed with ks_) or a browser device flow. Create a key from the web dashboard at app.kill-switch.net (Settings → API Keys), or via the API.
ks auth setup
Authenticate via your browser (opens a one-time approval page). Add --manual to open the Settings page and paste a key yourself instead.
ks auth login [--api-key KEY]
Authenticate. Uses the browser device flow by default; pass --api-key ks_… for a direct, non-interactive login. Saves to ~/.kill-switch/config.json (0600 permissions).
ks auth status
Show current auth status, account name, and tier.
ks auth logout
Clear stored credentials.
Auth Resolution Order
KILL_SWITCH_API_KEYenvironment variable (best for CI/CD and AI agents)--api-keyflag on any command~/.kill-switch/config.jsonfile (set byks auth login/ks auth setup)
Onboard (One-Command Setup)
The fastest way to get protected. Connects a cloud provider, applies shield presets, and configures alerts — all in a single command. Designed for both humans and AI agents. (ks setup is an alias for ks onboard.)
ks onboard --help-provider cloudflare to get exact instructions for obtaining credentials.
# Interactive onboarding (prompts for each value)
ks onboard
# Non-interactive: connect Cloudflare (for AI agents like Claude Code)
ks onboard \
--provider cloudflare \
--account-id 14a6fa23390363382f378b5bd4a0f849 \
--token your-cf-api-token \
--name "Production" \
--shields cost-runaway,ddos \
--alert-email you@example.com
# Connect AWS
ks onboard \
--provider aws \
--access-key AKIA... \
--secret-key wJalr... \
--region us-east-1 \
--shields aws-cost-runaway,gpu-runaway
# Connect GCP
ks onboard \
--provider gcp \
--project-id my-project-123 \
--service-account "$(cat service-account-key.json)" \
--shields cost-runaway
# Connect RunPod
ks onboard \
--provider runpod \
--runpod-api-key "YOUR_RUNPOD_API_KEY" \
--shields cost-runaway,gpu-runaway
# Connect Neo4j Aura
ks onboard \
--provider neo4j \
--neo4j-client-id "YOUR_CLIENT_ID" \
--neo4j-client-secret "YOUR_CLIENT_SECRET" \
--shields cost-runaway
# Connect MongoDB Atlas
ks onboard \
--provider mongodb \
--mongodb-subtype atlas \
--atlas-public-key "YOUR_PUBLIC_KEY" \
--atlas-private-key "YOUR_PRIVATE_KEY" \
--atlas-project-id "YOUR_PROJECT_ID" \
--shields cost-runaway
# Show how to get credentials for a provider
ks onboard --help-provider cloudflare
ks onboard --help-provider aws
ks onboard --help-provider gcp
ks onboard --help-provider runpod
ks onboard --help-provider neo4j
ks onboard --help-provider mongodb
Onboard Options
| Flag | Description |
|---|---|
--provider | Cloud provider: cloudflare, gcp, aws, runpod, neo4j, mongodb |
--name | Account name (e.g., "Production") |
--help-provider | Show how to get credentials for a provider |
| Cloudflare | |
--token | API token (must be an API Token, not Global Key) |
--account-id | Account ID (from the dashboard URL bar) |
| GCP | |
--project-id | Project ID |
--service-account | Service Account JSON |
| AWS | |
--access-key | Access Key ID |
--secret-key | Secret Access Key |
--region | Region (default: us-east-1) |
| RunPod | |
--runpod-api-key | API Key |
| Neo4j Aura | |
--neo4j-client-id | Client ID |
--neo4j-client-secret | Client Secret |
--neo4j-instance-id | Instance ID (optional) |
| MongoDB | |
--mongodb-subtype | atlas or self-hosted |
--atlas-public-key | Atlas API public key |
--atlas-private-key | Atlas API private key |
--atlas-project-id | Atlas project ID |
--atlas-cluster-name | Atlas cluster name (optional) |
--mongodb-uri | Connection URI (self-hosted) |
--mongodb-database | Database name (self-hosted, optional) |
| Protection & alerts | |
--shields | Comma-separated presets (default: cost-runaway) |
--alert-pagerduty | PagerDuty routing key (recommended) |
--alert-email | Email for alerts |
--alert-discord | Discord webhook URL |
--alert-slack | Slack webhook URL |
--skip-shields | Skip applying protection rules |
--skip-alerts | Skip alert setup |
Shield (Quick Protect)
The fastest way to add protection. One command applies a preset rule.
# Apply cost runaway protection
ks shield cost-runaway
# List all available shields
ks shield --list
# Preview without applying
ks shield gpu-runaway --dry-run
# Apply with JSON output (for automation)
ks shield gpu-runaway --json
Available Shields
| Preset | Name | Category |
|---|---|---|
cost-runaway | Cost Runaway Protection | Cost |
gpu-runaway | GPU Instance Runaway | Cost |
lambda-loop | Lambda Recursive Loop | Cost |
aws-cost-runaway | AWS Daily Cost Runaway | Cost |
ddos | DDoS Protection | Security |
brute-force | Brute Force Protection | Security |
exfiltration | Data Exfiltration Detection | Security |
error-storm | Error Storm Protection | Reliability |
Cloud Accounts
ks accounts list
List all connected cloud accounts with provider, name, and status. Filter with --provider or --status.
ks accounts get <id>
Show detailed account info including thresholds and last check results.
ks accounts add <provider> --name "My Account"
Connect a provider. Supported: cloudflare, gcp, aws, runpod, mongodb, redis, neo4j, and more. Named flags mirror each provider's credentials; --cred key=value (repeatable) and --credential-json are generic escape hatches for any field.
# Connect Cloudflare
ks accounts add cloudflare \
--name "Production" \
--token "your-cf-api-token" \
--account-id "your-account-id"
# Connect MongoDB Atlas
ks accounts add mongodb \
--name "Prod Atlas" \
--atlas-public-key PUB --atlas-private-key PRIV \
--atlas-project-id PROJ --atlas-cluster-name my-cluster
# Redis Cloud / Neo4j Aura
ks accounts add redis --name "Redis Cloud" --redis-cloud-key K --redis-cloud-secret S --redis-subscription-id ID
ks accounts add neo4j --name "Aura" --neo4j-client-id ID --neo4j-client-secret SECRET
ks accounts update <id>
Change thresholds and auto-actions after connecting: --threshold key=value (repeatable), --auto-disconnect, --auto-delete, --autokill-categories, --status, and --production-protected. Managed databases are production-protected by default — destructive actions (pause-cluster, delete) are never auto-executed; a breach is downgraded to a forensic snapshot + alert. Set --production-protected false to opt in to auto-pause/delete.
ks accounts check <id>
Run a manual monitoring check on a specific account.
ks accounts delete <id>
Disconnect and delete a cloud account and its stored credentials.
Integration-as-Code (ks apply)
Declare an integration in a version-controlled YAML or JSON file and reconcile it idempotently — no hand-rolled scripts. Secrets stay in the environment via ${ENV} interpolation. Re-running converges and reports each change as + create / ~ update / = unchanged.
ks apply -f <file> [--dry-run]
Find-or-create the account, apply thresholds/flags, apply shields, and ensure alert channels. --dry-run previews the plan without writing.
# ks.yaml — apply with: ks apply -f ks.yaml
account:
provider: mongodb
name: Production Atlas
credential: # only needed to create; ${ENV} interpolated
mongodbSubType: atlas
atlasPublicKey: ${ATLAS_PUBLIC_KEY}
atlasPrivateKey: ${ATLAS_PRIVATE_KEY}
atlasProjectId: ${ATLAS_PROJECT_ID}
atlasClusterName: prod-cluster0
thresholds: { mongodbDailyCostUSD: 40, monthlySpendLimitUSD: 1200 }
protectedServices: [prod-cluster0]
productionProtected: true
shields: [cost-runaway]
alerts:
- { type: pagerduty, routingKey: ${PD_ROUTING_KEY}, name: On-Call }
Diagnostics (ks doctor)
ks doctor
One-stop health check: API URL, API key, authentication, active org (name, role, count), connectivity, accounts, and alert channels — each reported ✓/⚠/✗ with a remediation hint. Exits non-zero on hard failures (CI-friendly). Because accounts/rules/alerts are scoped to your active org, ks doctor (and the org banner in ks status / ks accounts list) makes it obvious when something you expect is simply in another org — switch with ks orgs switch <id>.
Monitoring
ks check
Run monitoring checks on all connected accounts. Shows violations and actions taken.
$ ks check
Checked 2 account(s) — 1 violation(s)
✓ cloudflare Production CF
✗ gcp GCP Staging
Service Metric Current Threshold Over Severity
─────────────────────────────────────────────────────────────────────────────
BigQuery monthlySpend $523 $500 1x warning
Actions: scale-down
ks watch [--interval 60]
Continuously monitor all accounts, polling on an interval (default: 60 seconds). Ctrl-C to stop.
Rules
ks rules list
List kill switch rules. Filter with --trigger (cost, security, custom, api, agent), --enabled, or --disabled.
ks rules presets
List available preset rule templates.
ks rules create <name> --trigger <type>
Create a custom rule. Trigger types: cost, security, api. Pass --condition / --action JSON, or --dry-run to preview.
ks rules toggle <id>
Enable or disable a rule.
ks rules delete <id>
Delete a rule permanently.
Database Kill Switch
Multi-step database kill sequences: snapshot → verify → isolate → nuke. Each step is an explicit command — no interactive prompts.
# Initiate a kill sequence
ks kill init \
--credential-id "cred_abc123" \
--trigger "credential compromise detected"
# Check status (omit id to list all active)
ks kill status dbkill-xyz789
# Advance to next step
ks kill advance dbkill-xyz789 --credential-id "cred_abc123"
# Final step (nuke) requires human approval
ks kill advance dbkill-xyz789 \
--credential-id "cred_abc123" \
--human-approval
# Abort if needed
ks kill abort dbkill-xyz789
Alerts
ks alerts list
List configured alert channels with type, name, enabled status, and masked config preview.
ks alerts add --type TYPE [options]
Add an alert channel. Supported types: pagerduty, slack, discord, email, webhook, github.
ks alerts remove <name>
Remove an alert channel by name.
ks alerts test
Send a test alert to all configured and enabled channels.
# PagerDuty (recommended — immediate on-call paging)
ks alerts add --type pagerduty --routing-key YOUR_ROUTING_KEY --name "On-Call"
# Slack or Discord webhook
ks alerts add --type slack --webhook-url https://hooks.slack.com/...
ks alerts add --type discord --webhook-url https://discord.com/api/webhooks/...
# GitHub AI Remediation — triggers Claude Code to open a fix PR on extreme violations
ks alerts add --type github \
--token ghp_YOUR_PAT \
--repo-owner YOUR_ORG \
--repo-name YOUR_REPO \
--workflow kill-switch-remediate.yml \
--branch main
# Email or generic webhook
ks alerts add --type email --email you@example.com
ks alerts add --type webhook --webhook-url https://your-service.example.com/webhook
# Remove and test
ks alerts remove "PagerDuty"
ks alerts test
Agent Guard (ks guard)
Kill Switch for coding agents — stop a runaway Claude Code / Cursor / Aider session from racking up an LLM bill. ks guard is the same engine as the standalone @kill-switch/agent-guard binary (agent-guard / ksg) — they share one ledger, budget, and escape hatch.
/usage — from the JSON Claude Code pipes to your statusLine (rate_limits.five_hour and rate_limits.seven_day). That's the primary source and it's documented: no network call, no credential read, and it can't be rate-limited. ks guard usage is the fallback — it hits Anthropic's undocumented usage endpoint for the per-model weekly (Sonnet/Opus) that stdin doesn't carry, at most hourly and backing off when the endpoint rate-limits. The hook warns you in-session before you lock out. It's pace-aware: it measures you against a daily budget (your weekly cap ÷ 7 ≈ 14%/day), so 60% used with two days left stays quiet — it warns only when you're at or above that pace, or projected to lock out before the reset. This is alert-only — it never blocks a plan you've already paid for. (The token is read from your OS credential store and only ever sent to Anthropic; it's never logged or stored.)
agent-guard statusline as your Claude Code statusLine to keep a live 🛡 🟢 12%5h · 17%w · 9%d · 5.0wd in the bar:
{ "statusLine": { "type": "command", "command": "agent-guard statusline" } }
This is also how agent-guard gets your limits: Claude Code hands the status bar a JSON payload containing rate_limits, so every render refreshes the numbers the in-session warnings pace against — with no network call and nothing to rate-limit. Two caveats, both by design: rate_limits appears only for Pro/Max subscribers and only after the first API response of a session, and it carries no per-model breakdown — so if a per-model weekly is your tighter limit (say 56% while your all-models weekly is 31%), use ks guard usage to see it.
🛡 ⚪ limits stale (…), is never graded into a warning colour, and never fires a pacing nudge.
🛡 🟢 12%5h · 17%w · 9%d · 5.0wd:
12%5h— the 5-hour window used17%w— the weekly (7-day) window used9%d— your average daily burn: weekly used ÷ days elapsed this week. Read it against your daily budget (weekly cap ÷ 7 ≈ 14%/day) — under ~14%/day means you're pacing fine.5.0wd— weekly days left: days until the weekly window resets
ks guard install [--global]
Wire the agent-guard hook into Claude Code settings. Defaults to ./.claude/settings.json; pass --global to install into ~/.claude/settings.json.
ks guard usage [--json]
Fetch your real Claude Code plan limits from Anthropic's /api/oauth/usage endpoint — the 5-hour window, weekly (all-models), and per-model weekly (Sonnet/Opus), with reset times. No proxy and no workflow change. Reads your OAuth token from the macOS Keychain (Claude Code-credentials) or ~/.claude/.credentials.json; the token is only sent to Anthropic and never logged or stored. The endpoint is undocumented, so it fails soft (falls back to the proxy / “unknown”).
🟢 Claude Code plan limits · observed just now
[██░░░░░░░░░░░░░░░░░░] 5-hour limit 12% used, resets 9:19 AM
[███░░░░░░░░░░░░░░░░░] weekly limit 17% used, resets Tue 7:59 PM, ~83% left over 5.0d (~17%/day vs ~14%/day budget)
[░░░░░░░░░░░░░░░░░░░░] weekly · Sonnet 1%
ks guard status [--json]
Show current session + daily agent spend against the budget — and, on a Pro/Max subscription, your real Claude Code plan limits (auto-refreshed from the usage endpoint, throttled). Your plan tier is auto-detected from ~/.claude.json; pin it with --plan if you prefer.
ks guard config [options]
View or set budget caps (USD) and Claude Code plan limits.
| Flag | Description |
|---|---|
--session-soft <usd> | Per-session soft cap (warn) |
--session-hard <usd> | Per-session hard cap (block) |
--daily-soft <usd> | Daily rolling soft cap (warn) |
--daily-hard <usd> | Daily rolling hard cap (block) |
--slack-webhook <url> | Slack incoming-webhook for breach alerts |
--plan <tier> | Claude Code plan: auto (auto-detected from ~/.claude.json) | pro | max5 | max20. Real 5h/weekly percentages come from the proxy; without it, status shows the detected tier + absolute cost. |
--weekly-soft <pct> / --weekly-danger <pct> | Weekly limit warn / danger thresholds (0–1 utilization) |
--5h-soft <pct> / --5h-danger <pct> | 5-hour limit warn / danger thresholds (0–1 utilization) |
--burn-ratio <n> | Burn-rate multiplier (actual vs. sustainable pace) that triggers a warning |
ks guard pause [--minutes N]
Temporarily disable enforcement (escape hatch). Auto-resumes after N minutes, or stays paused indefinitely. The escape hatch always belongs to the human, never the agent.
ks guard resume
Re-arm enforcement after a pause.
ks guard reset [--all | --limits | --session ID | --today]
Clear the agent spend ledger — all sessions, a single session, or just today's. --limits clears the subscription detection latch + last snapshot (re-arming the dollar wall); --all clears both.
ks guard proxy [options]
Start the token-metering proxy (HTTP 402 at the hard cap) for non-Claude-Code agents. On the anthropic flavor it also reads anthropic-ratelimit-unified-* headers, so running Claude Code through it enables subscription plan-limit pacing (alert-only).
| Flag | Description |
|---|---|
--port <n> | Port to listen on (default: 8787) |
--flavor <name> | API flavor: anthropic | openai (default: anthropic) |
--upstream <url> | Upstream origin (default: api.anthropic.com / api.openai.com) |
# Cap a Claude Code session (dollars — API-key usage)
ks guard install
ks guard config --session-hard 30 --daily-hard 150
ks guard status
# Pro/Max subscription? See your REAL plan limits (no proxy, alert-only)
ks guard usage # 5-hour + weekly + per-model (Sonnet/Opus), with resets
ks guard status # same, auto-refreshed; tier auto-detected from ~/.claude.json
# Hard 402 wall for any other agent (Cursor, Aider, raw scripts)
ks guard proxy --flavor openai --port 8787
# then point the agent at it:
export OPENAI_BASE_URL=http://localhost:8787
# Escape hatch (human only)
ks guard pause --minutes 30
ks guard resume
Organizations
Multi-org support for team and enterprise tiers. Scope any command to an org with the active selection (ks orgs switch) or the X-Org-Id header via the API.
ks orgs list
List organizations you belong to.
ks orgs create <name>
Create a new organization (requires team/enterprise tier).
ks orgs switch <orgId>
Switch the active organization for subsequent commands.
ks orgs info [orgId]
Get organization details.
ks orgs members
List team members in the current organization.
ks orgs invite <email> [--role admin|member|viewer]
Invite a member to the current organization (default role: member).
ks orgs delete <orgId>
Delete an organization (owner only; cannot delete your personal workspace).
Activity Log
Audit trail of every mutation — account connects, rule changes, kill sequences, team changes. Available on team/enterprise tiers.
ks activity
Show recent activity (last 10 entries).
ks activity list [filters]
Query the activity log (owner/admin only).
| Flag | Description |
|---|---|
--page <n> | Page number (default: 1) |
--limit <n> | Results per page, max 100 (default: 25) |
--action <prefix> | Filter by action prefix (e.g., cloud_account, rule, team, kill_switch) |
--resource-type <type> | Filter by resource type |
--actor <userId> | Filter by actor user ID |
--from <date> | Start date (ISO format) |
--to <date> | End date (ISO format) |
Providers
Inspect supported cloud providers and validate credentials before connecting.
ks providers list
List supported cloud providers.
ks providers validate <provider> [creds]
Validate cloud provider credentials without connecting an account. Accepts the same credential flags as ks onboard (--token, --account-id, --project-id, --service-account, --access-key, --secret-key, --region, --runpod-api-key).
# Validate a Cloudflare token before connecting
ks providers validate cloudflare \
--token your-cf-api-token \
--account-id your-account-id
Status Dashboard
ks status
Mini-dashboard: plan tier, connected accounts, enabled rules, alert channels, and 30-day spend summary — all in one command.
$ ks status
Kill Switch Status
Plan: pro
Accounts: 2 active / 10 max
Rules: 3 enabled
Kill seqs: none
Alerts: 1 channel(s) — pagerduty
Spend (30d): $55.00 · $12.00 saved · 2 action(s) taken
Connected Accounts:
Provider Name Status Last Check
──────────────────────────────────────────────────────────────────
cloudflare Production CF active ok
aws AWS Dev active ok
Alert Channels:
Type Name Enabled Config
──────────────────────────────────────────────────────────────────
pagerduty On-Call true ****abcd
Analytics
ks analytics [--days 30]
FinOps overview: total spend, daily average, projected monthly cost, savings from kill-switch actions, and per-account cost breakdown.
$ ks analytics
Analytics Overview
Total spend: $123.45
Avg daily cost: $4.11
Projected monthly: $127.00
Savings estimate: $38.20
Kill switch actions: 3
Last 7 Days:
Date Cost (USD) Services Violations
──────────────────────────────────────────────────
2026-03-30 3.5 5 0
2026-03-31 5.2 6 1
Account Breakdown:
Provider Total Cost Avg Daily
──────────────────────────────────────
cloudflare 80 2.67
aws 43.45 1.44
Configuration
ks config init
Create ~/.kill-switch/config.json with defaults.
ks config list
Show all config values. The API key is masked (in both table and --json output); pass --reveal to print it in full.
ks config get <key>
Get a single config value. Secret values (e.g. apiKey) are masked unless you pass --reveal.
ks config set <key> <value>
Set a config value. Keys: apiKey, apiUrl.
Global Options
| Flag | Description |
|---|---|
--json | Output raw JSON to stdout (for automation, piping, AI agents) |
--api-key <key> | Override API key for this command |
--api-url <url> | Override API URL (default: https://api.kill-switch.net) |
-y, --yes | Skip confirmation prompts (for non-interactive / agent use) |
-V, --version | Show version number |
-h, --help | Show help |
AI Agent Usage
The CLI is designed to be used by AI coding agents (Claude Code, Cursor, Windsurf, etc.) to set up cloud cost protection on behalf of users — no manual steps required.
-y). All output is parseable with --json. Exit codes are deterministic (0=success, 1=error, 2=auth error). Use --help-provider to discover how to obtain credentials.
Full Agent Workflow
An AI agent can set up Kill Switch monitoring in a few steps:
# Step 1: Authenticate (user provides their API key, or set env var)
export KILL_SWITCH_API_KEY=ks_live_your_key
# Step 2: Discover how to get credentials for the user's provider
ks onboard --help-provider cloudflare --json
# Agent reads the instructions and helps user create the right token
# Step 3: Connect the provider with one command
ks onboard \
--provider cloudflare \
--account-id USER_CF_ACCOUNT_ID \
--token USER_CF_API_TOKEN \
--name "Production" \
--shields cost-runaway,ddos,error-storm \
--alert-pagerduty ROUTING_KEY \
--json
# Step 4: Add additional alert channels as needed
ks alerts add --type pagerduty --routing-key ROUTING_KEY --json
ks alerts add --type slack --webhook-url https://hooks.slack.com/... --json
# Step 5: Verify full status
ks status --json
Claude Code / CLAUDE.md Integration
Add this to your project's CLAUDE.md to let Claude Code manage Kill Switch for you:
# In your project's CLAUDE.md:
## Kill Switch (Cloud Cost Protection)
- CLI: `ks` (alias for `kill-switch`)
- Auth: KILL_SWITCH_API_KEY env var or `ks auth login --api-key KEY`
- Setup: `ks onboard --provider cloudflare --account-id ID --token TOKEN`
- Check: `ks check --json`
- Credential help: `ks onboard --help-provider cloudflare`
- Cap my own agent spend: `ks guard install && ks guard config --daily-hard 150`
Non-Interactive Commands for Agents
# All commands work with --json for machine-readable output
ks accounts list --json
ks shield cost-runaway --json
ks check --json
ks rules list --json
ks analytics --json
ks guard status --json
# Parse JSON output
ks check --json | jq '.results[].violations | length'
Environment Variables
| Variable | Description |
|---|---|
KILL_SWITCH_API_KEY | API key (overrides the config file) |
KILL_SWITCH_API_URL | API URL override (default: https://api.kill-switch.net) |
Exit Codes
| Code | Meaning |
|---|---|
0 | Success |
1 | Client error (bad arguments, API error) |
2 | Authentication error (invalid/missing API key) |
See Also
- API Reference (OpenAPI 3.1)
- Integration Guide (Edge Agent, Spend Guard, Alerting)
@kill-switch/cli&@kill-switch/agent-guardon npm- GitHub Repository