Claude Checkpoint MCP

Salva o estado da sessão do Claude Code (objetivo, tarefas, decisões, arquivos tocados, comandos recentes) em um arquivo local e o restaura como um resumo compacto de retomada após uma falha, /clear ou limite de contexto. Apenas local, segredos redigidos.

Documentação

claude-checkpoint-mcp

Salve o estado da sua sessão do Claude Code localmente, para que uma falha, /clear ou limite de contexto não faça o Claude reconstruir o contexto do zero.

License: MIT Node.js ≥ 20 MCP M8ven Score

claude-checkpoint-mcp é um servidor local de Model Context Protocol com duas ferramentas:

  • save_session_checkpoint grava o estado de trabalho da sua sessão em um pequeno arquivo JSON no projeto.
  • load_session_checkpoint transforma esse arquivo de volta em um resumo compacto de retomada.

Ele roda inteiramente na sua máquina. Nada é enviado para lugar nenhum.


Conteúdo


Por quê: pare de pagar duas vezes pelo mesmo contexto

Uma sessão longa do Claude Code acumula muito contexto:

  • o que você está tentando fazer;
  • quais abordagens já falharam;
  • quais arquivos importam;
  • qual teste ainda está falhando.

Várias coisas podem apagar tudo isso no meio da tarefa:

  • uma falha no terminal, queda de SSH ou suspensão do laptop;
  • estouro do limite de contexto;
  • um /clear para obter uma janela nova.

A próxima sessão começa do zero. Para voltar aonde você estava, o Claude precisa reconstruir esse contexto:

  • Relendo arquivos para descobrir o que foi alterado e por quê. Cada leitura de arquivo são tokens de entrada.
  • Refazendo exploração: grep, git diff, ls, execuções de teste, tudo apenas para redescobrir o estado.
  • Reexplicando. Você redigita o objetivo, as restrições e os becos sem saída, ou o Claude redescobre os becos sem saída do jeito mais difícil.

Cada uma dessas etapas reenvia a conversa crescente como entrada, então o custo se acumula.

claude-checkpoint-mcp troca essa reconstrução por uma leitura pequena e estruturada:

Sem checkpointCom load_session_checkpoint
Restaurar o objetivo e as restriçõesVocê os redigita, ou o Claude os infereUma seção do resumo
Saber o que está feito vs. pendenteRederivado do código e do gitLista de tarefas com status
Saber quais arquivos importamReleitura amplaLista exata de arquivos tocados, com anotações
Saber o que mudou desde entãoReler tudo para garantirApenas arquivos cujo conteúdo realmente mudou são sinalizados
Lembrar tentativas falhasFrequentemente repetidasRegistradas em Decisões e pegadinhas

O resumo de retomada para uma sessão típica tem cerca de 1,2 KB de markdown, algumas centenas de tokens. O exemplo abaixo é uma saída real nesse tamanho.

A maior economia vem da detecção de desvio. No momento de salvar, o servidor registra um hash de conteúdo para cada arquivo com alterações não commitadas. Ao carregar, ele compara esses hashes com a árvore de trabalho e diz ao Claude exatamente quais arquivos mudaram após o checkpoint. Todo o resto do resumo pode ser confiado como está, então o Claude relê apenas o que é necessário.


Como 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          └─────────────────────┘
  • O Claude fornece o significado: o objetivo, o progresso, as decisões, os próximos passos e quais comandos foram importantes.
  • O servidor fornece os fatos: branch e HEAD do git, todo arquivo não commitado ou não rastreado com seu hash de conteúdo, e timestamps.
  • As instruções do servidor ensinam o Claude quando agir. O Claude é instruído a carregar no início de uma sessão e a salvar após marcos, antes de operações arriscadas e quando a conversa fica longa. Não é necessário solicitar toda vez.

Instalação

Requisitos: Node.js 20+ e git. O git é opcional, mas sem ele você perde a detecção de desvio.

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

O ponto de entrada do servidor agora está em dist/index.js.


Configuração

Claude Code

Como plugin (mais fácil). Este repositório também é um marketplace de plugins do Claude Code. Você não precisa clonar ou compilar nada:

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

Reinicie o Claude Code e, em seguida, /mcp deve mostrar plugin:claude-checkpoint-mcp:claude-checkpoint como conectado.

Configuração manual. Se você clonou o repositório, registre o servidor uma vez para sua conta de usuário, para que fique disponível em todos os projetos:

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

Use um caminho absoluto. Um servidor com escopo de usuário é iniciado a partir de qualquer projeto em que você abrir o Claude Code. Um caminho relativo como ./dist/index.js seria resolvido em relação a esse projeto, não a este repositório. "$PWD/dist/index.js" expande para o caminho absoluto quando você executa o comando, que é o que fica salvo.

Verifique se está registrado:

claude mcp list

Dentro de uma sessão, /mcp deve mostrar checkpoint como conectado.

Alternativa com escopo de projeto. Para compartilhar o servidor com uma equipe por meio de controle de versão, adicione-o ao .mcp.json do projeto:

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

De qualquer forma, adicione os arquivos de checkpoint ao .gitignore do projeto, ou ao seu gitignore global:

.claude-checkpoint*

Claude Desktop (claude_desktop_config.json)

Abra o arquivo de configuração:

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

Adicione o servidor em mcpServers, usando o caminho absoluto para sua compilação local:

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

Reinicie o Claude Desktop após salvar o arquivo.

O Claude Desktop não tem noção de "projeto atual". Use CHECKPOINT_PROJECT_ROOT para definir o projeto padrão, ou peça ao Claude para passar projectRoot em cada chamada ("salve um checkpoint para /home/meu/codigo/meu-app"). Veja resolução da raiz do projeto.

Outros clientes MCP

Qualquer cliente MCP que suporte o transporte stdio pode executar o servidor:

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

Uso

As instruções integradas do servidor cobrem os casos comuns automaticamente. Você também pode pedir diretamente ao Claude.

Salvar:

  • "Registre nosso progresso."
  • "Salve um checkpoint antes de executar a migração."
  • "Atualize o checkpoint. Incorpore o que acabamos de fazer."

Retomar (em uma sessão nova):

  • "Retome de onde paramos."
  • "Carregue o checkpoint e continue."

Exemplo de resumo de retomada

Esta é uma saída real de load_session_checkpoint. No cenário, um arquivo foi commitado sem alterações após o salvamento, e um colega de equipe então editou 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 foi commitado após o salvamento, mas seu conteúdo não mudou, então não é sinalizado. Apenas session.ts precisa ser relido.

Marcadores de tarefa: [x] concluído · [~] em andamento · [ ] pendente · [!] bloqueado.


Referência de ferramentas e exemplos

save_session_checkpoint

Grava <projectRoot>/.claude-checkpoint.

ParâmetroTipoObrigatórioDescrição
goalstring (≤ 500)✅Objetivo principal da sessão
tasks{ description, status }[] (≤ 30)status: pending · in_progress · done · blocked
summarystring (≤ 4000)Onde as coisas estão: o que funciona, o que está quebrado, o que você estava fazendo no meio
nextStepsstring[] (≤ 20)Próximas ações ordenadas para quem retomar
decisionsstring[] (≤ 20)Decisões-chave, restrições, becos sem saída a evitar
modifiedFiles{ path, note? }[] (≤ 100)Arquivos para anotar, ou arquivos commitados para incluir. Alterações git não commitadas são detectadas automaticamente. Caminhos absolutos dentro do projeto são armazenados como relativos.
recentCommands{ command, exitCode?, note? }[] (≤ 50)Comandos significativos, do mais antigo ao mais recente. Segredos são mascarados.
mode"replace" | "merge"Padrão replace. Veja abaixo.
projectRootstring (absoluto)Substitui a resolução da raiz

Salvamento 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" }
  ]
}

Resposta (texto mostrado ao 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).

Atualização incremental com 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
goaldefinidodefinido
tasksdefinidoatualizado por correspondência com description; novas tarefas anexadas
summary, nextStepsdefinidosubstituídos se fornecidos, caso contrário mantidos
decisionsdefinidoanexado (deduplicado)
recentCommandsdefinidoanexado; os mais antigos são descartados além de 50
modifiedFilesnova varredura git + fornecidanova varredura git + fornecida + registrada anteriormente
id, createdAtnovopreservado

Saída estruturada (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

Somente leitura. Lê o checkpoint, verifica desvios e retorna o resumo.

ParâmetroTipoObrigatórioDescrição
format"brief" | "full"Padrão brief (markdown, como acima). full retorna o JSON completo do checkpoint mais o desvio.
projectRootstring (absoluto)Substitui a resolução da raiz

Exemplos:

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

Saída estruturada (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": []
}

Se nenhum checkpoint existir, a ferramenta retorna found: false com uma mensagem de "nada para retomar". Isso não é tratado como erro.

Como a raiz do projeto é escolhida

  1. O argumento projectRoot
  2. A variável de ambiente CHECKPOINT_PROJECT_ROOT
  3. A primeira raiz file:// do cliente, se o cliente suportar raízes MCP
  4. O diretório de trabalho do processo do servidor

O caminho deve ser absoluto e deve ser um diretório existente. Symlinks são resolvidos. O arquivo é sempre gravado exatamente em <root>/.claude-checkpoint.


O arquivo .claude-checkpoint

Este é um JSON simples e versionado, fácil de ler, comparar ou editar manualmente. Exemplo 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
versionVersão do esquema. Versões mais antigas são migradas no carregamento; versões desconhecidas são rejeitadas.
id / createdAtEstáveis entre salvamentos merge; novos em replace
gitnull fora de um repositório git, ou antes do primeiro commit do repositório
modifiedFiles[].statusCódigo porcelain do git (M, A, D, R, ??), ou M para arquivos relatados apenas pelo Claude
modifiedFiles[].sourcegit (detectado) ou agent (relatado pelo Claude, ou herdado de uma mesclagem anterior)
modifiedFiles[].hashHash de blob git do conteúdo da árvore de trabalho no momento do salvamento; impulsiona a detecção de desvio
meta.truncatedtrue se algo foi descartado para caber nos limites de lista ou tamanho

Caminhos são sempre relativos à raiz do projeto. O arquivo nunca armazena caminhos absolutos.


Segurança e privacidade

  • Apenas local. Não há chamadas de rede. O servidor lê metadados do git e um arquivo, e grava um arquivo.
  • Mascaramento de segredos. Os seguintes itens são substituídos por «redacted» em comandos, anotações, resumos, tarefas e decisões antes que qualquer coisa toque o disco:
    • atribuições de *_KEY=, *_TOKEN=, *_SECRET=, *PASSWORD=, incluindo formas Header: value e JSON
    • cabeçalhos Authorization: Bearer …
    • credenciais em URLs (postgres://user:pass@…)
    • flags --password / --token / --api-key / --secret
    • tokens simples de sk-…, ghp_…, github_pat_…, AKIA… e xox?-… Redaçao é uma rede de segurança, não uma garantia, então mantenha o arquivo fora do controle de versão.
  • Somente proprietário, gravações seguras contra falhas. Os arquivos são gravados com modo 0600. Cada salvamento grava um arquivo temporário, faz fsync e o renomeia no lugar, para que uma falha no meio do salvamento não deixe um checkpoint pela metade.
  • Backup automático. O checkpoint válido anterior é mantido como .claude-checkpoint.prev. Se o arquivo principal estiver corrompido, o carregamento recorre ao backup e informa isso. Um arquivo corrompido nunca sobrescreve um backup bom.
  • Tamanho limitado. Cada campo tem um limite de comprimento, e o arquivo é limitado a 64 KB (os comandos mais antigos são descartados primeiro), para que um checkpoint não cresça até virar um sumidouro de tokens.
  • Sem shell. O Git é executado via execFile com timeout de 3 segundos e GIT_OPTIONAL_LOCKS=0, então nunca compete com seus próprios comandos git.
  • Não toca na sua configuração. Se o checkpoint não estiver no git-ignore, a resposta do salvamento avisa. Ele nunca edita .gitignore por você.
  • Seguro com chamadas de ferramentas paralelas. As chamadas de ferramentas são serializadas dentro do servidor, então salvamentos concorrentes de merge não podem perder atualizações.

Solução de problemas

SintomaCorreção
checkpoint não aparece em /mcpExecute claude mcp list e verifique se o caminho é absoluto e se dist/index.js existe (npm run build).
O checkpoint é gravado no diretório erradoO servidor recorreu ao diretório de trabalho. Passe projectRoot, ou defina CHECKPOINT_PROJECT_ROOT.
projectRoot must be an absolute pathUse um caminho completo como /home/me/code/app, não ./app.
O resumo diz "Saved commit … is no longer reachable"O branch foi rebasado ou resetado após o salvamento. A deriva não pode ser calculada contra o histórico, então trate os arquivos sinalizados como precisando de uma nova leitura.
Aviso: "not git-ignored"Adicione .claude-checkpoint* a .gitignore.
Sem seção "Since this checkpoint"O projeto não é um repositório git, ou não tinha commits no momento do salvamento.

Os logs do servidor vão para stderr. O stdout é reservado para o protocolo MCP.


Desenvolvimento

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

Construído com o oficial @modelcontextprotocol/sdk e zod.

Licença

MIT