npm package: @gilangjavier/grafctl
Description: CLI tool for Grafana operations
Latest version: 0.1.0

# @gilangjavier/grafctl

[![npm](https://img.shields.io/npm/v/@gilangjavier/grafctl.svg)](https://www.npmjs.com/package/@gilangjavier/grafctl)
[![GitHub](https://img.shields.io/badge/GitHub-gilangjavier%2Fgrafctl-blue)](https://github.com/gilangjavier/grafctl)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

CLI tool for Grafana with token optimization for AI agents.

## Token Savings

| Operation | Standard API | grafctl | Savings |
|-----------|--------------|---------|---------|
| Dashboards list | ~4,500 tokens | ~800 tokens | 82% |
| Dashboard export | ~8,000 tokens | ~1,200 tokens | 85% |
| Datasources list | ~2,800 tokens | ~500 tokens | 82% |
| Datasource health | ~1,500 tokens | ~300 tokens | 80% |
| Alerts list | ~3,500 tokens | ~650 tokens | 81% |
| Alerts pause/unpause | ~1,200 tokens | ~250 tokens | 79% |
| Folders list | ~2,200 tokens | ~400 tokens | 82% |
| **Average** | | | **82%** |

## For AI Agents

### Installation (Ephemeral)

```bash
npx @gilangjavier/grafctl <command>
```

No installation required. Runs directly via npx.

### Quick Commands

```bash
# List all dashboards
npx @gilangjavier/grafctl dashboards list

# List dashboards in a specific folder
npx @gilangjavier/grafctl dashboards list --folder <folder-id>

# Filter dashboards by tags
npx @gilangjavier/grafctl dashboards list --tags "prod,monitoring"

# Export a dashboard by UID
npx @gilangjavier/grafctl dashboards export <uid>

# Export dashboard to file
npx @gilangjavier/grafctl dashboards export <uid> --file dashboard.json

# Import a dashboard from file
npx @gilangjavier/grafctl dashboards import dashboard.json

# List all datasources
npx @gilangjavier/grafctl datasources list

# Check datasource health
npx @gilangjavier/grafctl datasources health <datasource-id>

# List all alert rules
npx @gilangjavier/grafctl alerts list

# Filter alerts by state
npx @gilangjavier/grafctl alerts list --state alerting

# Pause an alert rule
npx @gilangjavier/grafctl alerts pause <alert-uid>

# Unpause an alert rule
npx @gilangjavier/grafctl alerts unpause <alert-uid>

# List all folders
npx @gilangjavier/grafctl folders list

# Create a new folder
npx @gilangjavier/grafctl folders create "My Folder"

# Check Grafana health
npx @gilangjavier/grafctl health

# Show current config
npx @gilangjavier/grafctl config
```

### Expected Behavior

**Exit Codes:**
- `0` - Success
- `1` - Error (connection failed, invalid input, config missing)

**Output Format:**
- Default: Human-readable tables
- `--format json` or `-o json`: Structured JSON for programmatic use

**Profile Selection:**
- `-p, --profile <name>` - Use specific profile from config

**Cache Control:**
- `--no-cache` - Disable ETag caching for fresh data

### Before/After Token Comparison

**Before (direct Grafana API calls):**
```
Raw JSON response with metadata, nested objects, extensive dashboard JSON
~4,500 tokens for a typical dashboards list response
~8,000+ tokens for dashboard export with full panel definitions
```

**After (grafctl):**
```
Clean table output with essential data only (uid, title, folder, url)
~800 tokens for the same dashboards list
~1,200 tokens for dashboard export with curated output
```

## For Humans

### Installation

```bash
npm install -g @gilangjavier/grafctl
```

### Setup Profile

Initialize configuration:

```bash
grafctl init
```

This creates `~/.config/grafctl/profiles.yaml` with a sample profile. Edit it:

```yaml
profiles:
  default:
    url: http://localhost:3000
    token_env: GRAFANA_TOKEN    # Use env var
    # OR
    token_file: /path/to/token  # Read from file
    # OR
    token: "api-key-here"       # Inline (not recommended)
```

Token priority (highest first):
1. `token_env` - Environment variable name
2. `token_file` - Path to file containing token
3. `token` - Inline token string

### All Available Commands

| Command | Description | Options |
|---------|-------------|---------|
| `grafctl init` | Create sample config | `--force` to overwrite |
| `grafctl config` | Show current config | `-p, --profile` |
| `grafctl dashboards list` | List dashboards | `--folder <id>`, `--tags <tags>` |
| `grafctl dashboards export <uid>` | Export dashboard JSON | `--file <path>` to save |
| `grafctl dashboards import <file>` | Import dashboard from file | |
| `grafctl datasources list` | List datasources | `-p, --profile` |
| `grafctl datasources health <id>` | Check datasource health | `-p, --profile` |
| `grafctl alerts list` | List alert rules | `--state <state>` |
| `grafctl alerts pause <uid>` | Pause an alert rule | `-p, --profile` |
| `grafctl alerts unpause <uid>` | Unpause an alert rule | `-p, --profile` |
| `grafctl folders list` | List folders | `-p, --profile` |
| `grafctl folders create <title>` | Create a folder | `-p, --profile` |
| `grafctl health` | Check Grafana health | `-p, --profile` |

Global flags available for all commands:
- `-p, --profile <name>` - Use specific profile
- `-o, --format <format>` - Output format: `table` or `json`
- `--no-cache` - Disable ETag caching

### Common Workflows

**List and filter dashboards:**
```bash
# All dashboards
grafctl dashboards list

# Dashboards in a specific folder
grafctl dashboards list --folder 123

# Dashboards with specific tags
grafctl dashboards list --tags "production,infra"
```

**Export and backup dashboards:**
```bash
# Export single dashboard
grafctl dashboards export abc123xyz --file my-dashboard.json

# Export all dashboards (script)
for uid in $(grafctl dashboards list --format json | jq -r '.[].uid'); do
  grafctl dashboards export "$uid" --file "backup/${uid}.json"
done
```

**Migrate dashboards between instances:**
```bash
# Export from source
grafctl -p source dashboards export <uid> --file dash.json

# Import to target
grafctl -p target dashboards import dash.json
```

**Check datasource health:**
```bash
# List datasources to get IDs
grafctl datasources list

# Check specific datasource health
grafctl datasources health 5
```

**Manage alert rules during maintenance:**
```bash
# List active alerts
grafctl alerts list --state alerting

# Pause an alert before maintenance
grafctl alerts pause <alert-uid>

# Perform maintenance...

# Unpause after maintenance
grafctl alerts unpause <alert-uid>
```

**Organize with folders:**
```bash
# List existing folders
grafctl folders list

# Create new folder
grafctl folders create "Team Metrics"
```

## Token Optimization Details

### Filtering

grafctl implements intelligent filtering to reduce data volume:

| Filter | Description |
|--------|-------------|
| `--folder` | Filter dashboards by folder ID |
| `--tags` | Filter dashboards by comma-separated tags |
| `--state` | Filter alerts by state (normal, alerting, pending, no_data) |
| Column selection | Only essential columns displayed in table mode |

### Caching (ETag)

grafctl implements HTTP ETag caching to reduce redundant API calls:

1. **Conditional requests** - Uses `If-None-Match` header with stored ETags
2. **304 responses** - Returns cached data when content has not changed
3. **Per-profile cache** - Cache keys include profile name for isolation

Benefits:
- Reduced network latency on repeated calls
- Lower token consumption for unchanged data
- Automatic cache invalidation when Grafana state changes

To bypass cache for fresh data:
```bash
grafctl dashboards list --no-cache
```

### Deterministic Output

grafctl produces consistent, predictable output:

| Component | Standard Response | grafctl Output |
|-----------|-------------------|----------------|
| HTTP headers | Full headers | Stripped |
| JSON metadata | `status`, `data`, nested objects | Direct values |
| Dashboard JSON | Full panel definitions, templating | Essential fields only |
| Timestamps | Unix milliseconds, mixed formats | Consistent ISO8601 |
| Alert rules | Full query definitions | Status, summary, labels |
| Datasource config | Credentials, secure JSON | Basic info only |
| Empty arrays | Included | Omitted from tables |
| Error messages | Verbose stack traces | Clean error messages |

Output is sorted and formatted consistently across runs for reliable parsing.

## Contributing

### For AI Agents

To suggest improvements or test changes:

1. Review the codebase structure in `src/`
2. Identify optimization opportunities
3. Document findings in GitHub issues:
   ```
   https://github.com/gilangjavier/grafctl/issues
   ```

### For Humans

**Development Setup:**

```bash
# Clone the repository
git clone https://github.com/gilangjavier/grafctl.git
cd grafctl

# Install dependencies
npm install

# Build TypeScript
npm run build

# Run tests
npm test

# Run in development mode
npm run dev -- dashboards list
```

**Submitting Changes:**

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/my-change`
3. Make changes and add tests
4. Run the test suite: `npm test`
5. Commit with clear messages
6. Push and open a Pull Request

**Reporting Issues:**

- [GitHub Issues](https://github.com/gilangjavier/grafctl/issues)

Include:
- grafctl version (`grafctl --version`)
- Node.js version (`node --version`)
- Grafana version
- Steps to reproduce
- Expected vs actual output

## License

MIT - See [LICENSE](LICENSE) file for details.