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.
claude-checkpoint-mcp é um servidor local de Model Context Protocol com duas ferramentas:
save_session_checkpointgrava o estado de trabalho da sua sessão em um pequeno arquivo JSON no projeto.load_session_checkpointtransforma 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
- Como funciona
- Instalação
- Configuração
- Uso
- Referência de ferramentas e exemplos
- O arquivo
.claude-checkpoint - Segurança e privacidade
- Solução de problemas
- Desenvolvimento
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
/clearpara 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 checkpoint | Com load_session_checkpoint | |
|---|---|---|
| Restaurar o objetivo e as restrições | Você os redigita, ou o Claude os infere | Uma seção do resumo |
| Saber o que está feito vs. pendente | Rederivado do código e do git | Lista de tarefas com status |
| Saber quais arquivos importam | Releitura ampla | Lista exata de arquivos tocados, com anotações |
| Saber o que mudou desde então | Reler tudo para garantir | Apenas arquivos cujo conteúdo realmente mudou são sinalizados |
| Lembrar tentativas falhas | Frequentemente repetidas | Registradas 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.jsseria 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:
| SO | Caminho |
|---|---|
| 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_ROOTpara definir o projeto padrão, ou peça ao Claude para passarprojectRootem 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âmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
goal | string (≤ 500) | ✅ | Objetivo principal da sessão |
tasks | { description, status }[] (≤ 30) | status: pending · in_progress · done · blocked | |
summary | string (≤ 4000) | Onde as coisas estão: o que funciona, o que está quebrado, o que você estava fazendo no meio | |
nextSteps | string[] (≤ 20) | Próximas ações ordenadas para quem retomar | |
decisions | string[] (≤ 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. | |
projectRoot | string (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" }]
}
| Campo | replace | merge |
|---|---|---|
goal | definido | definido |
tasks | definido | atualizado por correspondência com description; novas tarefas anexadas |
summary, nextSteps | definido | substituídos se fornecidos, caso contrário mantidos |
decisions | definido | anexado (deduplicado) |
recentCommands | definido | anexado; os mais antigos são descartados além de 50 |
modifiedFiles | nova varredura git + fornecida | nova varredura git + fornecida + registrada anteriormente |
id, createdAt | novo | preservado |
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âmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
format | "brief" | "full" | Padrão brief (markdown, como acima). full retorna o JSON completo do checkpoint mais o desvio. | |
projectRoot | string (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
- O argumento
projectRoot - A variável de ambiente
CHECKPOINT_PROJECT_ROOT - A primeira raiz
file://do cliente, se o cliente suportar raízes MCP - 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 }
}
| Campo | Notas |
|---|---|
version | Versão do esquema. Versões mais antigas são migradas no carregamento; versões desconhecidas são rejeitadas. |
id / createdAt | Estáveis entre salvamentos merge; novos em replace |
git | null fora de um repositório git, ou antes do primeiro commit do repositório |
modifiedFiles[].status | Código porcelain do git (M, A, D, R, ??), ou M para arquivos relatados apenas pelo Claude |
modifiedFiles[].source | git (detectado) ou agent (relatado pelo Claude, ou herdado de uma mesclagem anterior) |
modifiedFiles[].hash | Hash de blob git do conteúdo da árvore de trabalho no momento do salvamento; impulsiona a detecção de desvio |
meta.truncated | true 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 formasHeader: valuee 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…exox?-…Redaçao é uma rede de segurança, não uma garantia, então mantenha o arquivo fora do controle de versão.
- atribuições de
- 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
execFilecom timeout de 3 segundos eGIT_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
.gitignorepor você. - Seguro com chamadas de ferramentas paralelas. As chamadas de ferramentas são serializadas dentro do servidor, então salvamentos concorrentes de
mergenão podem perder atualizações.
Solução de problemas
| Sintoma | Correção |
|---|---|
checkpoint não aparece em /mcp | Execute claude mcp list e verifique se o caminho é absoluto e se dist/index.js existe (npm run build). |
| O checkpoint é gravado no diretório errado | O servidor recorreu ao diretório de trabalho. Passe projectRoot, ou defina CHECKPOINT_PROJECT_ROOT. |
projectRoot must be an absolute path | Use 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.