🌱 Empieza aquí · Guardia del crédito de API
Esta semilla le pone a tu asistente un guardia en la puerta: si una sesión de Claude Code arranca con una llave de API (la credencial que cobra por uso) metida en el ambiente sin que tú lo hayas autorizado, el guardia frena tu mensaje antes de que llegue al modelo. Así el gasto no se va al crédito de API cuando tú querías usar tu plan.
Para instalarla
Abre esta carpeta con Claude Code y dile a tu asistente:
"Siembra esta semilla 🌱"
Con eso basta de tu parte. Tu asistente hace todo lo demás y al final te dice cómo comprobar que quedó funcionando. Vas a ver algunas palabras en inglés en la pantalla; ni caso, él te guía.
¿Otras formas de pedírselo? "instala esta semilla", "pon la guardia del crédito de API", "activa el hook que frena la llave de API". Te entiende igual.
Para el asistente que siembra 🤖
Este componente es un hook (gancho de automatización) de Claude Code para el evento UserPromptSubmit (cada vez que la persona envía un mensaje). Es un solo archivo de Python 3 sin dependencias externas: kernel/guardia-credito-api.py.
Qué hace, exactamente:
- Si el ambiente trae
ANTHROPIC_API_KEYoANTHROPIC_AUTH_TOKEN(con valor no vacío) y no traeUSAR_CREDITO_API=1, escribe un aviso en la salida de error y sale con código 2. Claude Code bloquea el mensaje antes de mandarlo al modelo. - En cualquier otro caso sale con código 0 y el mensaje pasa normal.
CLAUDE_CODE_OAUTH_TOKEN(el pase del plan) no se revisa: con solo ese pase, la sesión pasa.- No lee la entrada del evento, no escribe archivos, no usa red y nunca imprime el valor de la llave.
No ejecutes nada por tu cuenta fuera de estos pasos y confirma con la persona antes de editar su settings.json.
0. Antes de instalar, pregunta una cosa
Pregúntale a la persona: "¿Usas a propósito una llave de API para pagar Claude Code (sin plan)?"
- Si no (usa su plan con inicio de sesión), sigue con el paso 1.
- Si sí, este guardia le frenaría todos sus mensajes. O no lo instales, o explícale que tendrá que lanzar cada sesión con
USAR_CREDITO_API=1(ver "Usar el crédito a propósito", abajo).
1. Copia el hook
macOS / Linux / Windows con Git Bash:
mkdir -p "$HOME/.claude/hooks"
cp kernel/guardia-credito-api.py "$HOME/.claude/hooks/guardia-credito-api.py"
chmod +x "$HOME/.claude/hooks/guardia-credito-api.py"
Windows (PowerShell):
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.claude\hooks" | Out-Null
Copy-Item "kernel\guardia-credito-api.py" "$env:USERPROFILE\.claude\hooks\guardia-credito-api.py"
2. Regístralo en settings.json
Abre ~/.claude/settings.json (en Windows, %USERPROFILE%\.claude\settings.json). Si el archivo no existe, créalo con exactamente este contenido. Si ya existe, agrega la sección UserPromptSubmit dentro de hooks sin tocar lo demás; si ya hay una sección UserPromptSubmit, añade el objeto al arreglo existente: no la dupliques ni borres los hooks que ya estén.
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "python3 ~/.claude/hooks/guardia-credito-api.py"
}
]
}
]
}
}
En Windows, si
python3no existe, usapythonen el campocommand. Comprueba cuál responde conpython3 --versionopython --version.
El cambio aplica en las sesiones nuevas de Claude Code.
3. Verificación post-siembra (obligatoria)
Las pruebas usan una llave falsa inventada solo para la prueba. Nunca uses una llave real aquí.
a) El archivo quedó en su lugar:
ls -la "$HOME/.claude/hooks/guardia-credito-api.py"; echo "exit=$?"
Salida esperada: una línea que lista el archivo y exit=0. Si sale No such file or directory, repite el paso 1.
b) El guardia frena y deja pasar lo correcto (simula el evento pasando un JSON por la entrada, como lo hace Claude Code):
HOOK="$HOME/.claude/hooks/guardia-credito-api.py"
EVENTO='{"hook_event_name":"UserPromptSubmit","prompt":"hola"}'
echo "--- 1) llave sin permiso (debe frenar, codigo=2)"
echo "$EVENTO" | env -u ANTHROPIC_AUTH_TOKEN -u USAR_CREDITO_API ANTHROPIC_API_KEY=llave-falsa-de-prueba python3 "$HOOK"; echo "codigo=$?"
echo "--- 2) llave con permiso (debe pasar, codigo=0)"
echo "$EVENTO" | env -u ANTHROPIC_AUTH_TOKEN ANTHROPIC_API_KEY=llave-falsa-de-prueba USAR_CREDITO_API=1 python3 "$HOOK"; echo "codigo=$?"
echo "--- 3) sin llave (debe pasar, codigo=0)"
echo "$EVENTO" | env -u ANTHROPIC_API_KEY -u ANTHROPIC_AUTH_TOKEN -u USAR_CREDITO_API python3 "$HOOK"; echo "codigo=$?"
Salida esperada: en el caso 1, un mensaje que empieza con GUARDIA DEL CRÉDITO: y codigo=2; en los casos 2 y 3, nada de mensaje y codigo=0. Si el caso 1 da codigo=0, el archivo copiado no es el del kernel: repite el paso 1.
Windows (PowerShell), mismo caso 1:
$HOOK = "$env:USERPROFILE\.claude\hooks\guardia-credito-api.py"
$env:ANTHROPIC_API_KEY = "llave-falsa-de-prueba"
Remove-Item Env:USAR_CREDITO_API -ErrorAction SilentlyContinue
'{"prompt":"hola"}' | python $HOOK; "codigo=$LASTEXITCODE"
Remove-Item Env:ANTHROPIC_API_KEY
Salida esperada: el mensaje GUARDIA DEL CRÉDITO: y codigo=2. La última línea borra la llave falsa de esa ventana.
c) Quedó registrado y Claude Code lo correría bien (lee settings.json, busca el hook y ejecuta su command tal como lo hará Claude Code, con la llave falsa):
python3 - <<'FIN'
import json, os, subprocess
ruta = os.path.expanduser("~/.claude/settings.json")
try:
datos = json.load(open(ruta, encoding="utf-8"))
except FileNotFoundError:
raise SystemExit("NO EXISTE " + ruta + ": repite el paso 2")
except json.JSONDecodeError as e:
raise SystemExit("JSON ROTO en " + ruta + " (" + str(e) + "): revisa comas y llaves")
grupos = datos.get("hooks", {}).get("UserPromptSubmit", [])
comandos = [h.get("command", "") for g in grupos for h in g.get("hooks", [])]
cmd = next((c for c in comandos if "guardia-credito-api.py" in c), None)
if not cmd:
raise SystemExit("NO REGISTRADO: falta el hook en UserPromptSubmit; repite el paso 2")
env = {k: v for k, v in os.environ.items() if k not in ("ANTHROPIC_AUTH_TOKEN", "USAR_CREDITO_API")}
env["ANTHROPIC_API_KEY"] = "llave-falsa-de-prueba"
r = subprocess.run(["bash", "-c", cmd], input='{"prompt":"hola"}', text=True, env=env, capture_output=True)
print("registrado:", cmd)
print("codigo=%d" % r.returncode)
FIN
Salida esperada: registrado: python3 ~/.claude/hooks/guardia-credito-api.py y codigo=2. Si sale JSON ROTO, NO EXISTE o NO REGISTRADO, corrige el paso 2: con el archivo roto, Claude Code no carga el guardia y la persona quedaría sin protección sin saberlo. En Windows con Git Bash, si python3 no existe, cambia python3 por python en la primera línea.
Cuando las tres partes pasen, avísale a la persona en una línea qué gana con esto.
Usar el crédito a propósito
Si alguna corrida sí debe cobrarse al crédito de API, se lanza con el permiso explícito en la misma línea:
USAR_CREDITO_API=1 claude
Para quitar una llave que se coló en la terminal actual, sin tocar nada más:
env -u ANTHROPIC_API_KEY -u ANTHROPIC_AUTH_TOKEN claude
✅ ¿Cómo sé que funcionó?
En el día a día no vas a notar nada: tus sesiones con tu plan funcionan igual que siempre. El guardia solo aparece si alguna sesión arranca con una llave de API en el ambiente sin tu permiso. En ese caso tu mensaje no se envía y ves un aviso que empieza con GUARDIA DEL CRÉDITO, con las dos salidas posibles: quitar la llave o, si es a propósito, volver a lanzar la sesión con USAR_CREDITO_API=1. 🌱
