Image for post Control de Tokens en Claude Code: Statusline en Tiempo Real

Control de Tokens en Claude Code: Statusline en Tiempo Real


La documentación oficial de Anthropic indica que el coste medio de Claude Code es de 6 $ por desarrollador al día, con el 90 % de los usuarios por debajo de 12 $. Ese número genera escepticismo porque, sin visibilidad sobre el consumo durante el trabajo, es imposible saber si estás en ese promedio o triplicándolo. El statusline de Claude Code resuelve exactamente eso.

TL;DR

Claude Code permite ejecutar un comando shell como statusline que se actualiza en cada refresco de interfaz. Con ccusage y dos hooks (PreToolUse + Stop), puedes mostrar modelo activo, coste de sesión, burn rate y porcentaje de contexto sin ninguna llamada a la API de Anthropic. Configuración: un bloque en settings.json y dos scripts en /tmp para caché instantánea.

El problema de operar a ciegas

El debate sobre el dato de "6 $ al día" no es sobre si el número es correcto o incorrecto: es sobre que sin métricas visibles durante el trabajo, ese promedio no sirve para nada. Sabes el resultado al revisar la factura, no mientras tomas decisiones.

El patrón más común que drena tokens sin que lo notes es la ventana de contexto creciente. Cada herramienta que Claude Code ejecuta, cada archivo que lee, cada fragmento de código que genera, se acumula en el contexto de la sesión. Cuando esa ventana llega al 80-90%, la calidad de las respuestas empieza a degradarse antes de que el modelo lo advierta explícitamente. Y para entonces ya has quemado la mayor parte del presupuesto de esa sesión.

Claude Code por defecto no muestra cuántos tokens está consumiendo, a qué velocidad los está quemando, ni cuánto contexto queda disponible. El statusline nativo solo indica el modelo activo y el directorio. Eso es suficiente para orientarse, pero no para optimizar.

¿Qué es el statusline de Claude Code?

Claude Code admite una clave statusLine en su settings.json que ejecuta un comando shell en cada refresco de interfaz y renderiza su salida en la línea inferior del terminal. Es la misma línea donde ves el modelo y el estado de git, pero es extensible: puedes poner cualquier comando cuya salida quepa en una línea.

El statusline de Claude Code es un comando shell configurado en settings.json que se ejecuta localmente en cada refresco de la interfaz, sin coste de tokens, para mostrar métricas de sesión en tiempo real.

La herramienta que más ha madurado para este propósito es ccusage. Lee los archivos de sesión que Claude Code escribe en ~/.claude/projects/, calcula coste estimado, burn rate y porcentaje de ventana de contexto, y devuelve una cadena compacta lista para el statusline. No realiza llamadas a la API de Anthropic: trabaja offline con datos locales.

Un statusline completo con ccusage muestra:

  • Modelo activo (claude-sonnet-4-6, claude-opus-4-6...)
  • Coste acumulado de la sesión y del día completo
  • Burn rate: tokens por minuto con indicador visual
  • Porcentaje de ventana de contexto usado
  • Tiempo hasta el reset del bloque de 5 horas (plan Max)

Implementación paso a paso

Paso 1: instalar ccusage

ccusage funciona con npx sin instalación previa, pero para un statusline que se ejecuta en cada refresco, lo más sensato es instalarlo globalmente para eliminar la latencia de descarga:

# Instalación global con npm
npm install -g ccusage

# O con Bun (arranque más rápido en cada ejecución)
bun add -g ccusage

# Verifica que funciona antes de configurar el statusline
ccusage statusline

Si ves una línea con costes y modelo, está funcionando. Si muestra $0.00 en una sesión nueva, es normal: los datos aparecen una vez que Claude Code haya escrito suficientes archivos de sesión.

Paso 2: configurar settings.json

Abre o crea ~/.claude/settings.json para una configuración global (aplica a todos los proyectos) o .claude/settings.json dentro del proyecto para configuración local:

{
  "statusLine": {
    "type": "command",
    "command": "ccusage statusline --visual-burn-rate emoji",
    "timeout": 5000
  }
}

El campo timeout es importante: 5000 ms es el tiempo máximo que Claude Code espera la respuesta del comando. Si ccusage tarda más (improbable una vez instalado globalmente), Claude Code ignora la salida y mantiene el último estado visible. No se bloquea la interfaz.

Con --visual-burn-rate emoji, el burn rate muestra indicadores visuales: texto normal para consumo bajo, llama para consumo elevado. Si prefieres umbrales de color sobre el porcentaje de contexto sin emojis:

{
  "statusLine": {
    "type": "command",
    "command": "ccusage statusline --context-low-threshold 60 --context-medium-threshold 85",
    "timeout": 5000
  }
}

Con esta configuración, el porcentaje de contexto aparece en verde por debajo del 60%, amarillo entre 60 y 85%, y rojo por encima. El umbral rojo a 85% da margen para ejecutar /compact antes de llegar al límite.

Paso 3: hooks PreToolUse y Stop para datos frescos

El statusline se refresca con cada actualización de la interfaz, pero los datos que ccusage lee de los archivos de sesión tienen cierto desfase. Para mantener las métricas actualizadas sin polling constante, añade dos hooks que fuerzan la escritura de una caché local:

{
  "statusLine": {
    "type": "command",
    "command": "ccusage statusline --visual-burn-rate emoji",
    "timeout": 5000
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "ccusage sessions --format json > /tmp/cc_usage_cache.json 2>/dev/null &"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "ccusage sessions --format json > /tmp/cc_usage_cache.json 2>/dev/null"
          }
        ]
      }
    ]
  }
}

El hook PreToolUse con matcher "*" se dispara antes de cualquier llamada a herramienta. El & al final lo ejecuta en background: no bloquea la operación que está a punto de ejecutarse. El hook Stop hace la misma escritura de forma síncrona al terminar la sesión.

La estructura completa de hooks en Claude Code, incluyendo cómo combinar PreToolUse con PostToolUse y los matchers por tipo de herramienta, está detallada en el post sobre Claude Code Hooks, Skills y MCPs para entornos reales.

Paso 4: alternativa minimalista sin dependencias npm

Si prefieres un setup con cero dependencias externas y solo necesitas modelo y branch de git, un script bash directo es suficiente:

#!/usr/bin/env bash
# ~/.claude/statusline.sh
# Requiere: git, jq (ambos disponibles en cualquier entorno de desarrollo)

BRANCH=$(git branch --show-current 2>/dev/null || echo "no-git")
MODEL=${CLAUDE_MODEL:-"unknown"}
CACHE_FILE="/tmp/cc_minimal_status"

# Lee caché si existe y tiene menos de 30 segundos
if [[ -f "$CACHE_FILE" ]]; then
  AGE=$(($(date +%s) - $(stat -c %Y "$CACHE_FILE" 2>/dev/null || echo 0)))
  if [[ $AGE -lt 30 ]]; then
    cat "$CACHE_FILE"
    exit 0
  fi
fi

OUTPUT="[$MODEL] $BRANCH"
echo "$OUTPUT" | tee "$CACHE_FILE"
# Hazlo ejecutable
chmod +x ~/.claude/statusline.sh

Y en settings.json:

{
  "statusLine": {
    "type": "command",
    "command": "bash ~/.claude/statusline.sh",
    "timeout": 3000
  }
}

Este enfoque tarda ~50 ms por ejecución, no requiere npm y funciona en cualquier entorno. La contrapartida es que no tienes métricas de coste ni burn rate.

Comparativa de opciones de statusline

Opción Dependencias Métricas disponibles Latencia aprox.
ccusage (global) Node.js Coste, burn rate, contexto, modelo 200-500 ms
ccusage (npx) Node.js Coste, burn rate, contexto, modelo 1-3 s (primera vez)
Script bash propio git, bash Modelo, branch, variables de entorno ~50 ms
oh-my-claude (oh-my-posh) oh-my-posh, ccusage, jq Completas + colores powerline ~50 ms (caché 60 s)

Aplicación práctica: cómo cambia el flujo de trabajo

El caso más inmediato donde el statusline tiene impacto es una sesión larga de refactorización. Sin visibilidad, el patrón típico es continuar hasta que el modelo empieza a repetirse o a perder coherencia, que es cuando el contexto ya está al 90%+ y el daño está hecho.

Con el porcentaje visible, el comportamiento cambia de forma natural:

  • Al superar el 65-70% de contexto, ejecuta /compact con una instrucción de foco ("mantén solo el contexto del módulo de autenticación") antes de seguir
  • Un burn rate elevado sostenido indica que el modelo está leyendo archivos grandes repetidamente; es momento de revisar qué hay cargado en contexto
  • Ver el coste acumulado por sesión ayuda a decidir si vale la pena continuar con Opus o cambiar a Sonnet para las tareas que quedan

Esta visibilidad hace que las estrategias de reducción de tokens sean accionables. La técnica del grafo de dependencias + MCP para reducir tokens en Claude Code tiene mucho más impacto cuando puedes ver en tiempo real si está funcionando o no.

Para quienes usan Claude Code con la API directa (sin plan Max), la visibilidad del coste acumulado es especialmente relevante. Los planes de suscripción Max de Anthropic ($100-200/mes) tienen límites semanales de uso, no costes por token, así que el dato de ccusage refleja el valor equivalente consumido, no un cargo real. En API directa, la estimación de ccusage se acerca bastante a la facturación real, con pequeñas diferencias por redondeo y descuentos de caché de prompt que ccusage no siempre calcula con exactitud.

En Producción

El statusline es un comando shell local: no consume tokens, no hace llamadas a Anthropic, no tiene coste asociado. Eso lo hace seguro para ejecutar en cualquier frecuencia.

Rendimiento: el timeout de 5000 ms es un límite superior de seguridad. Con ccusage instalado globalmente, la respuesta habitual es de 200-500 ms cuando lee de caché local. Si el comando supera el timeout, Claude Code muestra el último valor conocido, no un error.

Múltiples sesiones paralelas: la caché en /tmp/cc_usage_cache.json es compartida entre todas las sesiones del sistema. Si trabajas con varios proyectos en paralelo, los datos de la caché pueden mezclar sesiones. Para sesiones simultáneas, usa un nombre de archivo por proyecto:

# En el hook, usa el directorio del proyecto como sufijo de caché
PROJECT_HASH=$(echo "$PWD" | md5sum | cut -c1-8)
ccusage sessions --format json > "/tmp/cc_usage_${PROJECT_HASH}.json" 2>/dev/null &

Entornos CI/CD: si ejecutas Claude Code en pipelines, desactiva el statusline en esos contextos. El comando de statusline añade latencia innecesaria y puede fallar en entornos sin Node.js instalado. La variable de entorno CI=true puede usarse para condicionar el comando.

Sobre el dato de 6 $/día: ese promedio corresponde al uso equivalente en API para usuarios del plan Pro/Max. El rango real es amplio: hay desarrolladores que gastan ese equivalente en una sesión de exploración de codebase y otros que usan Claude Code de forma más acotada durante toda una semana. El statusline te da tu propio número, que es el único relevante para tu caso.

Errores comunes y depuración

Error: el statusline muestra "command timeout" o queda en blanco.
Causa: ccusage no responde dentro del timeout, habitualmente porque npx está descargando el paquete la primera vez o porque el timeout configurado es demasiado corto.
Solución: instala ccusage globalmente (npm install -g ccusage) y usa el binario directo. Si el problema persiste, sube el timeout a 8000 ms temporalmente.

Error: los datos de uso no cambian entre herramientas.
Causa: el hook PreToolUse corre en background y puede no terminar antes del siguiente refresco de statusline. Es comportamiento esperado: el desfase es de hasta 60 segundos.
Solución: si necesitas datos más frescos, elimina el & del comando del hook (ejecución síncrona). Esto añade 200-500 ms de latencia antes de cada tool call, que en sesiones interactivas es perceptible.

Error: ccusage statusline muestra $0.00 tras horas de trabajo.
Causa: ccusage lee archivos de ~/.claude/projects/ que se crean con la sesión. Si instalaste ccusage después de iniciar la sesión, los datos de esa sesión pueden no estar disponibles aún.
Solución: reinicia la sesión de Claude Code. Los datos históricos de sesiones anteriores sí están disponibles inmediatamente.

Preguntas frecuentes

¿ccusage accede a mi cuenta de Anthropic para obtener los datos?

No. ccusage lee exclusivamente los archivos de sesión que Claude Code escribe en ~/.claude/projects/ de forma local. No realiza autenticación con Anthropic ni accede a la API de facturación. El coste que muestra es una estimación calculada multiplicando los tokens registrados por los precios publicados de cada modelo, no el dato real de la factura.

¿El statusline funciona igual en el plan Max y con la API directa?

Técnicamente sí, con una diferencia en la interpretación del dato de coste. En el plan Max (tarifa fija), el coste estimado de ccusage refleja el valor equivalente consumido, no un cargo real. En API directa, la estimación es una aproximación razonablemente cercana a la factura, con posibles diferencias por descuentos de caché de prompt o batch processing que ccusage no siempre detecta.

¿Puedo usar el statusline con el script de Claude Code Auto-Memory?

Sí, son mecanismos independientes. El sistema de auto-memory de Claude Code funciona via hooks PostToolUse que escriben en archivos de memoria, mientras el statusline solo lee datos para visualización. Pueden coexistir en el mismo settings.json sin conflicto.

Cierre

Hemos configurado un statusline funcional en Claude Code con dos enfoques: ccusage para métricas completas de coste y contexto, y un script bash para quien prefiere cero dependencias. La diferencia entre ambas opciones no es solo de funcionalidad, sino de qué información necesitas para tomar decisiones durante el trabajo.

El debate sobre el dato oficial de "6 $ al día" es, en el fondo, una discusión sobre visibilidad. Con el statusline activo, ese número deja de ser un promedio abstracto y se convierte en tu propio dato en tiempo real, que es el único que importa para tu flujo de trabajo. Si además complementas esto con estrategias activas de reducción de tokens, el contexto de CLAUDE.md Masterclass y las técnicas de tool calling programático, la combinación puede reducir el consumo de forma significativa.

Si ya tienes hooks configurados en tu setup, añadir la entrada statusLine a tu settings.json existente es el paso más pequeño con mayor retorno de visibilidad inmediata.

¿Qué métricas usas actualmente para controlar el consumo en sesiones largas? Cuéntamelo en los comentarios o en Twitter @sergiomarquezp_.

El siguiente tema que exploraré: usar el burn rate como señal automática para cambiar de modelo dentro de una sesión, sin intervención manual.