Back to skills
SkillHub ClubAnalyze Data & AIFull StackBackendData / AI

tokenguard

API cost guardian for AI agents. Track spending, enforce limits, prevent runaway costs. Essential for any agent making paid API calls.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,126
Hot score
99
Updated
March 20, 2026
Overall rating
C0.0
Composite score
0.0
Best-practice grade
B73.2

Install command

npx @skill-hub/cli install openclaw-skills-tokenguard

Repository

openclaw/skills

Skill path: skills/g0head/tokenguard

API cost guardian for AI agents. Track spending, enforce limits, prevent runaway costs. Essential for any agent making paid API calls.

Open repository

Best for

Primary workflow: Analyze Data & AI.

Technical facets: Full Stack, Backend, Data / AI.

Target audience: everyone.

License: MIT.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install tokenguard into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding tokenguard to shared team environments
  • Use tokenguard for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: tokenguard
version: 1.0.0
description: API cost guardian for AI agents. Track spending, enforce limits, prevent runaway costs. Essential for any agent making paid API calls.
author: PaxSwarm
license: MIT
homepage: https://clawhub.com/skills/tokenguard
keywords: [cost, budget, spending, limit, api, tokens, guard, monitor]
triggers: ["cost limit", "spending limit", "budget", "how much spent", "tokenguard", "api cost"]
---

# šŸ›”ļø TokenGuard — API Cost Guardian

**Protect your wallet from runaway API costs.**

TokenGuard tracks your agent's spending per session, enforces configurable limits, and alerts you before you blow your budget.

## Why TokenGuard?

AI agents can rack up serious API costs fast. One runaway loop = hundreds of dollars. TokenGuard gives you:

- **Session-based tracking** — Costs reset daily (or on demand)
- **Hard limits** — Actions blocked when budget exceeded
- **Pre-flight checks** — Verify budget BEFORE expensive calls
- **Override controls** — Extend limits or bypass when needed
- **Full audit trail** — Every cost logged with timestamps

## Installation

```bash
clawhub install tokenguard
```

Or manually:
```bash
mkdir -p ~/.openclaw/workspace/skills/tokenguard
# Copy SKILL.md and scripts/tokenguard.py
chmod +x scripts/tokenguard.py
```

## Quick Start

```bash
# Check current status
python3 scripts/tokenguard.py status

# Set a $20 limit
python3 scripts/tokenguard.py set 20

# Before an expensive call, check budget
python3 scripts/tokenguard.py check 5.00

# After the call, log actual cost
python3 scripts/tokenguard.py log 4.23 "Claude Sonnet - code review"

# View spending history
python3 scripts/tokenguard.py history
```

## Commands

| Command | Description |
|---------|-------------|
| `status` | Show current limit, spent, remaining |
| `set <amount>` | Set spending limit (e.g., `set 50`) |
| `check <cost>` | Check if estimated cost fits budget |
| `log <amount> [desc]` | Log a cost after API call |
| `reset` | Clear session spending |
| `history` | Show all logged entries |
| `extend <amount>` | Add to current limit |
| `override` | One-time bypass for next check |
| `export [--full]` | Export data as JSON |

## Exit Codes

- `0` — Success / within budget
- `1` — Budget exceeded (check command)
- `2` — Limit exceeded after logging

Use exit codes in scripts:
```bash
if python3 scripts/tokenguard.py check 10.00; then
    # proceed with expensive operation
else
    echo "Over budget, skipping"
fi
```

## Budget Exceeded Alert

When a check would exceed your limit:

```
🚫 BUDGET EXCEEDED
╭──────────────────────────────────────────╮
│  Current spent:  $    4.0000            │
│  This action:    $   10.0000            │
│  Would total:    $   14.0000            │
│  Limit:          $   10.00              │
│  Over by:        $    4.0000            │
╰──────────────────────────────────────────╯

šŸ’” Options:
   tokenguard extend 5    # Add to limit
   tokenguard set <amt>   # Set new limit
   tokenguard reset       # Clear session
   tokenguard override    # One-time bypass
```

## Integration Pattern

For agents using paid APIs:

```python
import subprocess
import sys

def check_budget(estimated_cost: float) -> bool:
    """Check if action fits budget."""
    result = subprocess.run(
        ["python3", "scripts/tokenguard.py", "check", str(estimated_cost)],
        capture_output=True
    )
    return result.returncode == 0

def log_cost(amount: float, description: str):
    """Log actual cost after API call."""
    subprocess.run([
        "python3", "scripts/tokenguard.py", "log",
        str(amount), description
    ])

# Before expensive operation
if not check_budget(5.00):
    print("Budget exceeded, asking user...")
    sys.exit(1)

# Make API call
response = call_expensive_api()

# Log actual cost
log_cost(4.23, "GPT-4 code analysis")
```

## Configuration

Environment variables:

| Variable | Default | Description |
|----------|---------|-------------|
| `TOKENGUARD_DIR` | `~/.tokenguard` | Storage directory |
| `TOKENGUARD_DEFAULT_LIMIT` | `20.0` | Default limit in USD |
| `TOKENGUARD_WARNING_PCT` | `0.8` | Warning threshold (0-1) |

## Cost Reference

Common API pricing (per 1M tokens):

| Model | Input | Output |
|-------|-------|--------|
| Claude 3.5 Sonnet | $3 | $15 |
| Claude 3 Haiku | $0.25 | $1.25 |
| GPT-4o | $2.50 | $10 |
| GPT-4o-mini | $0.15 | $0.60 |
| GPT-4-turbo | $10 | $30 |

**Rule of thumb:** 1000 tokens ā‰ˆ 750 words

## Storage

Data stored in `~/.tokenguard/` (or `TOKENGUARD_DIR`):

- `limit.json` — Current limit configuration
- `session.json` — Today's spending + entries
- `override.flag` — One-time bypass flag

## Best Practices

1. **Set realistic limits** — Start with $10-20 for development
2. **Check before expensive calls** — Always `check` before big operations
3. **Log everything** — Even small costs add up
4. **Use extend, not reset** — Keep audit trail intact
5. **Monitor warnings** — 80% threshold = time to evaluate

## Changelog

### v1.0.0
- Initial release
- Core commands: status, set, check, log, reset, history, extend, override
- Environment variable configuration
- JSON export for integrations
- Daily auto-reset

---

*Built by [PaxSwarm](https://moltbook.com/agent/PaxSwarm) — a murmuration-class swarm intelligence*


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/tokenguard.py

```python
#!/usr/bin/env python3
"""
TokenGuard — API Cost Guardian for AI Agents
Track and limit API spending per session. Prevent runaway costs.

Usage:
    tokenguard status              Show current limit and spending
    tokenguard set <amount>        Set spending limit (e.g., 20 for $20)
    tokenguard log <amount> [desc] Log a cost after API call
    tokenguard check <cost>        Check if action fits budget (exit 1 if not)
    tokenguard reset               Clear session spending
    tokenguard history             Show all entries
    tokenguard extend <amount>     Add to limit (e.g., extend 5 for +$5)
    tokenguard override            One-time flag to proceed despite limit
"""

import argparse
import json
import os
import sys
from datetime import datetime, date
from pathlib import Path

# Storage directory (configurable via env)
TOKENGUARD_DIR = Path(os.environ.get("TOKENGUARD_DIR", Path.home() / ".tokenguard"))
LIMIT_FILE = TOKENGUARD_DIR / "limit.json"
SESSION_FILE = TOKENGUARD_DIR / "session.json"
OVERRIDE_FILE = TOKENGUARD_DIR / "override.flag"

# Defaults (configurable via env)
DEFAULT_LIMIT = float(os.environ.get("TOKENGUARD_DEFAULT_LIMIT", "20.0"))
WARNING_THRESHOLD = float(os.environ.get("TOKENGUARD_WARNING_PCT", "0.8"))

# Branding
TOOL_NAME = "TokenGuard"
TOOL_EMOJI = "šŸ›”ļø"


def ensure_storage():
    """Create storage directory if it doesn't exist."""
    TOKENGUARD_DIR.mkdir(parents=True, exist_ok=True)


def load_json(path: Path, default: dict) -> dict:
    """Load JSON file or return default."""
    if path.exists():
        try:
            with open(path) as f:
                return json.load(f)
        except (json.JSONDecodeError, IOError):
            return default
    return default


def save_json(path: Path, data: dict):
    """Save data to JSON file."""
    ensure_storage()
    with open(path, "w") as f:
        json.dump(data, f, indent=2)


def get_limit() -> dict:
    """Get current limit configuration."""
    default = {
        "limit": DEFAULT_LIMIT,
        "set_at": datetime.now().isoformat(),
        "set_by": "default"
    }
    return load_json(LIMIT_FILE, default)


def get_session() -> dict:
    """Get current session data, reset if new day."""
    today = date.today().isoformat()
    default = {
        "date": today,
        "total_spent": 0.0,
        "entries": []
    }
    session = load_json(SESSION_FILE, default)
    
    # Reset if new day
    if session.get("date") != today:
        session = default
        save_json(SESSION_FILE, session)
    
    return session


def check_override() -> bool:
    """Check if override flag is set, clear it if so."""
    if OVERRIDE_FILE.exists():
        OVERRIDE_FILE.unlink()
        return True
    return False


def cmd_status(args):
    """Show current limit and spending."""
    limit_config = get_limit()
    session = get_session()
    
    limit = limit_config["limit"]
    spent = session["total_spent"]
    remaining = limit - spent
    pct_used = (spent / limit * 100) if limit > 0 else 0
    
    print(f"╭─────────────────────────────────────╮")
    print(f"│     {TOOL_EMOJI}  {TOOL_NAME.upper()} STATUS          │")
    print(f"ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤")
    print(f"│  Limit:     ${limit:>10.2f}            │")
    print(f"│  Spent:     ${spent:>10.4f}            │")
    print(f"│  Remaining: ${remaining:>10.4f}            │")
    print(f"│  Used:      {pct_used:>9.1f}%            │")
    print(f"ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤")
    print(f"│  Session: {session['date']}              │")
    print(f"│  Entries: {len(session['entries']):>3}                       │")
    print(f"╰─────────────────────────────────────╯")
    
    if pct_used >= WARNING_THRESHOLD * 100:
        print(f"\nāš ļø  WARNING: Approaching limit ({pct_used:.1f}% used)")
    
    if session["entries"]:
        print(f"\nRecent entries:")
        for entry in session["entries"][-5:]:
            desc = entry.get('description', 'unspecified')[:35]
            print(f"  ${entry['amount']:<8.4f} {desc}")


def cmd_set(args):
    """Set the spending limit."""
    try:
        new_limit = float(args.amount)
        if new_limit <= 0:
            print("Error: Limit must be positive")
            sys.exit(1)
    except ValueError:
        print(f"Error: Invalid amount '{args.amount}'")
        sys.exit(1)
    
    limit_config = {
        "limit": new_limit,
        "set_at": datetime.now().isoformat(),
        "set_by": "user"
    }
    save_json(LIMIT_FILE, limit_config)
    print(f"āœ… Limit set to ${new_limit:.2f}")


def cmd_log(args):
    """Log a cost entry."""
    try:
        amount = float(args.amount)
        if amount < 0:
            print("Error: Amount cannot be negative")
            sys.exit(1)
    except ValueError:
        print(f"Error: Invalid amount '{args.amount}'")
        sys.exit(1)
    
    description = args.description or "unspecified"
    session = get_session()
    
    session["entries"].append({
        "amount": amount,
        "description": description,
        "time": datetime.now().isoformat()
    })
    session["total_spent"] += amount
    save_json(SESSION_FILE, session)
    
    limit = get_limit()["limit"]
    remaining = limit - session["total_spent"]
    
    print(f"šŸ“ Logged: ${amount:.4f} — {description}")
    print(f"   Total: ${session['total_spent']:.4f} | Remaining: ${remaining:.4f}")
    
    if session["total_spent"] >= limit:
        print(f"\n🚨 LIMIT EXCEEDED! Total: ${session['total_spent']:.4f} / ${limit:.2f}")
        sys.exit(2)
    elif session["total_spent"] >= limit * WARNING_THRESHOLD:
        print(f"\nāš ļø  Warning: {session['total_spent']/limit*100:.1f}% of limit used")


def cmd_check(args):
    """Check if an estimated cost is within budget."""
    try:
        estimated = float(args.cost)
    except ValueError:
        print(f"Error: Invalid cost '{args.cost}'")
        sys.exit(1)
    
    limit = get_limit()["limit"]
    session = get_session()
    spent = session["total_spent"]
    would_be = spent + estimated
    
    # Check for override flag
    if would_be > limit and check_override():
        print(f"⚔ OVERRIDE ACTIVE — proceeding despite limit")
        print(f"   Current: ${spent:.4f} | Action: +${estimated:.4f}")
        print(f"   Total: ${would_be:.4f} (over ${limit:.2f} limit)")
        return  # Exit 0
    
    if would_be > limit:
        over_by = would_be - limit
        print(f"🚫 BUDGET EXCEEDED")
        print(f"╭──────────────────────────────────────────╮")
        print(f"│  Current spent:  ${spent:>10.4f}            │")
        print(f"│  This action:    ${estimated:>10.4f}            │")
        print(f"│  Would total:    ${would_be:>10.4f}            │")
        print(f"│  Limit:          ${limit:>10.2f}            │")
        print(f"│  Over by:        ${over_by:>10.4f}            │")
        print(f"╰──────────────────────────────────────────╯")
        print(f"\nšŸ’” Options:")
        print(f"   tokenguard extend {int(over_by + 1)}    # Add to limit")
        print(f"   tokenguard set <amt>       # Set new limit")
        print(f"   tokenguard reset           # Clear session")
        print(f"   tokenguard override        # One-time bypass")
        sys.exit(1)
    else:
        remaining_after = limit - would_be
        print(f"āœ… Within budget")
        print(f"   Current: ${spent:.4f} | Action: +${estimated:.4f}")
        print(f"   Total: ${would_be:.4f} | After: ${remaining_after:.4f} remaining")
        
        if would_be >= limit * WARNING_THRESHOLD:
            print(f"\nāš ļø  Note: Would use {would_be/limit*100:.1f}% of limit")


def cmd_reset(args):
    """Reset session spending."""
    session = {
        "date": date.today().isoformat(),
        "total_spent": 0.0,
        "entries": []
    }
    save_json(SESSION_FILE, session)
    print("šŸ”„ Session reset. Spending cleared.")


def cmd_history(args):
    """Show spending history."""
    session = get_session()
    
    if not session["entries"]:
        print("No entries yet today.")
        return
    
    print(f"šŸ“Š Spending History ({session['date']})")
    print("─" * 55)
    
    for i, entry in enumerate(session["entries"], 1):
        desc = entry.get('description', 'unspecified')[:40]
        print(f"{i:3}. ${entry['amount']:<10.4f} {desc}")
    
    print("─" * 55)
    print(f"Total: ${session['total_spent']:.4f}")


def cmd_extend(args):
    """Extend the limit by a specified amount."""
    try:
        amount = float(args.amount)
        if amount <= 0:
            print("Error: Amount must be positive")
            sys.exit(1)
    except ValueError:
        print(f"Error: Invalid amount '{args.amount}'")
        sys.exit(1)
    
    limit_config = get_limit()
    old_limit = limit_config["limit"]
    new_limit = old_limit + amount
    
    limit_config["limit"] = new_limit
    limit_config["extended_at"] = datetime.now().isoformat()
    limit_config["extended_by"] = amount
    save_json(LIMIT_FILE, limit_config)
    
    session = get_session()
    remaining = new_limit - session["total_spent"]
    
    print(f"šŸ“ˆ Limit extended!")
    print(f"   {old_limit:.2f} → ${new_limit:.2f} (+${amount:.2f})")
    print(f"   Remaining: ${remaining:.4f}")


def cmd_override(args):
    """Set one-time override flag."""
    ensure_storage()
    with open(OVERRIDE_FILE, "w") as f:
        f.write(datetime.now().isoformat())
    
    print(f"⚔ Override flag set!")
    print(f"   Next budget check will pass regardless of limit.")
    print(f"   Flag auto-clears after one use.")


def cmd_export(args):
    """Export session data as JSON (for integrations)."""
    session = get_session()
    limit_config = get_limit()
    
    export_data = {
        "limit": limit_config["limit"],
        "spent": session["total_spent"],
        "remaining": limit_config["limit"] - session["total_spent"],
        "date": session["date"],
        "entry_count": len(session["entries"]),
        "pct_used": (session["total_spent"] / limit_config["limit"] * 100) if limit_config["limit"] > 0 else 0
    }
    
    if args.full:
        export_data["entries"] = session["entries"]
        export_data["limit_config"] = limit_config
    
    print(json.dumps(export_data, indent=2))


def main():
    parser = argparse.ArgumentParser(
        prog="tokenguard",
        description=f"{TOOL_EMOJI} {TOOL_NAME} — API Cost Guardian for AI Agents",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
    tokenguard status           # Check current spending
    tokenguard set 50           # Set $50 limit
    tokenguard check 5.00       # Check if $5 action fits budget
    tokenguard log 2.50 "GPT-4" # Log $2.50 spent on GPT-4
    tokenguard extend 10        # Add $10 to current limit

Environment Variables:
    TOKENGUARD_DIR              Storage directory (default: ~/.tokenguard)
    TOKENGUARD_DEFAULT_LIMIT    Default limit in USD (default: 20.0)
    TOKENGUARD_WARNING_PCT      Warning threshold 0-1 (default: 0.8)
        """
    )
    
    subparsers = parser.add_subparsers(dest="command", help="Command to run")
    
    # status
    sub_status = subparsers.add_parser("status", help="Show current limit and spending")
    sub_status.set_defaults(func=cmd_status)
    
    # set
    sub_set = subparsers.add_parser("set", help="Set the spending limit")
    sub_set.add_argument("amount", help="Limit amount in dollars")
    sub_set.set_defaults(func=cmd_set)
    
    # log
    sub_log = subparsers.add_parser("log", help="Log a cost entry")
    sub_log.add_argument("amount", help="Cost amount in dollars")
    sub_log.add_argument("description", nargs="?", default="", help="Description")
    sub_log.set_defaults(func=cmd_log)
    
    # check
    sub_check = subparsers.add_parser("check", help="Check if cost is within budget")
    sub_check.add_argument("cost", help="Estimated cost in dollars")
    sub_check.set_defaults(func=cmd_check)
    
    # reset
    sub_reset = subparsers.add_parser("reset", help="Reset session spending")
    sub_reset.set_defaults(func=cmd_reset)
    
    # history
    sub_history = subparsers.add_parser("history", help="Show spending history")
    sub_history.set_defaults(func=cmd_history)
    
    # extend
    sub_extend = subparsers.add_parser("extend", help="Extend the limit")
    sub_extend.add_argument("amount", help="Amount to add to limit")
    sub_extend.set_defaults(func=cmd_extend)
    
    # override
    sub_override = subparsers.add_parser("override", help="One-time budget bypass")
    sub_override.set_defaults(func=cmd_override)
    
    # export
    sub_export = subparsers.add_parser("export", help="Export data as JSON")
    sub_export.add_argument("--full", action="store_true", help="Include entries")
    sub_export.set_defaults(func=cmd_export)
    
    args = parser.parse_args()
    
    if args.command is None:
        args.func = cmd_status
        args.func(args)
    else:
        args.func(args)


if __name__ == "__main__":
    main()

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "g0head",
  "slug": "tokenguard",
  "displayName": "TokenGuard",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1769990441417,
    "commit": "https://github.com/clawdbot/skills/commit/74220a3b411ea2bd1b714841056044b06d36953d"
  },
  "history": []
}

```

tokenguard | SkillHub