Skip to main content
Glama

claude-handoff

claude-handoff: el ruidoso transcript fluye a través de chf y se convierte en un handoff.md limpio y una memoria de proyecto permanente

PyPI Python CI Downloads License: MIT

Convierte cualquier sesión de Claude Code — incluso una que se haya bloqueado — en un handoff.md limpio del que otra IA pueda continuar. Y dale a Claude Code memoria de proyecto permanente, destilada de tu propio historial.

chf

Eso es todo. Tu última sesión se convierte en handoff.md: la conversación sin el ruido, los archivos que cambiaron, los comandos que se ejecutaron — con instrucciones iniciales para el asistente receptor, para que puedas pegarlo directamente en Gemini, GPT, claude.ai o una sesión nueva de Claude Code sin ningún prompt adicional.

chf -o clipboard en acción — cinco segundos de sesión a handoff listo para pegar

Claude Code guarda cada sesión localmente como JSONL (~/.claude/projects/…/*.jsonl), lleno de llamadas a herramientas, resultados de herramientas, bloques de pensamiento y recordatorios del sistema. Los exportadores existentes vuelcan todo eso en markdown. claude-handoff en cambio produce un documento de handoff — y, como puede leer tu historial completo, también un resumen de memoria del proyecto.

  • Cero dependencias. Solo stdlib, Python 3.9+. Un paquete de nueve módulos — también distribuido como un script de un solo archivo generado que puedes curl y auditar.

  • Determinista por defecto. Sin llamadas a API, sin coste, funciona sin conexión.

  • --llm cuando quieres un resumen real. Claude, OpenAI o Gemini con tu propia clave de API — o --llm claude-cli, que ejecuta tu CLI de Claude Code instalado localmente con tu plan Pro/Max existente: sin clave de API en absoluto.

  • Sin ruido. Elimina resultados de herramientas, bloques de pensamiento, recordatorios del sistema, charla de subagentes, envoltorios de comandos de barra. Conserva la intención del usuario, las respuestas del asistente, los archivos modificados, los comandos ejecutados — incluidos los archivos y comandos de subagentes (agent-*.jsonl), cuyos transcripts completos quedan detrás de --include-sidechains.

  • Memoria de proyecto. chf --brief destila el historial COMPLETO de sesiones de un proyecto en un resumen vivo (decisiones, correcciones, convenciones, hilos abiertos — con citas de sesión); --install-brief-hook lo inyecta en cada nueva sesión de Claude Code, para que Claude empiece ya conociendo el proyecto.

  • Seguro para pegar. Las cadenas con aspecto de secreto (claves de API, tokens, password=…) se redactan de todas las salidas — el handoff que pegas en un chat web también es una salida. --anonymize va más allá para compartir públicamente.


Requisitos previos

Requisito

Mínimo

Comprobación

Notas

Python

3.9+

python3 --version

El único requisito duro

Claude Code

cualquiera

claude --version

Solo para --llm claude-cli (usa tu inicio de sesión Pro/Max)

pipx (recomendado)

cualquiera

pipx --version

pip install pipx — o usa brew / pip normal

Sin paquetes Python de terceros, nunca — todo funciona con la biblioteca estándar.

Related MCP server: Longhand

Instalación

pipx install claude-handoff        # or: pip install claude-handoff
brew install Vasilispapg/tap/claude-handoff   # Homebrew
# or just grab the generated single-file build — stdlib-only, auditable:
curl -O https://raw.githubusercontent.com/Vasilispapg/claude-handoff/main/single/claude_handoff.py
python3 claude_handoff.py --list

Instalar el paquete te da dos comandos idénticos: claude-handoff y el alias corto chf. Completado con tabulador:

eval "$(claude-handoff --completions zsh)"    # bash works too

60 segundos: elige tu situación

Una sesión se bloqueó, alcanzó el límite de uso, o cerraste la terminal:

chf -o clipboard

…luego pega en claude.ai, ChatGPT, Gemini — o en una sesión nueva de claude. Funciona con cualquier sesión antigua; no hace falta que nada estuviera instalado antes del bloqueo.

Mover trabajo de Claude Code a otro modelo:

chf --fit 32k -o clipboard         # sized to the receiver's context window

"¿En qué sesión hablamos de CORS?"

chf --list --grep "CORS"           # every match, with a 🔍 context preview
chf --grep "CORS"                  # or export the newest match directly

Dale a Claude Code memoria permanente de este proyecto:

chf --brief --llm claude-cli       # distill ALL sessions → one cited brief
chf --install-brief-hook           # every new session starts knowing it

Un resumen real en lugar del transcript (objetivo / decisiones / estado / siguiente):

chf --llm claude-cli               # your Claude Code login — no API key

Un chat web de claude.ai o ChatGPT en lugar de una sesión de terminal:

chf conversations.json --list      # each app's data export works as input
chf conversations.json --name "webhook bug"

Memoria de proyecto (--brief)

Claude Code olvida todo entre sesiones — pero todo el historial está en tu disco. chf --brief lee todas las sesiones del proyecto actual y escribe un documento de memoria en ~/.claude/briefs/<project>.md:

  • una línea de tiempo de sesiones factual + los archivos más tocados (determinista, gratis);

  • con --llm, una memoria destilada — decisiones con su porqué, errores corregidos, convenciones, hilos abiertos — cada viñeta citada con el id de sesión del que proviene (chf --name <id> abre la fuente).

chf --brief en acción — todo el historial del proyecto destilado en memoria citada

Las notas por sesión se guardan en caché, así que refrescar después de nuevas sesiones solo paga por las nuevas — y una sesión monstruosa (más de ~120k caracteres) se reduce con map-reduce dentro de la nota, para que la ruta de memoria nunca se trunque: nada se descarta silenciosamente, a cualquier tamaño.

chf --install-brief-hook

instala dos hooks: SessionStart inyecta el resumen como contexto (Claude empieza ya conociendo tu proyecto — se reinyecta también después de /compact), SessionEnd refresca automáticamente la parte factual gratis. Ningún LLM se ejecuta nunca desde un hook; la parte destilada se refresca solo cuando tú lo dices. El resumen lleva una marca de frescura, y tanto el archivo como la inyección avisan cuando existen sesiones más nuevas. Totalmente local; la redacción se aplica como en todas partes.

→ Mecánica paso a paso, la tabla de costes honesta y un recorrido completo de un día con ello: docs/GUIDE.md.

Hazlo automático

chf --install-hook                 # SessionEnd + PreCompact → handoff to ~/.claude/handoffs/
chf --install-brief-hook           # SessionStart/End + PreCompact → project memory (above)

PreCompact importa: justo antes de que Claude Code compacte el contexto de una sesión larga, ambos hooks capturan el estado — el handoff conserva el detalle que la compactación está a punto de exprimir, y el esqueleto del resumen se mantiene fresco a mitad de sesión.

Ambos editan ~/.claude/settings.json de forma no destructiva, son idempotentes y tienen flags --uninstall-* correspondientes. Los fallos de hooks nunca rompen la sesión anfitriona, y los hooks nunca disparan llamadas a LLM ni crean archivos por su cuenta.


Cómo se ve la salida

# Conversation handoff

> To the receiving assistant: … you are taking over …

## Session
- Project: /home/you/myapp (branch main)
- When: 2026-08-20 09:00 → 09:04
- Activity: 2 user messages, 4 assistant replies, 4 tool calls

## Files created / modified
- /home/you/myapp/auth.py

## Commands run
- python -m pytest tests/test_auth.py -q

_🤖 2 subagent(s) contributed to the work above (--include-sidechains for their transcripts)._

## Conversation
### 🧑 User
the login breaks on unicode passwords…
### 🤖 Assistant
Found it — ascii encoding. Changed to utf-8, tests pass.

Comandos comunes

chf                                # latest session → handoff.md
chf -i                             # numbered picker; "1,3" or "2-4" merges several
chf --list                         # what sessions do I have? (title · first prompt)
chf --list --format json           # the same, machine-readable
chf --name "login bug"             # newest session whose title/prompt matches
chf "login bug"                    # same — a non-path argument is a name search
chf --grep "CORS"                  # newest session that *talked about* CORS
chf --grep CORS --grep auth        # …that talked about BOTH (AND)
chf a.jsonl b.jsonl                # several paths → ONE merged handoff
chf --project myrepo               # latest session of a specific project
chf path/to/session.jsonl -o -     # explicit file → stdout
chf -o clipboard                   # straight to the clipboard — go paste it
chf --last 5                       # only the last 5 user turns
chf --since 2h                     # only the last 2 hours of the session
chf --fit 32k                      # sized to fit a 32k-token context
chf --include-tools                # keep collapsed per-tool-call detail
chf --include-sidechains           # append full subagent transcripts
chf --anonymize                    # public-safe: ~ paths, no emails/IPs/username
chf --project myrepo --merge       # whole project in ONE handoff, oldest → newest
chf --format json -o session.json  # machine-readable handoff

# LLM summaries (goal / decisions / current state / next steps):
chf --llm claude-cli               # your Claude Code login — no API key
chf --llm ollama                   # local model — fully offline
chf --llm claude                   # Anthropic API   (ANTHROPIC_API_KEY)
chf --llm openai --model gpt-4o    # OpenAI API      (OPENAI_API_KEY)
chf --llm gemini --with-transcript # Google API      (GEMINI_API_KEY)
chf --llm claude-cli --focus "emphasize the API decisions"

# project memory:
chf --brief                        # free factual brief (timeline + files)
chf --brief --llm claude-cli       # + distilled decisions/fixes/conventions

¿Dónde busca? Las sesiones viven en el almacén global de Claude Code (~/.claude/projects), así que puedes ejecutar chf desde cualquier lugar. Si tu directorio actual es un proyecto (o una subcarpeta de uno), se limita a las sesiones de ese proyecto; una "carpeta maestra" padre se limita a todos los proyectos bajo ella; --any ignora el directorio por completo. La auto-selección omite sesiones casi vacías (como el stub que deja claude /login) para que "última" signifique tu última conversación real — una ruta explícita, --name o -i siempre gana.

Sesiones grandes. Los transcripts que superan una pasada (~400k caracteres) se resumen al estilo map-reduce: notas por fragmento, luego una síntesis — nada se descarta silenciosamente, y los fragmentos terminados se guardan en caché en ~/.cache/claude-handoff para que una ejecución interrumpida se reanude gratis. Los fragmentos se ejecutan en paralelo 4 vías en proveedores de API; claude-cli y ollama permanecen secuenciales por diseño. En una terminal obtienes una barra de progreso en vivo:

[█████████░░░░░░░░░░░░░░░] 3/9 chunks | 4m12s elapsed | ~8m left | summarizing part 4/8 (199,867 chars)…

Las sesiones con datos de usage de API también reciben una línea de Tokens en el encabezado, y cada ejecución informa el tamaño aproximado en tokens de la salida.

Privacidad y confianza cero

  • No se envía nada a ningún sitio a menos que pases --llm — el modo determinista es totalmente sin conexión.

  • La redacción está activada en cada salida, no solo en el tráfico de LLM: las cadenas con forma de secreto (claves de API, tokens, JWTs, password=…) se eliminan del handoff en sí, de los archivos de hooks y de las respuestas MCP — un documento pegado también es una salida. --no-redact opta por salir por ejecución (y deliberadamente no está permitido en el archivo de configuración).

  • --anonymize además colapsa tu directorio personal a ~ y reemplaza correos electrónicos, IPv4 y tu nombre de usuario con marcadores de posición — para pegar en issues y foros públicos.

  • --llm claude-cli y --llm ollama mantienen todo dentro de cuentas y máquinas que ya controlas.

  • Defensa contra inyección de prompts: los transcripts suelen incrustar texto no confiable (páginas web en resultados de herramientas, READMEs pegados). Cada prompt que consume un transcript, el preámbulo del handoff y el envoltorio de inyección del resumen enmarcan ese contenido como datos, no instrucciones — fijado por pruebas. Una mitigación, no una prueba; el analizador en sí nunca ejecuta nada.

Configuración (opcional)

Pon los valores predeterminados que siempre usas en ~/.config/claude-handoff/config.json (los flags de CLI siempre ganan; CLAUDE_HANDOFF_CONFIG anula la ruta):

{ "llm": "claude-cli", "fit": "32k", "include_tools": true }

Claves permitidas: llm, model, fit, output, include_tools, include_sidechains, max_chars, anonymize, focus. Los interruptores de seguridad (no_redact) están deliberadamente no configurables — debilitar la redacción debe ser una elección explícita por ejecución. Una configuración rota avisa y se ignora, nunca es fatal.

Variables de entorno

Variable

Propósito

ANTHROPIC_API_KEY / CLAUDE_API

clave para --llm claude (la primera que se establece gana)

OPENAI_API_KEY / GPT_API

clave para --llm openai

GEMINI_API_KEY / GOOGLE_API_KEY / GEMINI_API

clave para --llm gemini

OLLAMA_MODEL / OLLAMA_BASE_URL

modelo y endpoint de Ollama local

CLAUDE_HOME

inicio de Claude Code (por defecto ~/.claude) — donde viven sesiones, handoffs y resúmenes

CLAUDE_HANDOFF_CACHE

directorio de caché de fragmentos/notas (por defecto ~/.cache/claude-handoff)

CLAUDE_HANDOFF_CONFIG

ruta del archivo de configuración (por defecto ~/.config/claude-handoff/config.json)

CLAUDE_HANDOFF_DEBUG

1 = igual que --debug; también activa los hooks (añádelo al comando del hook o a tu entorno de shell)

claude-cli no necesita variable — ejecuta tu Claude Code CLI instalado, facturado a tu plan Pro/Max (ejecuta claude una vez para iniciar sesión).

Servidor MCP

Cualquier cliente MCP (Claude Desktop, Claude Code, …) puede obtener handoffs directamente:

claude mcp add claude-handoff -- claude-handoff --mcp

Herramientas: list_sessions (qué hay en esta máquina) y handoff (construye el documento para una sesión por nombre/proyecto/ruta; pasa anonymize para una versión compartible). Determinista por defecto — un cliente MCP solo puede disparar resúmenes con LLM cuando inicias el servidor con --allow-llm.

Solución de problemas

claude-handoff: command not found después de pip install pip coloca los scripts en un directorio bin de usuario que puede no estar en PATH. Usa pipx install claude-handoff o brew — ambos gestionan PATH — o añade ~/.local/bin (Linux) / ~/Library/Python/3.x/bin (macOS) a tu PATH.

"No sessions found under ~/.claude/projects" Estás en una máquina (o usuario) que no ha ejecutado Claude Code, o tu almacén vive en otro lugar — apunta CLAUDE_HOME a él. Dentro de una carpeta de proyecto la herramienta se limita a ese proyecto; pasa --any para buscar en todo.

Eligió la sesión equivocada "Última" omite stubs casi vacíos pero sigue siendo solo el archivo más nuevo. Usa -i (selector), --name "parte del título", o --grep "algo dicho".

--llm claude-cli falla o pide autenticación Ejecuta claude una vez e inicia sesión (/login). Funciona incluso cuando se invoca desde dentro de una sesión de Claude Code: las variables de entorno CLAUDE* heredadas se eliminan para que la CLI anidada se autentique como una nueva.

"Establece ANTHROPIC_API_KEY … para usar --llm claude" Los proveedores de API necesitan una clave en el entorno; consulta la tabla anterior. ¿Sin clave? Usa --llm claude-cli (suscripción) o --llm ollama (local).

--fit se niega a combinarse con --llm / --max-chars --fit ajusta el resultado determinista por sí solo. Si no lo escribiste, tu archivo de configuración probablemente establece fit; anula eliminando un --max-chars explícito, o elimina la clave.

La inyección del brief advierte "existen sesiones más nuevas que este brief" Eso es el sello de frescura haciendo su trabajo: ejecuta chf --brief --llm claude-cli para re-destilar (en caché: solo se pagan las sesiones nuevas). La parte factual se actualiza sola si el hook de SessionEnd está instalado.

¿Algo no hizo nada en silencio? Las rutas tolerantes por diseño (líneas JSONL corruptas, archivos ilegibles, problemas de caché) nunca detienen la ejecución; añade --debug (o CLAUDE_HANDOFF_DEBUG=1) para ver exactamente qué se omitió y por qué. Los hooks siempre informan sus errores en stderr mientras salen con 0.

Caracteres corruptos en Windows Establece PYTHONUTF8=1 (el CI ejecuta toda la suite así).

Referencia completa de banderas

Bandera

Significado

--list

lista sesiones (fecha, tamaño, proyecto, título · primer prompt); con un conversations.json, lista sus chats

--name QUERY

elige la sesión más reciente (o conversación web) cuyo título/primer prompt contenga QUERY

--grep TEXT

elige la sesión más reciente cuya conversación contenga TEXT (repite la bandera para exigir TODOS los términos); con --list/-i muestra cada coincidencia con una vista previa 🔍

--project NAME

elige la última sesión cuya ruta de proyecto contenga NAME (repetible: varios proyectos juntos)

-i / --interactive

elige sesión(es) de una lista numerada: 1,3 o 2-4 fusiona varias en un solo handoff

--any

ignora el directorio actual; considera las sesiones de todos los proyectos

--last N / --since 2h

conserva solo la cola de la conversación (N turnos de usuario / una ventana de tiempo)

--merge

fusiona todas las sesiones en el alcance en UN solo handoff (marcadores de corte de sesión, actividad sumada)

--brief

destila toda la historia del proyecto en ~/.claude/briefs/<project>.md (determinista; --llm para destilación real)

--install-brief-hook / --uninstall-brief-hook

hooks de memoria del proyecto: inyecta el brief en SessionStart, actualiza automáticamente los hechos en SessionEnd

--install-hook / --uninstall-hook

escribe automáticamente un handoff en ~/.claude/handoffs/ cuando cada sesión termina

--format md|json

markdown (predeterminado) o JSON legible por máquina; también se aplica a --list

-o FILE / -o - / -o clipboard

archivo de salida / stdout / portapapeles (predeterminado handoff.md)

--fit TOKENS

ajusta el handoff determinista a un presupuesto de tokens (32k, 128k, 1m) ajustando la truncación de la transcripción

--max-chars N

limita la sección de transcripción (predeterminado 80 000; conserva el inicio + el final reciente)

--include-tools

bloques <details> colapsados con cada llamada a herramienta

--include-sidechains

añade transcripciones completas de subagentes (sidechains en línea y <session-id>/subagents/agent-*.jsonl); su actividad de archivos/comandos siempre se cuenta

--llm claude|openai|gemini|claude-cli|ollama

resumen LLM en lugar de transcripción limpia sin procesar

--model ID

anula el modelo LLM

--focus TEXT

instrucciones adicionales para el resumen (p. ej. --focus "enfatiza las decisiones de API")

--with-transcript

con --llm, también añade la transcripción limpia

--anonymize

elimina la identidad para compartir públicamente: rutas de inicio → ~, correos/IPs/nombre de usuario → marcadores de posición

--no-redact

conserva cadenas que parecen secretos (predeterminado: redactadas de cada salida, LLM o no)

--no-cache

desactiva la caché de notas de fragmentos (~/.cache/claude-handoff)

--mcp

ejecuta como servidor MCP sobre stdio

--allow-llm

con --mcp: permite que la herramienta handoff ejecute resúmenes LLM (aceptación explícita)

--completions bash|zsh

imprime un fragmento de autocompletado

--debug

informa fallos tolerados (líneas corruptas, archivos ilegibles) en stderr: nada se vuelve fatal

Hoja de ruta

  • Exportaciones de Gemini como entrada (Google Takeout solo incluye HTML: trae una exportación real y redactada para construir contra ella)

  • Cadenas de sesión: detecta automáticamente sesiones continuadas con /compact y ofrece fusionar el linaje (--follow)

Se aceptan PRs.

Cómo se compara

Este espacio no está vacío: está fragmentado. Elige la herramienta que se ajuste a tu situación:

  • Exportadoresclaude-conversation-extractor, claude-code-log, claude-code-transcripts, claude-to-markdown — convierten transcripciones en Markdown/HTML legible, con ruido de herramientas incluido, sin marco de handoff.

  • Movedores de sesiones entre CLIscli-continues (npm i -g continues) lee los almacenes de sesiones nativos de 16 CLIs de codificación (incluido Claude Code) e inyecta un documento de contexto en otra herramienta terminal. Excelente para Claude Code → Codex/Cursor/Gemini CLI; pero no puede apuntar a chats web, no hace resúmenes LLM y necesita Node 22.5+.

  • Habilidades/plugins de handoff en sesiónthepushkarp/handoff, claude-session-handoff, claude-code-handoff — geniales si recuerdas ejecutarlos antes de que termine la sesión; el modelo escribe el resumen usando el contexto de tu sesión, y la salida apunta a la próxima sesión de Claude.

  • Extensiones de navegador — Handoff, LLM Context Bridge, ContextSwitch — transfieren chats web entre ChatGPT/Claude/Gemini; no pueden ver sesiones de Claude Code.

claude-handoff es la esquina post-hoc y de pegar en cualquier lugar de este mapa: funciona sobre el JSONL después del hecho — sesiones antiguas, sesiones bloqueadas, sesiones que alcanzaron el límite de uso — no necesita nada instalado de antemano, cuesta cero tokens por defecto, puede escribir un resumen real cuando lo pides (--llm), y produce un documento que cualquier modelo receptor puede recoger, incluyendo claude.ai, ChatGPT y Gemini en el navegador o en tu teléfono. Y con --brief, es el único que convierte esa historia en memoria de proyecto permanente.

Desarrollo

git clone https://github.com/Vasilispapg/claude-handoff && cd claude-handoff
python3 -m unittest discover -s tests -v      # the whole suite (no deps needed)
python3 -m claude_handoff tests/fixtures/agent_session.jsonl -o -   # smoke run
python3 scripts/build_single.py --check       # single-file build is fresh
uvx ruff check claude_handoff scripts tests   # lint (config in pyproject)

El código en tiempo de ejecución vive en el paquete claude_handoff/; single/claude_handoff.py es generado — recompílalo con python3 scripts/build_single.py después de cualquier cambio en el paquete (el CI falla si está desactualizado). El nuevo comportamiento del parser comienza con un fixture redactado en tests/fixtures/ — consulta CONTRIBUTING.md y AGENTS.md (instrucciones e invariantes para contribuyentes humanos y de IA).

Aprende más

docs/GUIDE.mdun día con claude-handoff: recorrido, cómo funciona --brief paso a paso, tabla de costos honesta, chuleta · INDEX.md — mapa de archivos · docs/DEVELOPMENT.md — arquitectura, notas sobre el esquema JSONL, decisiones de diseño · AGENTS.md — guía para contribuyentes de agentes de IA · CONTRIBUTING.md · CHANGELOG.md

Licencia

MIT


mcp-name: io.github.Vasilispapg/claude-handoff

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
18Releases (12mo)
Commit activity

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Persistent memory for Claude Code. Automatically indexes every conversation and provides production-grade hybrid search (BM25 + vectors + reranker) via MCP tools. 100% local, zero config, zero API keys, zero invoice.
    16
    55
    7
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Persistent local memory for Claude Code that indexes every session's JSONL file verbatim into SQLite + ChromaDB. Exposes 17 MCP tools for semantic recall, deterministic file replay, and fuzzy "do you remember when..." queries across your entire session history — no API calls, nothing leaves the machine.
    17
    12
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Persistent memory + FTS5 full-text search for Claude Code conversation history. Indexes ~/.claude/projects/ JSONL into SQLite, exposes 10 MCP tools (store/recall/search memories, browse sessions, get summaries) plus prompts. Includes a web UI for visual exploration
    10
    89
    92
    MIT

View all related MCP servers

Related MCP Connectors

  • Hosted MCP memory: save sessions/decisions once, search from Claude, Cursor, ChatGPT. EU-hosted FTS.

  • Persistent context for Claude. Your AI always knows your projects and next actions across sessions.

  • One memory, every AI: Claude, ChatGPT, Perplexity, Gemini, Cursor, OpenClaw, Hermes, any MCP client.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Vasilispapg/claude-handoff'

If you have feedback or need assistance with the MCP directory API, please join our Discord server