PluginWorld
To

tokensniff

Claude Code✓ SPEC VERIFIED

Claude Code telemetry proxy and live terminal status line HUD. Real-time token tracking, API costs, TTFT, and calendar heatmap dashboard. Zero dependencies.

@neerajsahu0306 · v0.1.1 · MIT · updated 19d ago

SECURITY

A

SCORE

76

INSTALLS

▲ 27K

PLUG IN

/plugin marketplace add neerajsahu0306/tokensniff
/plugin install tokensniff

README

tokensniff

Local telemetry sidecar for AI coding CLIs.

Track every token, every turn, every dollar — live in your terminal and on a calendar heatmap dashboard. Zero runtime dependencies.

npm version License: MIT Node.js


What Is tokensniff?

tokensniff is a transparent HTTP reverse proxy and local telemetry sidecar designed specifically for the Claude Code CLI harness running alongside the local antigravity-claude-proxy.

By default, tokensniff orchestrates and connects to antigravity-claude-proxy to route Claude Code API requests through Google Antigravity / Cloud Code, allowing you to utilize your Antigravity Gemini quota directly inside Claude Code.


⚠️ Important Notice: Use At Your Own Risk & Account Warning

[!CAUTION] Use at your own risk. By default, tokensniff routes traffic through antigravity-claude-proxy, which accesses Google Antigravity / Cloud Code endpoints using unofficial proxying techniques.

  • Risk of Account Suspension / Bans: Google actively monitors and enforces Terms of Service (ToS) restrictions. Accounts connected to unofficial Cloud Code and Antigravity reverse proxies risk being shadow-banned, quota-restricted, or permanently banned.
  • No Guarantees & Zero Liability: The creators and maintainers of tokensniff provide no guarantees or warranties of any kind, express or implied. We are not responsible or liable for any account bans, suspensions, quota penalties, data loss, or any other consequences resulting from the use of this software.
  • Safety Recommendation: Do not use your primary, personal, or corporate Google account. If you choose to use this integration, use a dedicated burner/disposable Google account.
  • Learn More: Read the upstream antigravity-claude-proxy GitHub Repository and its Safety, Usage, and Risk Notices to understand how the underlying authentication and proxying operate.

It captures every API turn flowing through it and gives you:

  • Per-turn token counts — input, output, cache-read, cache-write, thinking tokens
  • Real-time cost tracking — per turn, per session, per day (in USD)
  • Performance metrics — Time to First Token (TTFT), tokens per second (TPS), turn duration
  • Live terminal status line — a single-line HUD rendered directly inside Claude Code's status bar
  • Calendar heatmap dashboard — a beautiful, self-contained HTML page showing your daily token spend over the entire year
  • Multi-terminal session management — run multiple terminals against the same proxy without conflicts
  • Tool call tracking — which tools the model called, how many times, argument token sizes
  • Context window monitoring — how full your context is, with color-coded warnings (green → yellow → red)

All of this happens transparently. Your AI tool doesn't know tokensniff exists. It just thinks it's talking to the normal API. tokensniff forwards every byte with zero latency overhead, while quietly recording the telemetry.


How It Works

flowchart TD
    CLI["Claude Code CLI<br/><code>ANTHROPIC_BASE_URL:4000</code>"]
    TS["tokensniff<br/><code>Reverse Proxy :4000</code>"]
    Proxy["antigravity-claude-proxy<br/><code>Local Upstream :8085</code>"]
    Google["Google Cloud Code API<br/><code>Gemini Backend / Quota</code>"]

    subgraph Telemetry["Telemetry Engine"]
        T1["latest.json"]
        T2["totals.json"]
        T3["history.ndjson"]
        T4["/dashboard (HTML)"]
    end

    Statusline["Claude Code Statusline HUD"]
    Dashboard["Live Calendar Heatmap<br/><code>http://localhost:4000/dashboard</code>"]

    CLI <-->|"1. Anthropic API Requests / Streams"| TS
    TS <-->|"2. Forward"| Proxy
    TS -->|"3. Telemetry (Async)"| Telemetry
    Proxy <-->|"4. Protocol Translation"| Google

    T1 --> Statusline
    T4 --> Dashboard
  1. Harness Redirection: You point Claude Code to http://localhost:4000 by setting ANTHROPIC_BASE_URL in ~/.claude/settings.json. Claude Code continues sending standard Anthropic Messages API requests normally.
  2. Upstream Proxy Startup: When launched, tokensniff checks port 8085 and automatically starts the local upstream proxy command (npx antigravity-claude-proxy@latest start) if it is not already running.
  3. Protocol & Quota Translation: The local antigravity-claude-proxy receives the Anthropic-formatted request, authenticates with your Google Antigravity / Cloud Code OAuth credentials, translates the schema to Google Generative AI format, and submits it to Google Cloud Code's backend to consume your Antigravity Gemini quota.
  4. Streaming Response Pass-Through: As Google's response streams back, antigravity-claude-proxy transforms it into Anthropic-compatible SSE events or buffered JSON. tokensniff instantly relays every raw byte back to Claude Code (res.write(chunk)) with zero latency overhead.
  5. Telemetry Extraction: Concurrently and non-blockingly, tokensniff's parser inspects the response payload. It extracts Google's usageMetadata (input, output, cache-read, cache-write, and thinking/reasoning tokens), measures Time to First Token (TTFT) and token generation speed (TPS), and tracks turn duration.
  6. Live Pricing Calculation: tokensniff queries live pricing from OpenRouter's model catalog, computing turn cost, session cumulative spend, and daily totals.
  7. Statusline HUD & Calendar Heatmap: Telemetry snapshots are written atomically to disk (latest.json, totals.json, history.ndjson). Claude Code's status bar runs tokensniff-status to display the live single-line HUD, and tokensniff serves an interactive calendar heatmap dashboard at http://localhost:4000/dashboard.

Quick Start

1. Install

npm install -g tokensniff

Or with pnpm:

pnpm add -g tokensniff

2. Initialize Configuration

tokensniff init

This creates a configuration file at ~/.tokensniff/config.json with sensible defaults:

{
  "upstreamCommand": "npx antigravity-claude-proxy@latest start",
  "upstreamHost": "localhost",
  "upstreamPort": 8085,
  "listenPort": 4000,
  "harnessCommand": "claude"
}

Default Upstream: Out of the box, tokensniff is pre-configured to launch antigravity-claude-proxy on port 8085, allowing you to route Claude Code prompts through your Antigravity Gemini quota. Please review the Risk & Terms of Service Warning before running with this configuration.

3. Configure Claude Code

Add the following to your ~/.claude/settings.json file:

{
  "env": {
    "ANTHROPIC_BASE_URL": "http://localhost:4000"
  },
  "statusLine": {
    "type": "command",
    "command": "tokensniff-status",
    "padding": 0
  }
}

This does two things:

  • ANTHROPIC_BASE_URL — Tells Claude Code to send all API requests through tokensniff's proxy on port 4000 instead of directly to Anthropic
  • statusLine — Tells Claude Code to run tokensniff-status and display its output as a live status bar at the bottom of the terminal

4. Run

tokensniff

That's it. tokensniff will:

  1. Start the upstream proxy (if configured)
  2. Start the telemetry proxy on port 4000
  3. Launch Claude Code (or whatever harness command you configured)
  4. Show you a live status line and dashboard URL

Open the dashboard in your browser:

http://localhost:4000/dashboard

CLI Commands

tokensniff

Runs the full telemetry pipeline: starts the upstream proxy, starts the tokensniff proxy, and launches your AI coding tool.

tokensniff

tokensniff init

Generates the global configuration file at ~/.tokensniff/config.json and prints the Claude Code settings.json instructions.

tokensniff init

tokensniff dashboard

Prints the URL of the live calendar heatmap dashboard.

tokensniff dashboard
# Output: [tokensniff] live heatmap dashboard: http://127.0.0.1:4000/dashboard

tokensniff-status

This is the statusline renderer. You don't run this directly — Claude Code runs it automatically via the statusLine setting. It reads the latest telemetry snapshot from disk and outputs a formatted single-line status bar.

If you want to test it manually:

echo '{}' | tokensniff-status

To get raw JSON output instead of the formatted status line:

TOKENSNIFF_JSON=1 echo '{}' | tokensniff-status

The Status Line

When running inside Claude Code, you'll see a live status line at the bottom of your terminal that looks like this:

Wide terminals (≥ 180 columns) — single line:

turn 3 [3.8-flash] | ctx: 38.5k/1M (3.9%) [cache: 25k (64.9%)] | input: +4.5k tok, output: 42 tok, think: 180 tok | ttft: 1.2s, 110 tok/s | cost: turn $0.0042, sess $0.058, today $0.245

Standard terminals (< 180 columns) — clean 2-line stack:

turn 3 [3.8-flash] | ctx: 38.5k/1M (3.9%) [cache: 25k (64.9%)]
input: +4.5k tok, output: 42 tok, think: 180 tok | ttft: 1.2s, 110 tok/s | cost: turn $0.0042, sess $0.058, today $0.245

What Each Segment Means

Segment Example Meaning
Turn turn 3 Which turn number this is in the current session
Model [3.8-flash] The AI model being used (vendor prefix stripped for readability)
[bg] [bg] Shown when this is a background agent turn (via x-app: cli-bg header)
Context ctx: 38.5k/1M (3.9%) Current context usage / max window size (percentage full)
Cache [cache: 25k (64.9%)] How many tokens were served from cache and the cache hit ratio
Input input: +4.5k tok New tokens added to context this turn (delta). Shows freed when context shrinks
Output output: 42 tok Tokens generated by the model this turn
Thinking think: 180 tok Reasoning/thinking tokens used (for models with extended thinking)
Tool tool: Read (45 tok) Which tool was called and how many argument tokens it used
TTFT ttft: 1.2s Time to First Token — how long before the model started generating
Speed 110 tok/s Generation velocity in tokens per second
Turn Cost turn $0.0042 How much this specific turn cost in USD
Session Cost sess $0.058 Total spend for this entire session
Today Cost today $0.245 Total spend across all sessions today (resets at local midnight)
[idle] [idle] Shown when the last turn was more than 120 seconds ago

Color Coding

The context percentage is color-coded based on how full your context window is:

  • 🟢 Green — Under 60% (plenty of room)
  • 🟡 Yellow — 60-80% (getting full, consider starting a new session)
  • 🔴 Red — Over 80% (context is nearly full, model may start forgetting earlier context)

These thresholds are configurable via warnPct and critPct.


The Dashboard

tokensniff serves a live calendar heatmap dashboard directly on the proxy port. Open it in any browser:

http://localhost:4000/dashboard

The dashboard shows:

  • Total Spend — cumulative USD spent across all sessions
  • Total Tokens — cumulative token volume processed
  • Cache Ratio — what percentage of tokens were served from cache
  • Total Turns — how many API turns have been recorded
  • Calendar Heatmap — a GitHub-contributions-style grid showing daily token volume across the year

Heatmap Tiers

The calendar tiles are colored using a 5-tier emerald luminosity scale:

Tier Daily Volume Color
0 No activity Dark (nearly invisible)
1 < 5M tokens Dark emerald
2 5M – 25M tokens Medium emerald
3 25M – 100M tokens Bright emerald
4 > 100M tokens Vivid emerald (glowing)

Hover over any tile to see a detailed tooltip with exact token counts, cost, cache leverage, and turns logged for that day.

Dashboard API

There's also a JSON API endpoint for programmatic access:

curl http://localhost:4000/api/daily

Returns the raw daily rollup data as JSON.


Configuration

tokensniff uses a strict hierarchical configuration system:

Environment Variables  >  Config File  >  Embedded Defaults
          (highest)                          (medium)                   (lowest)

Config File Location

~/.tokensniff/config.json

You can override this path with the TOKENSNIFF_CONFIG environment variable:

TOKENSNIFF_CONFIG=/path/to/custom/config.json tokensniff

All Configuration Options

Config Key Env Variable Default Description
listenPort TOKENSNIFF_PORT 4000 Port the tokensniff proxy listens on
listenHost TOKENSNIFF_HOST 127.0.0.1 Host/IP the proxy binds to
upstreamHost TOKENSNIFF_UPSTREAM_HOST localhost Hostname of the upstream API server
upstreamPort TOKENSNIFF_UPSTREAM_PORT 8085 Port of the upstream API server
upstreamTimeoutMs TOKENSNIFF_UPSTREAM_TIMEOUT_MS 300000 (5 min) Timeout for upstream requests in milliseconds (range: 1,000 – 3,600,000)
maxBodyBytes TOKENSNIFF_MAX_BODY_BYTES 10485760 (10 MB) Maximum request/response body size. Requests exceeding this get a 413 error (range: 1,024 – 104,857,600)
statusDirs TOKENSNIFF_STATUS_DIRS ~/.tokensniff/status Comma-separated list of directories where telemetry snapshots are written
maxSessions TOKENSNIFF_MAX_SESSIONS 50 Maximum number of tracked sessions before oldest are evicted (range: 1 – 1,000)
deadSessionMs TOKENSNIFF_DEAD_SESSION_MS 259200000 (72 hrs) How long to keep stale session files before pruning (range: 1 hour minimum)
staleAfterS TOKENSNIFF_STALE_AFTER_S 120 Seconds of inactivity before a session shows [idle] in the status line (range: 5 – 86,400)
labelMaxIn TOKENSNIFF_LABEL_MAX_IN 2000 Maximum input tokens for a turn to be classified as a micro-label
labelMaxOut TOKENSNIFF_LABEL_MAX_OUT 60 Maximum output tokens for a turn to be classified as a micro-label
warnPct TOKENSNIFF_WARN_PCT 60 Context utilization % threshold for yellow warning color (range: 1 – 99)
critPct TOKENSNIFF_CRIT_PCT 80 Context utilization % threshold for red critical color (range: 2 – 100)
color TOKENSNIFF_COLOR true Enable/disable ANSI color output. Automatically disabled when NO_COLOR env var is set (per no-color.org)
upstreamCommand TOKENSNIFF_UPSTREAM_CMD npx antigravity-claude-proxy@latest start Shell command to start the upstream proxy server
upstreamStopCommand TOKENSNIFF_UPSTREAM_STOP_CMD (empty) Shell command to stop the upstream proxy on shutdown
harnessCommand TOKENSNIFF_HARNESS_CMD claude The AI coding tool to launch (e.g., claude, codex, or any executable)

Example Config File

{
  "listenPort": 4000,
  "listenHost": "127.0.0.1",
  "upstreamHost": "localhost",
  "upstreamPort": 8085,
  "upstreamCommand": "npx antigravity-claude-proxy@latest start",
  "upstreamStopCommand": "",
  "harnessCommand": "claude",
  "maxSessions": 50,
  "staleAfterS": 120,
  "warnPct": 60,
  "critPct": 80,
  "color": true
}

Environment Variable Examples

# Change the proxy port
TOKENSNIFF_PORT=5000 tokensniff

# Point to a different upstream
TOKENSNIFF_UPSTREAM_HOST=api.anthropic.com TOKENSNIFF_UPSTREAM_PORT=443 tokensniff

# Disable colors
NO_COLOR=1 tokensniff

# Use a custom config file
TOKENSNIFF_CONFIG=./my-config.json tokensniff

# Write status to multiple directories
TOKENSNIFF_STATUS_DIRS="/path/a,/path/b" tokensniff

Multi-Terminal Support

tokensniff supports multiple terminal sessions running simultaneously against the same proxy. This is how it works:

  1. When you run tokensniff, it first checks if a proxy is already running on port 4000
  2. If yes, it attaches to the existing proxy (no duplicate servers) and just launches your harness
  3. Each terminal session registers itself in ~/.tokensniff/sessions/ with a PID lock file
  4. When you close a terminal (Ctrl+C or exit):
    • If other terminals are still active → only the local harness is terminated; the proxy stays alive
    • If this was the last terminal → the proxy and upstream are cleanly shut down
  5. Dead PID lock files (from crashed terminals) are automatically pruned

This means you can have 5 Claude Code windows all routing through the same tokensniff proxy, and the telemetry stays unified. Session costs are tracked independently, but today cost accumulates across all sessions.


Supported Providers

tokensniff's parser understands multiple API response formats:

Provider Format Detection
Anthropic (Claude) SSE streams (text/event-stream) event: message_start framing
Anthropic (Claude) Buffered JSON (application/json) usage.input_tokens / usage.output_tokens
Google Gemini (Antigravity) Buffered JSON candidates[].content.parts[] + usageMetadata

The parser automatically detects the format from the response content-type and payload structure. You don't need to configure anything.

Pricing

tokensniff fetches live per-token pricing from OpenRouter's public model catalog. This means:

  • Pricing is always up to date — no hardcoded rate tables to maintain
  • Any model listed on OpenRouter is automatically priced correctly
  • Pricing includes prompt, completion, cache-read, and cache-write tiers
  • Context window sizes are also pulled dynamically from the catalog

If a model isn't found on OpenRouter, costs default to $0.00 (zero-rate boundary) rather than guessing wrong. The context window defaults to 128K tokens for unknown models.

The pricing cache is populated on-demand (first turn using a new model triggers a background fetch) and persists in memory for the lifetime of the proxy process.


Telemetry Data Files

tokensniff stores all telemetry in ~/.tokensniff/status/:

File Format Purpose
latest.json JSON Most recent telemetry snapshot (any session)
latest-<session_id>.json JSON Most recent snapshot for a specific session
totals.json JSON Cumulative spend per session
history.ndjson Newline-delimited JSON Append-only turn-by-turn ledger (feeds the heatmap)

latest.json Schema (v1)

{
  "v": 1,
  "session_id": "abc-123",
  "turn_index": 5,
  "ts": 1726056000000,
  "model": "gemini-3.8-flash-tiered",
  "is_bg": false,
  "ctx": 38500,
  "window": 1000000,
  "pct": 3.9,
  "cache_read": 25000,
  "cache_create": 0,
  "delta_in": 4500,
  "in_tokens": 13500,
  "out_tokens": 42,
  "thinking": true,
  "thinking_tokens": 180,
  "tool": "Read",
  "tool_tk": 45,
  "tools_summary": [{ "name": "Read", "count": 1, "arg_tk": 45 }],
  "stop_reason": "end_turn",
  "is_label": false,
  "label": "",
  "ttft_ms": 1200,
  "tps": 110,
  "dur_s": 1.6,
  "cost_turn": 0.0042,
  "cost_session": 0.058,
  "cost_today": 0.245,
  "error": null,
  "status": 200,
  "quota_pct": null,
  "quota_reset": null,
  "tier": null
}

history.ndjson Record Format

Each line is a compact JSON object:

{"d":"2026-09-11","ts":1726056000000,"s":"abc-123","t":5,"m":"gemini-3.8-flash","tk":38542,"c":0.0042,"cr":25000,"th":180}
Field Meaning
d Local calendar date (YYYY-MM-DD)
ts Unix timestamp in milliseconds
s Session ID
t Turn number
m Model name
tk Total tokens (context + output)
c Cost in USD
cr Cache-read tokens
th Thinking tokens

Programmatic API

tokensniff exports its entire engine as a library. You can use it in your own Node.js projects:

npm install tokensniff

Start the Proxy Programmatically

import { startProxy } from 'tokensniff';

const server = startProxy({
  listenPort: 4000,
  listenHost: '127.0.0.1',
  upstreamHost: 'localhost',
  upstreamPort: 8085,
});

// server is a standard Node.js http.Server
server.on('listening', () => {
  console.log('tokensniff proxy is running');
});

Calculate Costs

import { costFor, ratesFor, resolveModelRates } from 'tokensniff/pricing';

// Synchronous (from cache, or zero if not yet fetched)
const rates = ratesFor('claude-3-7-sonnet');

// Async (fetches from OpenRouter if needed)
const rates2 = await resolveModelRates('gemini-2.5-pro');

// Calculate cost
const cost = costFor(rates, {
  input: 10000,
  output: 500,
  cacheRead: 8000,
  cacheCreate: 0,
});

console.log(`Turn cost: $${cost.toFixed(4)}`);

Use the Schema

import { buildLatest, isTokenSniffLatest, SCHEMA_VERSION } from 'tokensniff/schema';

// Build a telemetry snapshot with safe defaults
const snapshot = buildLatest({
  session_id: 'my-session',
  model: 'gemini-3.8-flash',
  ctx: 25000,
  window: 1000000,
  pct: 2.5,
});

// Validate unknown data
if (isTokenSniffLatest(someData)) {
  console.log('Valid telemetry snapshot');
}

Full API Exports

import {
  // CLI Orchestrator
  runCli,
  countActiveSessions,
  getSessionsDir,
  isPortActive,
  isProcessAlive,
  registerSession,
  waitForTcp,
  writeInitFile,
  printClaudeInstructions,

  // Configuration
  loadConfig,
  getGlobalDir,
  getGlobalConfigPath,

  // Proxy Server
  startProxy,

  // Dashboard & Analytics
  importCapturesDirectory,
  loadDailyRollup,
  renderHeatmapHtml,

  // Statusline Renderer
  formatStatus,
  formatTokenCount,
  formatToolSegment,
  runStatusRenderer,
  readStdin,
  pickLatest,
  extractModel,

  // Pricing Engine
  costFor,
  ratesFor,
  resolveModelRates,
  normalizeModelName,
  syncOpenRouterCatalog,

  // Schema & Types
  buildLatest,
  isTokenSniffLatest,
  extractCleanLabel,
  SCHEMA_VERSION,
} from 'tokensniff';

Sub-path Exports

// Just the schema types and guards
import { buildLatest, isTokenSniffLatest } from 'tokensniff/schema';

// Just the pricing engine
import { costFor, resolveModelRates } from 'tokensniff/pricing';

Architecture

tokensniff/
├── bin/
│   ├── tokensniff.js          # CLI entrypoint → dist/cli.js
│   └── tokensniff-status.js   # Statusline entrypoint → dist/status.js
├── src/
│   ├── index.ts               # Public API facade (re-exports everything)
│   ├── cli/
│   │   └── run.ts             # Master CLI orchestrator & multi-terminal lifecycle
│   ├── collector/
│   │   ├── config.ts          # Hierarchical config loader (env > file > defaults)
│   │   ├── index.ts           # HTTP reverse proxy server & telemetry capture
│   │   ├── parse.ts           # SSE stream & JSON payload parser (multi-provider)
│   │   └── store.ts           # Atomic file persistence engine (Windows-safe)
│   ├── dashboard/
│   │   └── heatmap.ts         # Calendar heatmap HTML renderer & capture importer
│   ├── renderer/
│   │   ├── format.ts          # Responsive statusline formatter
│   │   └── index.ts           # Statusline CLI renderer (stdin consumer)
│   └── shared/
│       ├── pricing.ts         # Dynamic pricing engine (OpenRouter catalog sync)
│       └── schema.ts          # Domain schemas, type guards, label extraction
└── test/
    ├── fixtures.ts            # Synthetic SSE/JSON payload generators
    ├── collector.test.ts      # Integration: proxy, streaming, 502, 413, dashboard
    ├── format.test.ts         # Statusline formatting & responsive layouts
    ├── heatmap.test.ts        # Daily rollups, capture import, HTML rendering
    ├── parse.test.ts          # SSE/JSON parsing, multi-provider, tool grouping
    ├── pricing.test.ts        # Cost math, OpenRouter sync, model normalization
    ├── run.test.ts            # CLI routing, TCP probing, session lifecycle
    ├── schema.test.ts         # Type guards, buildLatest, label extraction
    └── store.test.ts          # Atomic writes, totals, history, pruning, config

Key Design Decisions

  • Zero runtime dependencies — The entire package uses only Node.js built-in modules (http, fs, net, path, os, child_process). No Express, no Axios, no anything. This keeps the install tiny and avoids supply chain risk.

  • Atomic file writes — All file persistence uses a temp-file + OS rename pattern. This means readers (the statusline renderer) never see a half-written JSON file. On Windows, retries with exponential backoff handle EPERM/EBUSY file lock contention.

  • Streaming-first proxy — Response bytes are forwarded to the client as they arrive (res.write(chunk)). tokensniff never buffers the full response before forwarding. This means zero latency overhead. The telemetry parsing happens on the buffered copy.

  • LRU-bounded memory — Internal maps (context history, turn indices) are capped at 500 entries using LRU eviction. The proxy can run for weeks without leaking memory.

  • Defensive parsing — The parser never throws. Corrupt payloads, truncated SSE streams, binary noise — everything returns a safe fallback result. This is critical because the proxy sits in the hot path of your AI tool.


Development

Prerequisites

  • Node.js ≥ 22.0.0
  • pnpm 11.x

Setup

git clone https://github.com/neerajsahu0306/tokensniff.git
cd tokensniff
pnpm install

Build

pnpm build

Run Tests

pnpm test

Type Check

pnpm typecheck

Lint

pnpm lint

Auto-fix Lint Issues

pnpm lint:fix

Watch Mode (Development)

pnpm dev

Validate Package Structure

pnpm check:package

Troubleshooting

"waiting for first turn..."

The status line shows this message when tokensniff hasn't received any API requests yet. Make sure:

  1. Your ANTHROPIC_BASE_URL is set to http://localhost:4000 in ~/.claude/settings.json
  2. The tokensniff proxy is actually running (check terminal output)
  3. You've made at least one prompt in Claude Code

Port 4000 is already in use

Another tokensniff instance (or another program) is using port 4000. Either:

  • Let tokensniff attach to it (it will do this automatically if the existing proxy is tokensniff)
  • Change the port: TOKENSNIFF_PORT=5000 tokensniff
  • Kill the existing process: find and terminate whatever is using port 4000

Upstream proxy failed health check

tokensniff couldn't connect to the upstream API server. Check that:

  1. Your upstreamCommand is valid and the upstream server starts correctly
  2. The upstreamHost and upstreamPort match where the upstream is listening
  3. The upstream server is not firewalled or blocked

tokensniff will continue running even if the upstream health check fails — downstream requests will get 502 errors until the upstream becomes available.

Costs showing $0.0000

This means tokensniff couldn't find pricing for the model you're using on OpenRouter. This can happen if:

  • The model is brand new and not yet listed on OpenRouter
  • The OpenRouter API was unreachable when tokensniff tried to fetch pricing
  • You're using a custom/private model that isn't publicly listed

The proxy and telemetry still work perfectly — only the cost calculation defaults to zero.

Status line not appearing in Claude Code

Make sure your ~/.claude/settings.json has the exact statusLine block:

{
  "statusLine": {
    "type": "command",
    "command": "tokensniff-status",
    "padding": 0
  }
}

Also verify that tokensniff-status is accessible in your PATH (it should be if you installed tokensniff globally).


Requirements

  • Node.js ≥ 22.0.0
  • OS: Windows, macOS, or Linux
  • Terminal: Any terminal that supports ANSI colors (for the status line color coding)

License

MIT © 2026 tokensniff contributors

SIMILAR PLUGINS