Un solo archivo (llm.py) que habla directo con la API de Anthropic Messages usando el token OAuth que Claude Code guarda en ~/.claude/.credentials.json. Sin servidor, sin arranque: chat interactivo con memoria, one-shot, pipe, y bucle de tools propias (run_tool_loop). Empaqueta standalone la logica del grupo claude-direct del registry para poder distribuirla (basta llm.py + README.md, el receptor solo necesita httpx + Claude Code logueado).
llm — chat con Claude desde la terminal
CLI mínima y autocontenida para hablar con Claude directamente desde la terminal.
Usa el token que Claude Code ya guarda en tu máquina, así que no hay nada que
configurar: instala httpx, ejecútala y escribe.
Un solo archivo (llm.py), respuesta en streaming, arranque instantáneo (no lanza
ningún proceso de fondo).
Requisitos
- Python 3.9+
httpx→pip install httpx- Claude Code instalado y con sesión iniciada (para que exista
~/.claude/.credentials.json, de donde se lee el token automáticamente).
Instalar
pip install httpx
# copia llm.py donde quieras; opcionalmente hazlo ejecutable:
chmod +x llm.py
Usar
# Chat interactivo (con memoria de la conversación)
python3 llm.py
# Respuesta de una sola pregunta
python3 llm.py "que es un pseudo-terminal en una frase"
# Por pipe
echo "resume esto en 2 lineas: ..." | python3 llm.py
# Elegir modelo / system prompt
python3 llm.py --model claude-opus-4-8 --system "responde conciso" "explica los punteros"
Comandos del chat interactivo
| Comando | Acción |
|---|---|
/model <id> |
Cambia de modelo (claude-opus-4-8, claude-haiku-4-5-20251001, ...) |
/system <texto> |
Fija un system prompt |
/reset |
Empieza una conversación nueva |
/exit |
Salir |
Modelo por defecto: claude-haiku-4-5-20251001 (rápido). Usa --model claude-opus-4-8
para respuestas más potentes.
Tus propias herramientas (tools)
llm.py incluye run_tool_loop, un bucle agéntico donde defines tus tools y el
código que las ejecuta. Tú controlas qué puede hacer el modelo:
import llm
def get_time(inp):
import datetime
return {"now": datetime.datetime.now().isoformat()}
tools = [{
"name": "get_time",
"description": "Devuelve la fecha y hora actual",
"input_schema": {"type": "object", "properties": {}},
}]
res = llm.run_tool_loop(
messages=[{"role": "user", "content": "que hora es?"}],
tools=tools, dispatch={"get_time": get_time},
model="claude-haiku-4-5-20251001",
on_text=lambda d: print(d, end="", flush=True),
)
print("\n→", res["final_text"])
El modelo pedirá la tool, tu función la ejecuta, el resultado vuelve al modelo y responde. Añade las tools que quieras (consultar una base de datos, llamar a una API, leer un archivo...).
API del módulo
| Función | Para qué |
|---|---|
stream_messages(messages, model, system, tools, max_tokens, token) |
Stream crudo de eventos (text / tool_use / done / error) |
run_tool_loop(messages, tools, dispatch, ...) |
Bucle agéntico con tus tools |
load_oauth_token() |
Lee el token de ~/.claude/.credentials.json (refresh best-effort) |