Claude Checkpoint MCP

Guarda el estado de la sesión de Claude Code (objetivo, tareas, decisiones, archivos modificados, comandos recientes) en un archivo local y lo restaura como un resumen compacto de reanudación tras un fallo, /clear o límite de contexto. Solo local, secretos redactados.

Documentación

claude-checkpoint-mcp

Guarda el estado de tu sesión de Claude Code localmente, para que un fallo, /clear, o el límite de contexto no obliguen a Claude a reconstruir el contexto desde cero.

License: MIT Node.js ≥ 20 MCP M8ven Score

claude-checkpoint-mcp es un servidor local de Model Context Protocol con dos herramientas:

  • save_session_checkpoint escribe el estado de trabajo de tu sesión en un pequeño archivo JSON en el proyecto.
  • load_session_checkpoint convierte ese archivo de nuevo en un resumen compacto para reanudar.

Se ejecuta completamente en tu máquina. Nada se envía a ningún lugar.


Contenido


Por qué: deja de pagar dos veces por el mismo contexto

Una sesión larga de Claude Code acumula mucho contexto:

  • lo que estás tratando de hacer;
  • qué enfoques ya fallaron;
  • qué archivos importan;
  • qué prueba sigue en rojo.

Varias cosas pueden borrar todo eso a mitad de tarea:

  • un fallo de terminal, caída de SSH o suspensión del portátil;
  • quedarse sin ventana de contexto;
  • un /clear para obtener una ventana nueva.

La siguiente sesión comienza en frío. Para volver a donde estabas, Claude tiene que reconstruir ese contexto:

  • Releyendo archivos para averiguar qué cambió y por qué. Cada lectura de archivo son tokens de entrada.
  • Reejecutando exploración: grep, git diff, ls, ejecuciones de pruebas, todo solo para redescubrir el estado.
  • Reexplicando. Vuelves a escribir el objetivo, las restricciones y los callejones sin salida, o Claude redescubre los callejones sin salida de la manera difícil.

Cada una de esas acciones reenvía la conversación creciente como entrada, por lo que el costo se acumula.

claude-checkpoint-mcp reemplaza esa reconstrucción por una lectura pequeña y estructurada:

Sin checkpointCon load_session_checkpoint
Restaurar el objetivo y las restriccionesLos vuelves a escribir, o Claude los infiereUna sección del resumen
Saber qué está hecho vs. pendienteRe-derivado del código y gitLista de tareas con estados
Saber qué archivos importanRelectura ampliaLista exacta de archivos tocados, con notas
Saber qué cambió desde entoncesReleer todo para estar seguroSolo los archivos cuyo contenido realmente cambió se marcan
Recordar intentos fallidosA menudo repetidosRegistrados en Decisiones y trampas

El resumen de reanudación para una sesión típica es de aproximadamente 1.2 KB de markdown, unos pocos cientos de tokens. El ejemplo a continuación es salida real de ese tamaño.

El mayor ahorro proviene de la detección de deriva. Al guardar, el servidor registra un hash de contenido para cada archivo con cambios sin confirmar. Al cargar, compara esos hashes con el árbol de trabajo y le dice a Claude exactamente qué archivos cambiaron después del checkpoint. Todo lo demás en el resumen se puede confiar tal cual, por lo que Claude relee solo lo que tiene que releer.


Cómo funciona

  Session 1                                     Session 2 (after crash / /clear)
  ─────────                                     ────────────────────────────────
  Claude ──save_session_checkpoint──┐       ┌──load_session_checkpoint── Claude
         goal, tasks, summary,      │       │   compact markdown brief
         next steps, decisions,     ▼       │   + "changed since checkpoint"
         files, commands      ┌─────────────────────┐
                              │ <project>/          │
     server adds:             │ .claude-checkpoint  │◀── git: branch, HEAD,
     git branch/HEAD,         │ .claude-checkpoint  │    dirty files + hashes
     dirty files + hashes,    │   .prev (backup)    │
     redacts secrets          └─────────────────────┘
  • Claude aporta el significado: el objetivo, el progreso, las decisiones, los siguientes pasos y qué comandos importaron.
  • El servidor aporta los hechos: rama git y HEAD, cada archivo sin confirmar o sin rastrear con su hash de contenido, y marcas de tiempo.
  • Las instrucciones del servidor enseñan a Claude cuándo actuar. Se le dice a Claude que cargue al inicio de una sesión y que guarde después de hitos, antes de operaciones arriesgadas y cuando la conversación se vuelve larga. No necesita que se le pida cada vez.

Instalación

Requisitos: Node.js 20+ y git. Git es opcional, pero sin él pierdes la detección de deriva.

git clone https://github.com/tenlean/claude-checkpoint-mcp.git
cd claude-checkpoint-mcp
npm install
npm run build

El punto de entrada del servidor ahora está en dist/index.js.


Configuración

Claude Code

Como plugin (lo más fácil). Este repositorio también es un marketplace de plugins de Claude Code. No necesitas clonar ni compilar nada:

claude plugin marketplace add tenlean/claude-checkpoint-mcp
claude plugin install claude-checkpoint-mcp@tenlean

Reinicia Claude Code, luego /mcp debería mostrar plugin:claude-checkpoint-mcp:claude-checkpoint como conectado.

Configuración manual. Si clonaste el repositorio, registra el servidor una vez para tu cuenta de usuario, para que esté disponible en todos los proyectos:

# Run from the claude-checkpoint-mcp directory
claude mcp add --scope user checkpoint -- node "$PWD/dist/index.js"

Usa una ruta absoluta. Un servidor a nivel de usuario se lanza desde cualquier proyecto en el que abras Claude Code. Una ruta relativa como ./dist/index.js se resolvería contra ese proyecto, no contra este repositorio. "$PWD/dist/index.js" se expande a la ruta absoluta cuando ejecutas el comando, que es lo que se guarda.

Verifica que esté registrado:

claude mcp list

Dentro de una sesión, /mcp debería mostrar checkpoint como conectado.

Alternativa a nivel de proyecto. Para compartir el servidor con un equipo a través del control de versiones, agrégalo al .mcp.json del proyecto:

{
  "mcpServers": {
    "checkpoint": {
      "command": "node",
      "args": ["/absolute/path/to/claude-checkpoint-mcp/dist/index.js"]
    }
  }
}

De cualquier manera, agrega los archivos de checkpoint al .gitignore del proyecto, o a tu gitignore global:

.claude-checkpoint*

Claude Desktop (claude_desktop_config.json)

Abre el archivo de configuración:

SORuta
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json

Agrega el servidor bajo mcpServers, usando la ruta absoluta a tu compilación local:

{
  "mcpServers": {
    "checkpoint": {
      "command": "node",
      "args": ["/absolute/path/to/claude-checkpoint-mcp/dist/index.js"],
      "env": {
        "CHECKPOINT_PROJECT_ROOT": "/absolute/path/to/your/project"
      }
    }
  }
}

Reinicia Claude Desktop después de guardar el archivo.

Claude Desktop no tiene noción de "proyecto actual". Usa CHECKPOINT_PROJECT_ROOT para establecer el proyecto predeterminado, o haz que Claude pase projectRoot en cada llamada ("guarda un checkpoint para /home/me/code/my-app"). Consulta resolución de raíz de proyecto.

Otros clientes MCP

Cualquier cliente MCP que admita el transporte stdio puede ejecutar el servidor:

node /absolute/path/to/claude-checkpoint-mcp/dist/index.js

Uso

Las instrucciones integradas del servidor cubren los casos comunes automáticamente. También puedes pedirle a Claude directamente.

Guardar:

  • "Registra nuestro progreso."
  • "Guarda un checkpoint antes de ejecutar la migración."
  • "Actualiza el checkpoint. Fusiona lo que acabamos de hacer."

Reanudar (en una sesión nueva):

  • "Reanuda donde lo dejamos."
  • "Carga el checkpoint y continúa."

Ejemplo de resumen de reanudación

Esta es salida real de load_session_checkpoint. En el escenario, un archivo se confirmó sin cambios después del guardado, y un compañero luego editó session.ts:

# Resuming: my-app (checkpoint saved 2m ago, 2026-10-08 02:23:55 UTC)
Branch `feat/github-oauth` @ b2ef1b591 (uncommitted changes)

## Goal
Add GitHub OAuth login with persistent sessions

## Tasks
- [x] OAuth callback route
- [~] Session cookie persistence
- [ ] Logout endpoint

## Where things stand
Callback exchanges the code and creates a session, but the cookie is dropped on reload. Suspect SameSite/secure flags in dev.

## Next steps
1. Set sameSite: 'lax' and secure only in production in src/auth/session.ts
2. Re-run npm test -- auth
3. Start the logout endpoint

## Decisions & gotchas
- Use iron-session, not express-session (needs edge runtime support)
- Don't mock the GitHub API in e2e tests; use the recorded fixtures in test/fixtures

## Files touched (3)
- src/auth/session.ts (M) — cookie options
- src/auth/callback.ts (M)
- src/auth/session.spec.ts (??)

## Recent commands (last 2, oldest first)
- ✓ `GITHUB_CLIENT_SECRET=«redacted» npm run dev`
- ✗ exit 1 `npm test -- auth` — 2 failing in session.spec.ts: cookie missing after reload

## Since this checkpoint
- 1 new commit(s) on HEAD
- ⚠ Changed after the checkpoint, re-read before editing: `src/auth/session.ts`

callback.ts se confirmó después del guardado, pero su contenido no cambió, por lo que no se marca. Solo session.ts necesita ser releído.

Marcadores de tareas: [x] hecho · [~] en progreso · [ ] pendiente · [!] bloqueado.


Referencia de herramientas y ejemplos

save_session_checkpoint

Escribe <projectRoot>/.claude-checkpoint.

ParámetroTipoRequeridoDescripción
goalstring (≤ 500)✅Objetivo principal de la sesión
tasks{ description, status }[] (≤ 30)status: pending · in_progress · done · blocked
summarystring (≤ 4000)Dónde están las cosas: qué funciona, qué está roto, en qué estabas en medio
nextStepsstring[] (≤ 20)Próximas acciones ordenadas para quien reanude
decisionsstring[] (≤ 20)Decisiones clave, restricciones, callejones sin salida a evitar
modifiedFiles{ path, note? }[] (≤ 100)Archivos para anotar, o archivos confirmados para incluir. Los cambios git sin confirmar se detectan automáticamente. Las rutas absolutas dentro del proyecto se almacenan como relativas.
recentCommands{ command, exitCode?, note? }[] (≤ 50)Comandos significativos, del más antiguo al más reciente. Los secretos se redactan.
mode"replace" | "merge"Predeterminado replace. Ver abajo.
projectRootstring (absoluta)Anula la resolución de raíz

Guardado completo:

{
  "goal": "Add GitHub OAuth login with persistent sessions",
  "tasks": [
    { "description": "OAuth callback route", "status": "done" },
    { "description": "Session cookie persistence", "status": "in_progress" },
    { "description": "Logout endpoint", "status": "pending" }
  ],
  "summary": "Callback exchanges the code and creates a session, but the cookie is dropped on reload. Suspect SameSite/secure flags in dev.",
  "nextSteps": [
    "Set sameSite: 'lax' and secure only in production in src/auth/session.ts",
    "Re-run npm test -- auth"
  ],
  "decisions": ["Use iron-session, not express-session (needs edge runtime support)"],
  "modifiedFiles": [{ "path": "src/auth/session.ts", "note": "cookie options" }],
  "recentCommands": [
    { "command": "GITHUB_CLIENT_SECRET=gh_live_8f2a91 npm run dev", "exitCode": 0 },
    { "command": "npm test -- auth", "exitCode": 1, "note": "2 failing in session.spec.ts" }
  ]
}

Respuesta (texto mostrado al modelo):

Checkpoint saved to /home/me/code/my-app/.claude-checkpoint (2202 bytes, replace).
3 task(s), 3 file(s), 2 command(s) on feat/github-oauth@b2ef1b591.
⚠ Redacted 1 secret-looking value(s).

Actualización incremental con merge:

{
  "goal": "Add GitHub OAuth login with persistent sessions",
  "mode": "merge",
  "tasks": [
    { "description": "Session cookie persistence", "status": "done" },
    { "description": "Logout endpoint", "status": "in_progress" }
  ],
  "recentCommands": [{ "command": "npm test -- auth", "exitCode": 0, "note": "all green" }]
}
Camporeplacemerge
goalestablecidoestablecido
tasksestablecidoactualizado al hacer coincidir description; las nuevas tareas se agregan
summary, nextStepsestablecidoreemplazados si se proporcionan, de lo contrario se conservan
decisionsestablecidoagregado (deduplicado)
recentCommandsestablecidoagregado; los más antiguos se eliminan más allá de 50
modifiedFilesescaneo git fresco + proporcionadoescaneo git fresco + proporcionado + registrado previamente
id, createdAtnuevoconservado

Salida estructurada (structuredContent):

{
  "path": "/home/me/code/my-app/.claude-checkpoint",
  "bytes": 2202,
  "mode": "replace",
  "counts": { "tasks": 3, "modifiedFiles": 3, "recentCommands": 2, "redactions": 1 },
  "warnings": ["Redacted 1 secret-looking value(s)."]
}

load_session_checkpoint

Solo lectura. Lee el checkpoint, verifica la deriva y devuelve el resumen.

ParámetroTipoRequeridoDescripción
format"brief" | "full"Predeterminado brief (markdown, como arriba). full devuelve el JSON completo del checkpoint más la deriva.
projectRootstring (absoluta)Anula la resolución de raíz

Ejemplos:

{}
{ "format": "full", "projectRoot": "/home/me/code/my-app" }

Salida estructurada (structuredContent):

{
  "found": true,
  "path": "/home/me/code/my-app/.claude-checkpoint",
  "fromBackup": false,
  "updatedAt": "2026-10-08T02:23:55.477Z",
  "drift": {
    "branchChanged": false,
    "currentBranch": "feat/github-oauth",
    "commitsSince": 1,
    "changedSince": ["src/auth/session.ts"]
  },
  "warnings": []
}

Si no existe un checkpoint, la herramienta devuelve found: false con un mensaje de "nada que reanudar". Eso no se trata como un error.

Cómo se elige la raíz del proyecto

  1. El argumento projectRoot
  2. La variable de entorno CHECKPOINT_PROJECT_ROOT
  3. La primera raíz file:// del cliente, si el cliente admite raíces MCP
  4. El directorio de trabajo del proceso del servidor

La ruta debe ser absoluta y debe ser un directorio existente. Los enlaces simbólicos se resuelven. El archivo siempre se escribe exactamente en <root>/.claude-checkpoint.


El archivo .claude-checkpoint

Esto es JSON simple y versionado, por lo que es fácil de leer, comparar o editar a mano. Ejemplo real:

{
  "version": 1,
  "id": "ee5507c0-855e-44a5-85c1-d97b767537c9",
  "createdAt": "2026-10-08T02:23:55.477Z",
  "updatedAt": "2026-10-08T02:23:55.477Z",
  "generator": { "name": "claude-checkpoint-mcp", "version": "0.1.0" },
  "project": { "name": "my-app" },
  "git": {
    "branch": "feat/github-oauth",
    "head": "b2ef1b5919ee5d456ea146c9362a7abc92b1e556",
    "dirty": true
  },
  "goal": {
    "primary": "Add GitHub OAuth login with persistent sessions",
    "tasks": [
      { "description": "OAuth callback route", "status": "done" },
      { "description": "Session cookie persistence", "status": "in_progress" },
      { "description": "Logout endpoint", "status": "pending" }
    ]
  },
  "summary": "Callback exchanges the code and creates a session, but the cookie is dropped on reload. Suspect SameSite/secure flags in dev.",
  "nextSteps": [
    "Set sameSite: 'lax' and secure only in production in src/auth/session.ts",
    "Re-run npm test -- auth",
    "Start the logout endpoint"
  ],
  "decisions": [
    "Use iron-session, not express-session (needs edge runtime support)",
    "Don't mock the GitHub API in e2e tests; use the recorded fixtures in test/fixtures"
  ],
  "modifiedFiles": [
    { "path": "src/auth/session.ts", "status": "M", "source": "git", "note": "cookie options", "hash": "9ec893ef673dac860e7e2b6fcaad602983eeb0b1" },
    { "path": "src/auth/callback.ts", "status": "M", "source": "git", "hash": "f3ecc849c3875d4f11bb42ae0e5ab6c71931d7f1" },
    { "path": "src/auth/session.spec.ts", "status": "??", "source": "git", "hash": "9daeafb9864cf43055ae93beb0afd6c7d144bfa4" }
  ],
  "recentCommands": [
    { "command": "GITHUB_CLIENT_SECRET=«redacted» npm run dev", "exitCode": 0, "at": "2026-10-08T02:23:55.477Z" },
    { "command": "npm test -- auth", "exitCode": 1, "note": "2 failing in session.spec.ts: cookie missing after reload", "at": "2026-10-08T02:23:55.477Z" }
  ],
  "meta": { "redactions": 1, "truncated": false }
}
CampoNotas
versionVersión del esquema. Las versiones anteriores se migran al cargar; las versiones desconocidas se rechazan.
id / createdAtEstables entre guardados de merge; nuevos en replace
gitnull fuera de un repositorio git, o antes del primer commit del repositorio
modifiedFiles[].statusCódigo porcelain de git (M, A, D, R, ??), o M para archivos reportados solo por Claude
modifiedFiles[].sourcegit (detectado) o agent (reportado por Claude, o arrastrado de una fusión anterior)
modifiedFiles[].hashHash de blob git del contenido del árbol de trabajo al guardar; impulsa la detección de deriva
meta.truncatedtrue si se eliminó algo para ajustarse a los límites de lista o tamaño

Las rutas siempre son relativas a la raíz del proyecto. El archivo nunca almacena rutas absolutas.


Seguridad y privacidad

  • Solo local. No hay llamadas de red. El servidor lee metadatos de git y un archivo, y escribe un archivo.
  • Redacción de secretos. Lo siguiente se reemplaza con «redacted» en comandos, notas, resúmenes, tareas y decisiones antes de que cualquier cosa toque el disco:
    • asignaciones de *_KEY=, *_TOKEN=, *_SECRET=, *PASSWORD=, incluidas las formas Header: value y JSON
    • encabezados Authorization: Bearer …
    • credenciales en URLs (postgres://user:pass@…)
    • banderas --password / --token / --api-key / --secret
    • tokens simples de sk-…, ghp_…, github_pat_…, AKIA… y xox?-… La redacción es una red de seguridad, no una garantía, así que mantén el archivo fuera del control de versiones.
  • Escrituras seguras ante fallos, solo para el propietario. Los archivos se escriben con el modo 0600. Cada guardado escribe un archivo temporal, lo sincroniza (fsync) y lo renombra en su lugar, de modo que un fallo a mitad del guardado no puede dejar un punto de control a medias.
  • Copia de seguridad automática. El punto de control válido anterior se conserva como .claude-checkpoint.prev. Si el archivo principal está corrupto, la carga recurre a la copia de seguridad y lo indica. Un archivo corrupto nunca sobrescribe una copia de seguridad buena.
  • Tamaño limitado. Cada campo tiene un límite de longitud, y el archivo está limitado a 64 KB (los comandos más antiguos se eliminan primero), de modo que un punto de control no puede convertirse en un sumidero de tokens.
  • Sin shell. Git se ejecuta mediante execFile con un tiempo de espera de 3 segundos y GIT_OPTIONAL_LOCKS=0, por lo que nunca compite con tus propios comandos de git.
  • No toca tu configuración. Si el punto de control no está ignorado por git, la respuesta de guardado te lo advierte. Nunca edita .gitignore por ti.
  • Seguro con llamadas a herramientas en paralelo. Las llamadas a herramientas se serializan dentro del servidor, de modo que los guardados concurrentes de merge no pueden perder actualizaciones.

Solución de problemas

SíntomaSolución
checkpoint no aparece en /mcpEjecuta claude mcp list y comprueba que la ruta sea absoluta y que dist/index.js exista (npm run build).
El punto de control se escribe en el directorio incorrectoEl servidor recurrió a su directorio de trabajo. Pasa projectRoot, o establece CHECKPOINT_PROJECT_ROOT.
projectRoot must be an absolute pathUsa una ruta completa como /home/me/code/app, no ./app.
El resumen dice "Saved commit … is no longer reachable"La rama se reescribió o se reinició después del guardado. La deriva no se puede calcular contra el historial, así que trata los archivos marcados como que necesitan una relectura.
Advertencia: "not git-ignored"Añade .claude-checkpoint* a .gitignore.
Sin sección "Since this checkpoint"El proyecto no es un repositorio git, o no tenía confirmaciones en el momento del guardado.

Los registros del servidor van a stderr. Stdout está reservado para el protocolo MCP.


Desarrollo

npm run typecheck   # strict TypeScript, src + tests
npm test            # unit tests + in-memory MCP end-to-end tests (vitest)
npm run build       # compile to dist/
npm run inspect     # open the MCP Inspector against dist/index.js
src/
├── index.ts    # entry point: stdio transport, signals, stderr logging
├── server.ts   # McpServer construction + server instructions
├── tools.ts    # save/load tool schemas and handlers
├── schema.ts   # zod schema for the checkpoint file (v1) + migrations
├── store.ts    # project root resolution, atomic I/O, backup/fallback
├── git.ts      # branch/HEAD/status snapshot, blob hashing, drift detection
├── redact.ts   # secret scrubbing
└── render.ts   # checkpoint → markdown resume brief

Construido con el oficial @modelcontextprotocol/sdk y zod.

Licencia

MIT