TinkerClaw Token Panel

Know exactly where your AI tokens go. Multi-provider tracking, budget alerts, and a local REST API—all in one dashboard. Provider credentials are supplied by you and sealed in the …

Oscar Serra

@globalcaos

Install

$ openclaw skills install @globalcaos/token-panel-ultimate

Token Panel Ultimate

One of dozens of skills and plugins in TinkerClaw — a self-improving OpenClaw fork that's been running 24/7 for months.

One dashboard for every token you spend. Anthropic, Gemini, OpenAI, Manus—tracked, stored, and queryable before the bill arrives.

Part of TinkerClaw — real-time token tracking, self-improving crons, persistent cognitive memory. This is one piece of that stack; the repo has dozens more.

👉 https://github.com/globalcaos/tinkerclaw

Clone it. Fork it. Break it. Make it yours.

⚠️ Permissions, Data Flow & Consent — read before installing

What it does that a "dashboard" does not imply:

  • It uses only credentials you supply to Token Panel itself. python3 secretstore.py --login anthropic reads the key from stdin and seals it in the OS keychain — never in a shell argument, so it cannot be picked up from your history or from another process reading command lines. The same command supports anthropic-admin, openai, gemini and manus. The keychain helper is run from /usr/bin or /bin by absolute path, never looked up on $PATH.
  • Each credential goes only where it belongs. The Claude usage token (anthropic) and an Anthropic Admin API key (anthropic-admin) live in separate slots and are never sent to each other's endpoint. The Gemini key travels in the x-goog-api-key header, not in a URL, and is redacted from error text. The Claude fetcher sends its own User-Agent, not Claude Code's. On macOS the write goes through Security.framework rather than security add-generic-password -w, precisely because that CLI form would place your key in this process's argv. --logout PROVIDER clears every local store and prints the provider's server-side revoke URL, because deleting a local copy is not revocation.
  • It reads no other application's credential store. Not Claude Code's, not OpenClaw's, not a browser's. Versions up to 2.5.1 could borrow Claude Code's OAuth token behind an opt-in environment variable; 2.6.0 removes that path entirely rather than gating it — a token issued to another application does not become this tool's to spend just because you set a variable. With no credential of its own, the Claude fetcher fails and tells you how to mint one.
  • It will not quietly use an API key you exported for something else. TOKEN_PANEL_* variables are ours and are always honoured. Generic ones — OPENAI_API_KEY, ANTHROPIC_ADMIN_API_KEY, GEMINI_API_KEY, MANUS_API_KEY — belong to other tools and are read only if you set TOKEN_PANEL_ALLOW_PROVIDER_ENV=1.
  • It can parse your session transcripts, which contain your prompts and replies in full. Opt-in and off by default: nothing is read unless TOKEN_PANEL_READ_TRANSCRIPTS=1, checked both by the collector and by the parser. Only token counts are extracted; message text is never written to the database or returned by the API.
  • Live rate-limit checks cost you money, so you have to ask for them. OpenAI and Google publish remaining capacity only in responses to real requests, so chatgpt-usage-fetch.py and gemini-usage-fetch.py can send a 1-token request per model — billable, visible in your account activity. Off by default: without --probe they make no network call at all and report the documented caps.
  • It serves a REST API, and it is not read-only. GET endpoints are unauthenticated and report your spend and quota — bind to localhost and do not expose the port. Every POST additionally requires X-Token-Panel-Token to match TOKEN_PANEL_API_TOKEN, and returns 403 for everything when that variable is unset.
  • It deletes exactly one file, and checks before it does. --logout unlinks its own credential fallback file when the last provider is removed. That path must be absolute, inside $HOME, a regular file, not a symlink, owned by you, and sitting beside a .token-panel-store marker this tool wrote itself — otherwise it refuses. Your database is never deleted.

What it stores: counts and identifiers. Provider, model, token totals, cost, credit totals, opaque task ids, statuses, timestamps. No prompts, no message content, no task titles. Earlier versions kept a 200-character slice of each Manus task prompt and wrote task titles into the usage JSON; 2.6.0 stops collecting both, and on first connect it blanks any prompt text a previous version already stored.

What it does NOT do: no credential reuse, no browser-token extraction, no silent secrets scraping, no .env reads, no message content in the database, no telemetry, no third-party endpoint. If no OS keychain exists, the CLI warns on every use before falling back to an owner-only 0600 file inside a 0700 directory; that file and its directory must not be symlinks, and it is rewritten atomically. Database and usage files are created 0600 inside a 0700 directory rather than inheriting an ambient umask. The local API allows CORS only from localhost dashboard origins, not *.

The widget treats its data as text. Plan names, model ids and counts come from provider responses, so every value is HTML-escaped or coerced to a number before it reaches the page, and the userscript requests no GM_* grants and no file:// access. The API accepts only identifier-shaped strings and non-negative counts on POST, and compares the mutate token in constant time.

Diagnostics are off by default. The browser widget logs nothing unless you set localStorage.BP_DEBUG = "1" — including error paths, which can carry request URLs and response bodies. Console output is readable by anything sharing the page.

It runs as you, not as root. The systemd unit is a --user unit with no User= line and no machine's username baked in.

Dependencies are pinned above known-vulnerable releases. The floor for fastapi is 0.109.1; the previous >=0.100.0 permitted a release affected by CVE-2024-24762.

Why This Exists

You've checked your Anthropic console, squinted at the OpenAI dashboard, opened a Gemini tab, and still weren't sure where last Tuesday's $14 went. Token Panel Ultimate puts all four providers in one place so the answer is always one query away.

What It Does

  • Multi-Provider Tracking — Anthropic, Gemini, OpenAI, and Manus in a single SQLite database
  • Budget Alerts — Set monthly limits per provider. Get warned before you overspend, not after
  • REST API — Query usage programmatically on port 8765. Plug it into your own scripts or dashboards
  • Transcript Parsing — Extracts token counts from OpenClaw session transcripts, opt-in via TOKEN_PANEL_READ_TRANSCRIPTS=1
  • Zero Dependencies — SQLite storage. No Postgres, no Redis, no cloud account required
  • Runs as a Daemon — Systemd service keeps it alive in the background

Quick Start

pip install -r requirements.txt

# Give the dashboard a credential of its own (read from stdin, sealed in the keychain)
claude setup-token | python3 secretstore.py --login anthropic   # scripts/claude-usage-fetch.py
python3 secretstore.py --login anthropic-admin                  # collector: Admin usage API (optional)
python3 secretstore.py --status

python3 api.py                    # http://127.0.0.1:8765

Remove a credential at any time — this clears every local store and prints the provider's revoke URL:

python3 secretstore.py --logout anthropic

Architecture

OpenClaw Plugin → Budget Collector API → SQLite DB (0600)
   (GET only)               ↓
                Transcripts (opt-in) / Provider APIs / Manus Tracker

API Endpoints

MethodPathAuthDescription
GET/statusnoneOverall budget status
GET/budgetsnoneCurrent budget limits
GET/summary/monthlynoneMonthly usage summary
GET/summary/daily/{provider}noneDaily breakdown
POST/budgetstokenSet or update budget limits
POST/usagetokenRecord a usage event
POST/manus/tasktokenRecord a task (id, credits, status)

token = X-Token-Panel-Token must match TOKEN_PANEL_API_TOKEN; with that variable unset, every POST returns 403.

Changelog

  • 2.6.2 — widget HTML-escapes all rendered values (fixes markup injection from provider data) and drops unused GM/file grants; Gemini key moved from URL to header with error redaction; separate anthropic / anthropic-admin credential slots; keychain helpers run from fixed system paths, not $PATH; fallback credential file refuses symlinks and writes atomically; API token compared in constant time and POST inputs validated; Claude fetcher no longer sends a Claude Code User-Agent.

Clone it. Fork it. Break it. Make it yours.

👉 Explore the full project: github.com/globalcaos/tinkerclaw

Top skills in this category