Task Checkpoint について
Task Checkpointは、長時間のコーディングや文書作成に使うPython製MCPサーバーです。作業ファイルの変更と手順の説明を記録し、Git履歴を変えずに新しいセッションで再開したり、以前の状態へ戻したりできます。
主な機能
- 01作業ファイルの変更と手順の記録
- 02新しいセッションでの進捗再開
- 03以前の状態のプレビューと復元
- 04引き継ぎパッケージの出力と取り込み
- 05複数の中断中タスクの管理
活用シーン
- 01中断した作業の再開
- 02作業中の誤った変更の取り消し
- 03別のディレクトリやマシンへの作業引き継ぎ
MCP 対応
stdio MCPサーバーは、チェックポイントの開始、保存、再開、表示、復元、転送のツールを提供します。付属の`SKILL.md`は、各手順の完了後に保存するようエージェントに指示します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
10掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| goal | string | いいえ | タスクの目標 |
| name | string | はい | タスク名 |
| root | string | はい | ワークスペースのルートディレクトリ |
| store | string | いいえ | アーカイブディレクトリ。省略すると、ワークスペース内の .checkpoints を使用します |
| exclude | array | いいえ | 追加の除外パターン。個々の名前フィールド(ディレクトリ名またはパスの最初のセグメント)に照合します。例:["config", "*.local"] |
| constraints | string | いいえ | 制約 |
詳細
Task Checkpoint MCP
给长任务做"做一步、存一步"的存档:中断后新会话能接着做,做错了能退回任意一步。
一个 stdio MCP 服务器,只用 Python 标准库,不装任何第三方包。
快速开始 | 工具 | 客户端配置 | 使用限制 | English
快速开始
一、装
pipx install task-checkpoint-mcp
二、在客户端里接上(Claude Code、Codex、Cursor 等都是同一段配置)
{
"mcpServers": {
"task-checkpoint": { "command": "tc-mcp", "args": [] }
}
}
三、把 SKILL.md 装进技能目录,不装的话 Agent 不会主动存档
tc-mcp --install-skill ~/.claude/skills/task-checkpoint
SKILL.md 随包一起装(wheel 里的包数据),不需要仓库、也不需要联网。想看内容用 tc-mcp --print-skill,想知道它在哪用 tc-mcp --skill-path。
(技能目录按客户端而定,见下面"把 SKILL.md 装进 Agent 的技能目录"。)
四、交给 Agent 用。 一个任务就四步:
tc_init 开任务
tc_save 每完成一步存一次(带 conclusion 和 next)
tc_resume 新会话开头先调这个接上进度
tc_restore 退回去(先 apply:false 预览,再 apply:true)
五、不用记工具名,直接说人话。
用 task-checkpoint 开个任务,目标是把 user 模块拆成 service 和 repository 两层。每完成一步存一次档,带结论和下一步。
它会调 tc_init 建任务,之后每完成一步调一次 tc_save。中途换会话、或者隔天接着做,你说一句"接着上次的做",它调 tc_resume 就把进度拿回来了。
("每完成一步就存档"这条约束的可靠来源是 SKILL.md —— 装进技能目录之后它是硬规则;不装,就只能靠你每次提醒。)
中途被打断、隔天换个模型重开,新会话调一次 tc_resume 拿到的是这个:
任务:重构认证模块
目标:把 session 改成 JWT
当前步骤:3
下一步:把三个视图函数切到新入口,删旧函数
未落档:src/views/auth.py, src/views/user.py
handoff 字段就是这段文本,可以直接粘给新会话。它同时告诉你哪几个文件改了但还没落档。
为什么不直接用 git stash 或随手 commit 一下
| 做法 | 缺什么 |
|---|---|
git stash | 一次性的,不能命名、不能跨会话交接,也没有"这一步在做什么、结论是什么" |
| 随手一个 commit | 会污染真实历史;半成品未必允许 commit;还得你记得先 commit |
| 手写进度笔记 | 和文件状态脱钩,回退时要自己对着时间线拼 |
| 本工具 | 文件变化后台自动记(变更层),步骤语义由模型声明(任务层);只额外加 refs/checkpoints/...,不动你的 git 历史 |
值得装:多步、可能被中断、需要能退回的编码或文档任务。 不值得装:一次能做完、不需要回退也不需要交接的改动。
装之前先知道
- 需要 Python 3.10 或更新,只用标准库。
- 不碰你的 git 历史:不 commit、不 reset、不 clean、不动已有分支和 HEAD,只额外加
refs/checkpoints/...引用。 - 不是 git 仓库也能用,功能一样,只是少了那层 git 引用。
- 不保存聊天记录,只保存工作区文件和模型主动声明的步骤说明。
- 存档默认写在工作区的
.checkpoints/;指定外部store时,工作区仅留一个不含文件内容的.task-checkpoint-store.json路径指针。 - 敏感文件识别是路径黑名单,盖不全。 别把凭据放在被扫路径里 —— 详见"使用限制"。
安装
方式一:装成命令(推荐)
pipx install task-checkpoint-mcp
# 或
pip install task-checkpoint-mcp
也可以直接从 git 装,跟着仓库走、不走 PyPI 的版本号:
pipx install "git+https://github.com/qddfxp/task-checkpoint-mcp"
装完在客户端里用 tc-mcp 启动。包里有两个等价的入口点:tc-mcp 和 task-checkpoint-mcp(后者是给 uvx 这类按包名找命令的 runner 用的):
{
"mcpServers": {
"task-checkpoint": { "command": "tc-mcp", "args": [] }
}
}
方式二:直接用源码(不用安装)
git clone https://github.com/qddfxp/task-checkpoint-mcp
{
"mcpServers": {
"task-checkpoint": {
"command": "/absolute/path/to/python",
"args": ["/absolute/path/to/task-checkpoint-mcp/scripts/tc_mcp.py"]
}
}
}
command 要写解释器的绝对路径,不要写 python —— 客户端不一定能解析到你要的那个。装过之后也可以直接 python -m tc_mcp。
方式三:用 npx 启动
npm 上有一个同名的 task-checkpoint-mcp,但它是启动器,不是服务器本体:
npx -y task-checkpoint-mcp
它只做一件事:找到本机装了 tc_mcp 的 Python 解释器,然后把 stdio 透传给 python -m tc_mcp。所以本机仍然要先有 Python 包(方式一或方式二)。没有的话它会打印安装命令、以退出码 1 结束,而不是丢一堆 traceback 给你。
适合客户端只认 npm 式启动命令的情况:
{
"mcpServers": {
"task-checkpoint": { "command": "npx", "args": ["-y", "task-checkpoint-mcp"] }
}
}
npx -y task-checkpoint-mcp --version / --help 是启动器自己的开关,不需要本机有 Python。
配置文件放哪
上面那段 mcpServers JSON 要写进客户端的配置文件。各客户端的位置和顶层键:
| 客户端 | 配置文件 | 顶层键 |
|---|---|---|
| Claude Desktop | Windows %APPDATA%\Claude\claude_desktop_config.json;macOS ~/Library/Application Support/Claude/claude_desktop_config.json | mcpServers |
| Claude Code | 项目根目录 .mcp.json | mcpServers |
| Cursor | 全局 ~/.cursor/mcp.json;项目内 .cursor/mcp.json 优先 | mcpServers |
| Windsurf | ~/.codeium/windsurf/mcp_config.json | mcpServers |
| ZCode | ~/.zcode/cli/config.json | mcpServers |
| VS Code / Copilot | 项目内 .vscode/mcp.json;用户级 %APPDATA%\Code\User\mcp.json | servers |
| Codex CLI | ~/.codex/config.toml | TOML 的 [mcp_servers],不是 JSON |
两个容易踩的:
VS Code 的顶层键是 servers,不是 mcpServers。 直接抄上面的 JSON 不会生效,得改键名:
{
"servers": {
"task-checkpoint": { "command": "tc-mcp", "args": [] }
}
}
Codex 用 TOML。 同样一段配置要写成:
[mcp_servers.task-checkpoint]
command = "tc-mcp"
args = []
其余客户端以各自的文档为准。
怎么用
最重要的一条:文件变化由后台线程自动记录,但"这一步在做什么、结论是什么、下一步干什么"只有模型主动调 tc_save 才会留下。
所以要让 Agent 每完成一步就存一步 —— 这份约束写在 SKILL.md 里,得把它装进 Agent 的技能目录(见下面"把 SKILL.md 装进 Agent 的技能目录")。不装它,文件回退点照常产生,但没人知道当初要干什么、下一步该干什么。
四条铁律:
- 开长任务前先
tc_init,一个任务一个名。已有活动任务会被挂起而不是关闭,可以tc_switch切回去。 - 每完成一步就
tc_save,并且必须填conclusion和next。不填,新会话就只看得到一堆文件路径。 - 新会话、或中断后继续时,第一件事是
tc_resume,不要从零猜进度。 - 回退前先预览:先
apply: false看清单,确认了再apply: true。
一步的粒度:能独立说清"做完了、结论是 X"的单元。太细(每个文件一次)会淹没有效信息,太粗(整个任务一次)就失去了回退的意义。
工具
10 个。第一个参数都是 root,指工作区目录(通常是当前项目的绝对路径)。
| 工具 | 什么时候用 | 必填 |
|---|---|---|
tc_init | 长任务开工。已有活动任务会被挂起而不是关闭 | root, name |
tc_save | 每完成一步 | root, title |
tc_resume | 新会话开头、接手别人中断的工作(只读) | root |
tc_show | 想看有哪些步骤 / 变更记录 | root |
tc_restore | 退回某一步或某条变更记录。先预览再执行 | root,加 index 或 drift_id |
tc_capture | 想立刻记一次文件变化(不等后台线程) | root |
tc_switch | 回到之前挂起的任务 | root, task_id |
tc_export | 导出交接包给另一个目录 / 另一台机器 | root, to |
tc_import | 导入别人的交接包,在这里接续任务 | root, package |
tc_compress | 存档太大了,回收旧变更层空间 | root |
tc_save 的完整参数:
title(必填)——这一步一句话标题,写"做了什么",不写"改了什么"conclusion——这一步的结论。最有价值的字段next——下一步要干什么。接续工作的关键description——为什么这么做(决策理由,事后没人记得)verified——已验证项列表(跑了什么测试、确认了什么事实)open_questions——还没解决、留给后面的问题close: true——收尾时用。关闭后不能再存档,但还能读
回退操作本身也会被记成一条变更记录,返回里的 recovered 就是它的 drift_id —— 退错了可以再用它退回来。
返回值里几个值得看的字段
tc_resume.handoff—— 一段现成的交接文本,可以直接粘给新会话;drift_paths是工作区里还没落档的改动;health.errors是存档自身的问题tc_save.idempotent—— 同一步(标题、文件摘要、结论、下一步、已验证项都一样)重复存,不会产生重复步骤tc_save.active_task_changed—— 传了别人的task_id时活动任务会被切过去(原任务变 suspended),这个字段就是在提示这件事tc_restore.recovered—— 回退本身也会被记成一条变更记录,这就是它的drift_idtc_restore.plan.unrestorable/skipped_paths—— 目标里没能还原的文件;预览和执行给的是同一份清单tc_capture.waiting/partial—— 还在静默期,以及中间那条不完整的记录tc_init.exclude—— 回读你这次设进去的排除模式tc_export.path—— 交接包目录,里面有一个HANDOFF.md,是给接手方的提示词
把 SKILL.md 装进 Agent 的技能目录
SKILL.md 是这个项目的另一半功能,不是可选文档:MCP 服务器负责存取,SKILL.md 负责让模型每完成一步真的去调 tc_save。
复制到客户端扫描的技能目录,目录名即技能名:
| 客户端 | 放这里 |
|---|---|
| Claude Code | ~/.claude/skills/task-checkpoint/SKILL.md |
| Codex CLI | ~/.codex/skills/task-checkpoint/SKILL.md |
| ZCode | ~/.zcode/skills/task-checkpoint/SKILL.md |
| 跨客户端共用 | ~/.agents/skills/task-checkpoint/SKILL.md |
~/.agents/skills/ 是多个客户端共用的技能目录;客户端专属目录优先于它 —— 同名技能以客户端专属目录里的那份为准。OpenCode 等其它客户端放到它自己文档里的技能目录即可,规则不变。
tc-mcp --install-skill ~/.claude/skills/task-checkpoint
SKILL.md 是随包一起安装的(wheel 里的包数据),所以 pipx install 的用户不需要仓库,也不需要联网。目标已存在时会拒绝覆盖 —— 确实要覆盖加 --force;只想看内容用 tc-mcp --print-skill。
克隆了仓库的话,cp SKILL.md <技能目录>/ 效果一样。
Windows 路径形如 C:\Users\<你>\.claude\skills\task-checkpoint\SKILL.md。各客户端的技能目录可能不同,以它自己的文档为准;要求只有一条:文件落在技能目录下的 <技能名>/SKILL.md。重启客户端后生效。
自检(可选)
装完最快的一条,确认入口点活着、拿到版本号:
tc-mcp --version # 版本号
tc-mcp --help # 所有开关
下面几条都要先克隆仓库 —— pip 装出来的包里没有 tests/ 和 tools/。
在克隆下来的仓库里跑一遍回归测试:
python -m unittest discover -s tests -p "test_*.py" -v
最后一行是 OK 就对了。整套测试(100 多个用例)跑一次的时间完全看环境:
| 跑在哪 | 实测 |
|---|---|
| CI 的 ubuntu runner | 4.7 秒 |
| CI 的 windows runner | 39.8 秒 |
| 本机 Windows(E 盘) | 156~340 秒 |
同一套代码差了七十倍。开销集中在 git 子进程(refs/checkpoints/ 相关用例占大头)和静默期等待,对磁盘和杀毒的实时扫描极其敏感 —— 别把秒数当承诺,也别拿一个数字去对比另一台机器。
全部只用标准库,不需要 pytest;在 Python 3.10 上也能跑,只有读 pyproject.toml 的那几条会因为 tomllib 被跳过(3.11+ 全跑)。
仓库里还能跑真机端到端演练(起真 MCP 子进程、真杀进程、建约 190 MB 的重工作区、逐项核对"不动你 git"的承诺):
python tools/drill.py
它跑完默认把场地删掉;想看场地就 TC_DRILL_KEEP=1 python tools/drill.py(演练有未通过项时也会自动保留,方便排查)。
确认 MCP 服务器能起来 —— 会回一行带 serverInfo 的 JSON:
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' | python scripts/tc_mcp.py
从 pip 装的版本没有 scripts/,把上面那条改成 ... | tc-mcp(或 python -m tc_mcp)就行。
環境変数
| 変数 | デフォルト | 説明 |
|---|---|---|
TC_STORE | <工作区>/.checkpoints | アーカイブディレクトリ |
TC_WATCH | on | off に設定すると、バックグラウンドでの自動記録を無効にします |
TC_WATCH_INTERVAL | 15 | バックグラウンドでの確認間隔(秒) |
TC_DRIFT_MAX_WAIT | 60 | 静止期間の上限(秒) |
TC_GIT | on | off に設定すると、refs/checkpoints/... 参照を一切作成しません |
TC_GIT_VERIFY | on | 参照の作成前後に git フィンガープリントを比較し、「ユーザーの git に手を加えていない」ことを自ら検証します。off に設定すると検証を省略し、各 tc_save で git サブプロセスの実行回数を減らせます。検証を省略すると、返される git.unchanged は null になります |
TC_SHA_REUSE | off | mtime とサイズに変更がないファイルは読み直さず、インデックス内の sha をそのまま再利用します。リスクについては「使用上の制限」を参照してください |
使用上の制限
機密ファイル:ブラックリストでは網羅できません
機密ファイルは内容を保存せず、ハッシュも保存しません。mtime とサイズが変わったかどうかだけを確認できます。パスに基づいて判定するため、両方向の見落としが発生します。
- 見落とし:無害な名前の認証情報は検出できません。
config/database.yaml、docker-compose.yml、config.jsonは通常のファイルとして扱われ、payload/に平文で保存されます。スキャン対象のパスに認証情報を置かないでください。避けられない場合は、tc_init(exclude=[...])でディレクトリ全体を除外してください。 - 誤検出:機密ファイルと誤判定されたソースコードは、内容のコピーを取得できず、復元時に黙ってスキップされます(
plan.unrestorableにのみ記載されます)。誤検出を減らすため、リストは 2 つの階層に分かれています。
対象となる範囲:
- ディレクトリ名(ディレクトリ全体を保存しません)
.ssh.aws.gnupg.docker.kube.env.envdir.secrets.tokens、または名前にsecret/credential/tokenを含むディレクトリ。 - 明確に判別できるファイル名
- dotenv:
.env.env.**.env*.env.*.envrc - 秘密鍵:
*.pem*.key*.p12*.pfx*.p8*.jks*.keystore*.kdbx*.ppk*.ovpn*_rsa*_dsa*_ed25519*_ecdsa*_key - 認証情報:
.netrc.git-credentials.npmrc.pypirc.pgpass.htpasswd.my.cnfmy.cnfpasswdshadow - クラウドとインフラ:
kubeconfig*.kubeconfig*.tfstateterraform.tfvars*.tfvars*.jwt - ワイルドカード:
credentials*creds*secret*secrets.jsontokentoken.jsontoken.txt*.token*_tokenauth.json - フレームワーク設定:
settings.pylocal_settings.pysettings.xmlwp-config.phpweb.configwrangler.toml.dev.vars
- dotenv:
- 誤判定の可能性が高い部分文字列。設定ファイルの拡張子で終わるファイル名だけを対象にします
- 部分文字列:
*secret**password**passwd**credential**api_key**apikey**token**auth_token* - 拡張子:
.json .yaml .yml .toml .ini .cfg .conf .config .properties .xml .txt .env .envrc .cnf .sh .ps1 .bat .cmd .sql .php - そのため、
prod_credentials.jsonは対象になりますが、src/password_policy.py、src/tokenizer.py、docs/secrets.mdは対象になりません。
- 部分文字列:
exclude の照合方法は組み込みリストと同じで、単一の名前フィールド(ディレクトリ名、またはパスの最初の要素)に対して glob を適用します。そのため、exclude=["config"] は任意の階層にある config/ ディレクトリを除外しますが、特定のファイルだけを除外することはできません(config/database.yaml を除外するには、config/ ごと除外する必要があります)。/ を含むパターンは拒否され、黙って無効になることはありません。
この機能は、プライバシー保護やコンプライアンスを保証するものではありません。 アーカイブディレクトリへのアクセス権限はご自身で管理してください。除外されていない認証情報、トークン、秘密鍵、個人情報をスキャン対象のパスに置かないでください。
時間と粒度
- 静止期間は最長で約 60 秒です。ファイルへの書き込みが続いている場合、途中の記録には
partial: trueが設定されます。 - プロセスが突然終了した場合、次に
tc_save/tc_captureを実行するまでは、最後の変更分はtc_resumeの未記録パスにのみ存在し、変更レイヤーの記録にはなっていません。
変更レイヤーは mtime とサイズのみを確認します
tc_capture とバックグラウンドスレッドは、mtime とサイズに基づいて変更を判定します。内容が変わっても mtime と長さが同じ場合(cp -p、rsync -t、tar -x は mtime を保持します)、ファイルが変更されたとは判定されません。
タスクレイヤーの tc_save は、デフォルトでは内容に基づいて sha を計算するため、この制限を受けません。ただし、TC_SHA_REUSE=on にするとタスクレイヤーにも同じ判定基準が適用されます。下記の説明を参照してください。
復元
- ファイルのアクセス権ビット(POSIX 実行ビットも含む)は復元しますが、mtime は復元しません。古いタイムスタンプを書き戻すと、make 系のツールがファイルに変更がないと誤認するためです。注意:アクセス権だけが変更され、内容に変更がない場合は、内容が異なるファイルのみを書き直すため、復元時に書き直されません。その場合、アクセス権ビットも元に戻りません。
- 復元できないファイルはスキップされます(機密ファイル、内容が保存されていない 100 MB 超のファイル、payload の消失)。それ以外は通常どおり復元されます。スキップされたファイルは、返される
plan.unrestorableに記載されます。プレビューと実際の実行で同じリストを使用するため、.envが原因で復元全体が失敗することはありません。 - バイナリファイルも復元できますが、行単位の diff はできません。並行編集のマージには対応していません。
大きなファイル
100 MB 以下のファイルは、sha に基づいて元のまま payload/ に保存され、同じ内容は 1 つだけ保存されます。100 MB を超えるファイルは、ストリーミングハッシュとメタデータのみを記録し、内容は保存しないため、内容を復元できません。
アーカイブは自動的に縮小されません
古い変更レイヤーの内容は保存され続けるため、tc_compress を使って手動で回収してください。デフォルトの引数は7 日間保持なので、小さなワークスペースではデフォルトの呼び出しで converted: 0(何も回収されない)となることがよくあります。戻り値には keep_seconds / minimum / maximum / eligible / bytes_freed が含まれるため、「なぜ回収されなかったのか」を確認できます。実際にクリーンアップするには、keep_seconds を小さくしてください(ステップのベースラインと recovered レイヤーは、どのような場合も変更されません)。
TC_SHA_REUSE=on のリスク(デフォルトで無効にしている理由)
タスクレイヤーはデフォルトでは毎回、mtime を信用せず、内容に基づいて sha を計算します。そのため、1 回の save でワークスペース内の機密ファイルではないすべてのファイルを読み込みます(内容は保持せず、メモリ使用量はワークスペースのサイズに左右されません)。
TC_SHA_REUSE=on にすると、mtime とサイズに変更がないファイルは読み直さず、インデックス内の sha をそのまま再利用します。mtime が元に戻された場合(os.utime)、ファイルシステムの mtime の精度が粗い場合(FAT、一部のネットワークドライブ)、またはツールが mtime を保持する場合(cp -p、rsync -t、tar -x、一部のジェネレーター)、内容の変更が完全に見落とされます。ディスクから読み込まず、新しい内容も保存しないまま、古い sha がステップに記録され、復元時には古い内容が黙って返されます。デフォルトで無効にしている場合、この事態は発生しません。
tc_resume と tc_show は、どちらのモードでもファイルの内容を読み込まず(mtime とサイズのみを確認するため)、「mtime が保持された変更」を見落とす可能性があります。
パラメーターと状態に関する制約
tc_restoreにはindexまたはdrift_idのどちらか一方だけを指定する必要があります。apply=trueで閉じたタスクを変更することはできません。tc_saveにtask_idを指定した場合(かつそれが現在のアクティブタスクではない場合)、まずアクティブタスクを切り替えてから(元のタスクは suspended に設定されます)、この手順を保存します。戻り値のactive_task_changed: trueは、この切り替えが発生したことを示します。元に戻すにはtc_switchを使ってください。- ベースラインが存在し、未記録の変更が検出された状態で
tc_saveを実行すると、まずその変更を今回の save の manifest に関連付けてから、タスクの手順を記録します。 tc_exportでは出力先の親ディレクトリがすでに存在している必要があります。tc_importはタスク ID とワークスペースのパスを検証し、重複するタスク、..によるディレクトリ移動、シンボリックリンク先へのインポートを拒否します。インポートに失敗すると、書き込み済みの対象ファイルは元に戻されます。storeをワークスペースのルートディレクトリと同じ場所にすることはできません。カスタムstoreがワークスペース内にある場合、スキャナーによって自動的に除外されます。
git 関連
git リポジトリでは、tc_save のたびに数百ミリ秒余分にかかります(参照を作成する git サブプロセスのオーバーヘッド)。このコストを避けるには、TC_GIT=off または TC_GIT_VERIFY=off を指定してください。
実装に関する補足
このコードを変更する人だけが知っておく必要があります。
- アーカイブディレクトリ内の
.git/indexのバイト数は git 自身によって更新されます(status/ls-filesの実行で stat キャッシュが更新されます)が、HEAD、ブランチ、ステージ済みの内容は変わりません。前後のstatus/ls-filesの出力を比較すれば確認できます。 refs/checkpoints/に同名の参照がすでにある場合、上書きは拒否されます。tc_show/tc_resumeは状態スナップショットの読み取り時のみ短時間ロックを保持します。ワークスペースのスキャンやファイルの読み取りによって、書き込み操作が長時間ブロックされることはありません。- manifest は増分チェーンで、20 件ごとに全量アンカーを強制的に作成します。
ストレージ
<工作区>/.checkpoints/
├── current.json 活动任务指针,按工作区 root 分键(同一个 store 可服务多个工作区)
├── state.lock 并发锁
├── server.log 日志(不会写到 stdout,stdout 只走 MCP 帧)
├── payload/<sha前两位>/ 内容寻址的文件副本(多个任务/步骤共享,按 sha 去重)
└── tasks/<task_id>/
├── state.json
├── index.json 基线索引:每个文件的 mtime/size/sha256
├── steps/sNNNN.json 任务层:每一步的说明
├── drifts/dNNNN.json 变更层:文件变化
└── manifest/mNNNN.json 一致性清单(增量链,每 20 份一个全量锚点)
アクティブポインターとベースラインインデックスは、どちらもスコープごとに分離されています。同じ store を複数のワークスペースで共有しても、互いに混ざることはありません。
ディレクトリ構成
.
├── README.md 本文件
├── SKILL.md 给 Agent 看的使用约束(功能的一部分,会随包一起安装)
├── LICENSE MIT
├── pyproject.toml 打包配置,源码不改成包目录
├── MANIFEST.in sdist 包含哪些文件
├── server.json 官方 MCP Registry 的发布元数据
├── glama.json Glama 目录的所有权标记
├── scripts/
│ ├── tc.py 业务核心
│ └── tc_mcp.py stdio MCP 适配层 + 给人用的命令行开关
├── tools/
│ └── drill.py 真机端到端演练探针(不进测试套件,手动跑)
├── npm/ npm 启动器包(只是壳,服务器本体不在这里)
├── tests/
│ ├── test_tc.py 完整验收测试(回退安全、并发锁、git ref、返回字段、打包契约)
│ ├── test_tc_regressions.py 针对已修缺陷的定向回归
│ └── test_packaging_consistency.py 三处版本号 / 注册表元数据 / README 所有权标记的一致性
└── .github/workflows/ci.yml CI:跑测试、构建、校验 server.json 与 wheel
ビルド成果物はリポジトリに含めません。リリース経路は 2 つあります。PyPI の task-checkpoint-mcp(pipx install task-checkpoint-mcp)が主要な配布経路で、wheel と sdist はどちらも GitHub Releases に掲載されます。
参加する
Issue や PR を歓迎します。コードを変更する前に、まずテストを実行してください(上記の「セルフチェック」を参照。テストケースは 100 件以上で、ローカル環境では 2.5~6 分かかります)。
tests/test_tc.pyは完全な受け入れテストスイートです。ロールバックの安全性、並行ロック、git ref の到達可能性、各分岐の戻り値フィールド、パッケージングの契約を検証します。tests/test_tc_regressions.pyは修正済みの不具合を対象とする回帰テストです。新しいバグを修正したら、コードだけを変更するのではなく、ここにテストを 1 つ追加してください。
厳守すべき条件が 1 つあります。標準ライブラリのみを使用してください。新しい依存関係は一切受け入れません。テスト用の依存関係も同様です(テストには unittest を使い、pytest は使いません)。
ライセンス
MIT。詳細は LICENSE を参照してください。
Task Checkpoint MCP(英語)
長時間にわたるエージェントタスクのチェックポイント作成と再開に対応します。作業の各手順をその都度保存し、新しいセッションで作業を再開したり、以前の任意の手順にロールバックしたりできます。
純粋な Python 標準ライブラリだけで書かれた stdio MCP サーバーです。サードパーティーパッケージは不要です。Python 3.10 以降に対応しています。
クイックスタート | ツール | クライアントの設定 | 制限事項
クイックスタート
1. インストール
pipx install task-checkpoint-mcp
2. クライアントに接続します(Claude Code、Codex、Cursor などで同じブロックを使います)
{
"mcpServers": {
"task-checkpoint": { "command": "tc-mcp", "args": [] }
}
}
3. SKILL.md をスキルディレクトリにインストールします。 これがないと、エージェントは自動でチェックポイントを作成しません。
mkdir -p ~/.claude/skills/task-checkpoint
curl -fsSL -o ~/.claude/skills/task-checkpoint/SKILL.md \
https://raw.githubusercontent.com/qddfxp/task-checkpoint-mcp/main/SKILL.md
(スキルディレクトリはクライアントによって異なります。詳しくは、以下の「SKILL.md をエージェントのスキルディレクトリにインストールする」を参照してください。)
4. エージェントに使わせます。 タスクには 4 回の呼び出しが必要です。
tc_init start a task
tc_save once per completed step (with conclusion and next)
tc_resume first call in a new session, to pick up where you left off
tc_restore roll back (apply:false to preview, then apply:true)
5. ツール名を覚える必要はありません。話しかけるだけです。
task-checkpoint を使ってタスクを開始してください。目標は、ユーザーモジュールをサービス層とリポジトリ層に分割することです。各手順の後に、結論と次に行うことを添えてチェックポイントを作成してください。
エージェントは tc_init を呼び出してタスクを作成し、各手順の後に tc_save を呼び出します。セッションを切り替えたり、翌日に戻ってきたりして「前回の続きから再開して」と伝えると、tc_resume を呼び出して作業を再開します。
(「各手順の後にチェックポイントを作成する」という確実な指示は SKILL.md にあります。スキルディレクトリにインストールすれば、これは必須のルールになります。インストールしない場合は、エージェントに毎回指示する必要があります。)
タスクの途中で中断し、翌日に別のモデルで再開した場合、新しいセッションで tc_resume を 1 回呼び出すだけで、次の情報が得られます。
任务:重构认证模块
目标:把 session 改成 JWT
当前步骤:3
下一步:把三个视图函数切到新入口,删旧函数
未落档:src/views/auth.py, src/views/user.py
このテキストは handoff フィールドです。そのまま新しいセッションに貼り付けられます。また、変更されたものの、まだ記録されていないファイルも示します。
git stash や通常のコミットでは不十分な理由
| 方法 | 不足していること |
|---|---|
git stash | 使い切りです。名前も、セッションをまたいだ引き継ぎもなく、この手順の内容やそこから得られた結論も記録されません |
| 簡易コミット | 実際の履歴を汚します。作業が途中の状態ではコミットできないこともありますし、先にコミットするのを忘れないようにする必要があります |
| 手書きの進捗メモ | ファイルの状態と連動しないため、ロールバック時にタイムラインと手作業で照合する必要があります |
| このツール | バックグラウンドスレッドがファイルの変更を記録し(drift レイヤー)、モデルが手順の意味を宣言します(task レイヤー)。refs/checkpoints/... を追加するだけで、git の履歴には一切触れません |
中断される可能性があり、元に戻せる必要がある複数手順のコーディングや文章作成タスクには、インストールする価値があります。ロールバックや引き継ぎが不要で、一度の作業で完了する変更には必要ありません。
インストールする前に
- Python 3.10 以降が必要です。標準ライブラリのみを使用します。
- Git の履歴は変更されません。コミット、リセット、クリーン、ブランチ、HEAD の変更は行いません。追加されるのは
refs/checkpoints/...の参照のみです。 - Git リポジトリの外でも動作します。参照レイヤーを除き、同じ機能を利用できます。
- チャットログは保存されません。保存されるのはワークスペースのファイルと、モデルが宣言したステップのメモのみです。
- ストアのデフォルトは
<workspace>/.checkpoints/です。外部のstoreを指定すると、ワークスペースにはファイルの内容を含まない.task-checkpoint-store.jsonのパス参照のみが保存されます。 - 機密ファイルの検出はパスのブラックリスト方式であり、すべてを対象にするわけではありません。 スキャン対象のパスに認証情報を置かないでください。制限事項を参照してください。
インストール
オプション 1 — PyPI からインストール(推奨)
pipx install task-checkpoint-mcp
# or
pip install task-checkpoint-mcp
または、PyPI のバージョン管理を通さず、リポジトリを追跡して Git から直接インストールします。
pipx install "git+https://github.com/qddfxp/task-checkpoint-mcp"
次に、クライアントで tc-mcp を指定します。このパッケージには、同等のエントリーポイント tc-mcp と task-checkpoint-mcp の 2 つが含まれています(後者は、uvx のようにパッケージ名からコマンドを検索するランナー向けです)。
{
"mcpServers": {
"task-checkpoint": { "command": "tc-mcp", "args": [] }
}
}
オプション 2 — ソースから実行(インストール不要)
git clone https://github.com/qddfxp/task-checkpoint-mcp
{
"mcpServers": {
"task-checkpoint": {
"command": "/absolute/path/to/python",
"args": ["/absolute/path/to/task-checkpoint-mcp/scripts/tc_mcp.py"]
}
}
}
command には、python のような名前だけではなく、インタープリターの絶対パスを指定する必要があります。クライアントが意図したインタープリターを解決できない場合があります。インストール後は python -m tc_mcp も使用できます。
オプション 3 — npx 経由で起動
npm には同じ名前のパッケージがありますが、これはサーバーではなくランチャーです。
npx -y task-checkpoint-mcp
このランチャーは、tc_mcp をインポートできる Python インタープリターを見つけ、標準入出力を python -m tc_mcp に渡すだけです。そのため、先に Python パッケージをインストールする必要があります(オプション 1 または 2)。パッケージがない場合、ランチャーはインストールコマンドを表示して終了コード 1 で終了するため、トレースバックが表示されることはありません。
クライアントが npm スタイルの起動コマンドにしか対応していない場合に使用してください。
{
"mcpServers": {
"task-checkpoint": { "command": "npx", "args": ["-y", "task-checkpoint-mcp"] }
}
}
npx -y task-checkpoint-mcp --version / --help はランチャーのオプションなので、ローカルの Python は必要ありません。
設定ファイルの場所
mcpServers ブロックは、クライアントの設定ファイルに記述します。設定ファイルの場所とトップレベルキーは次のとおりです。
| クライアント | 設定ファイル | トップレベルキー |
|---|---|---|
| Claude Desktop | Windows %APPDATA%\Claude\claude_desktop_config.json;macOS ~/Library/Application Support/Claude/claude_desktop_config.json | mcpServers |
| Claude Code | プロジェクトルートの .mcp.json | mcpServers |
| Cursor | グローバル設定 ~/.cursor/mcp.json;プロジェクトローカルの .cursor/mcp.json が優先されます | mcpServers |
| Windsurf | ~/.codeium/windsurf/mcp_config.json | mcpServers |
| ZCode | ~/.zcode/cli/config.json | mcpServers |
| VS Code / Copilot | プロジェクトローカルの .vscode/mcp.json;ユーザーレベルの %APPDATA%\Code\User\mcp.json | servers |
| Codex CLI | ~/.codex/config.toml | JSON ではなく TOML の [mcp_servers] |
間違えやすい点が 2 つあります。
VS Code のキーは mcpServers ではなく servers です。 上記の JSON をそのままコピーしても動作しません。キー名を変更してください。
{
"servers": {
"task-checkpoint": { "command": "tc-mcp", "args": [] }
}
}
Codex は TOML を使用します。 同じ設定項目は次のようになります。
[mcp_servers.task-checkpoint]
command = "tc-mcp"
args = []
その他のクライアントについては、それぞれのドキュメントに従ってください。
使用方法
重要なルールは1つです:ファイルの変更はバックグラウンドスレッドによって自動的に記録されますが、「このステップで何をしたか、何が結論づけられたか、次に何をするか」は、モデルが tc_save を呼び出した場合にのみ記録されます。
そのため、エージェントはステップを完了するたびにチェックポイントを作成する必要があります。この取り決めは SKILL.md に記載されており、エージェントのスキルディレクトリにインストールします(下記を参照)。これがなくてもファイルのロールバックポイントは作成されますが、何をしていたのか、次に何をすべきかは誰にもわかりません。
4つのルール:
- 長時間のタスクを始める前に
tc_initを呼び出します。タスクごとに名前を1つ指定します。既存のアクティブなタスクは終了せず、一時停止します。再開するにはtc_switchを使います。 - ステップを完了するたびに
tc_saveを呼び出し、必ずconclusionとnextを入力します。入力しないと、次のセッションでファイルパスの一覧しか見られません。 - 新しいセッションを始めるとき、または中断後は、最初に
tc_resumeを呼び出します。進捗を最初から推測しないでください。 - ロールバックの前にプレビューします:まず
apply: falseで一覧を確認し、その後apply: trueを指定します。
ステップの粒度:完了したときに「完了し、結論は X です」と説明できる単位です。細かすぎる(ファイルごとに1つ)と重要な情報が埋もれ、粗すぎる(タスクごとに1つ)とロールバックの意味が失われます。
ツール
ツールは10個です。どれも最初に root(ワークスペースのディレクトリ。通常はプロジェクトの絶対パス)を指定します。
| ツール | 使用するタイミング | 必須項目 |
|---|---|---|
tc_init | 長時間のタスクを始めるとき。既存のアクティブなタスクは終了せず、一時停止します | root、name |
tc_save | ステップを完了するたび | root、title |
tc_resume | 新しいセッションの開始時、または中断された作業を引き継ぐとき(読み取り専用) | root |
tc_show | ステップ/ドリフト記録を確認するとき | root |
tc_restore | ステップまたはドリフト記録にロールバックするとき。適用前にプレビューします | root、および index または drift_id |
tc_capture | スレッドを待たずに、今すぐファイル変更のキャプチャを強制するとき | root |
tc_switch | 以前に一時停止したタスクに戻るとき | root、task_id |
tc_export | 引き継ぎパッケージを別のディレクトリ/マシンにエクスポートするとき | root、to |
tc_import | 他の人の引き継ぎパッケージをインポートして、ここで作業を続けるとき | root、package |
tc_compress | 古いドリフトレイヤーから空き容量を確保するとき | root |
tc_save のフィールド:
title(必須)— 変更した内容ではなく、実行したことを1行で記述しますconclusion— このステップで導き出された結論です。最も価値のあるフィールドですnext— 次に行うことです。作業を再開可能にする項目ですdescription— その作業を行った理由です(後になって誰も思い出せない判断の根拠です)verified— 実際に実行して確認した内容ですopen_questions— 次に引き継ぐ未解決の質問ですclose: true— タスクを終了します。終了したタスクも引き続き読み取れます
ロールバック自体もドリフトエントリとして記録されます。返される recovered はその drift_id なので、誤ったロールバックもロールバックできます。
確認しておくとよいレスポンスフィールド
tc_resume.handoff— 新しいセッションにそのまま貼り付けられる、すぐに使える引き継ぎテキストです。drift_pathsはまだ記録されていないディスク上の変更、health.errorsはストア自体の問題を示しますtc_save.idempotent— 同じステップ(同じタイトル、ファイルダイジェスト、結論、次の作業、検証内容)を再度保存しても、重複して記録されませんtc_save.active_task_changed— 別のタスクのtask_idを渡すと、アクティブなタスクが切り替わります(元のタスクは一時停止します)。このフィールドは切り替えが発生したことを示しますtc_restore.recovered— ロールバック自体のdrift_idtc_restore.plan.unrestorable/skipped_paths— 復元できなかったファイルです。プレビューと実行では同じ一覧が使われますtc_capture.waiting/partial— まだ静穏期間中であること、および不完全な中間記録を示しますtc_init.exclude— 設定した除外パターンをそのまま返しますtc_export.path— パッケージのディレクトリです。作業を引き継ぐ人向けのプロンプトHANDOFF.mdが含まれています
エージェントのスキルディレクトリに SKILL.md をインストールする
SKILL.md はこのプロジェクトのもう一つの柱であり、任意のドキュメントではありません。MCP サーバーが保存を担当し、各ステップの後にモデルが実際に tc_save を呼び出すようにするのが SKILL.md です。
クライアントがスキャンするディレクトリにコピーしてください。ディレクトリ名がスキル名になります。
| クライアント | パス |
|---|---|
| Claude Code | ~/.claude/skills/task-checkpoint/SKILL.md |
| Codex CLI | ~/.codex/skills/task-checkpoint/SKILL.md |
| ZCode | ~/.zcode/skills/task-checkpoint/SKILL.md |
| クライアント間で共有 | ~/.agents/skills/task-checkpoint/SKILL.md |
~/.agents/skills/ は複数のクライアントで共有されます。同じスキル名が両方に存在する場合は、クライアント固有のディレクトリが優先されます。OpenCode などの場合は、そのクライアントのドキュメントに記載されているスキルディレクトリを使用してください。ルールは変わりません。
tc-mcp --install-skill ~/.claude/skills/task-checkpoint
SKILL.md はホイール内のパッケージデータとして同梱されるため、pipx install を使う場合、リポジトリもネットワークアクセスも必要ありません。既存のファイルは上書きされません。上書きする場合は --force を指定してください。代わりに tc-mcp --print-skill を実行すると、内容が出力されます。
クローンを使用する場合は、cp SKILL.md <skill-dir>/ でも同じです。
Windows では、パスは C:\Users\<you>\.claude\skills\task-checkpoint\SKILL.md のようになります。クライアントによってスキャンするディレクトリは異なる場合があります。各クライアントのドキュメントを確認してください。必要なのは、ファイルが <skill-dir>/<skill-name>/SKILL.md に配置されていることだけです。有効にするには、クライアントを再起動してください。
確認(任意)
エントリーポイントが動作していることと、使用中のバージョンを手早く確認する方法です。
tc-mcp --version # version
tc-mcp --help # all flags
以下はすべてクローンが必要です。pip インストールには tests/ も tools/ も含まれません。
クローンしたリポジトリ内で回帰テストを実行します。
python -m unittest discover -s tests -p "test_*.py" -v
最後の行が OK になれば成功です。全テスト(100 件以上)の所要時間は、実行環境によって大きく異なります。
| 場所 | 実測値 |
|---|---|
| CI ubuntu runner | 4.7 s |
| CI windows runner | 39.8 s |
| このマシン、Windows(E: ドライブ) | 156–340 s |
同じコードでも、所要時間には最大 70 倍の差があります。時間がかかるのは git のサブプロセス(refs/checkpoints/ のケースが大半を占めます)と静穏期間の待機であり、ディスク速度やオンアクセスのウイルススキャンの影響を非常に受けやすいため、これらの数値は保証と見なさないでください。また、この数値でマシンを比較しないでください。
標準ライブラリのみ(unittest)を使用し、pytest は不要です。Python 3.10 でも実行できます。pyproject.toml を読み込むケースは、tomllib が 3.11 以降であるためスキップされます。
このリポジトリには、実際のワークスペースで実行するエンドツーエンドのドリルも含まれています(実際の MCP サブプロセスを起動して実行中に強制終了し、約 190 MB の大きなワークスペースを構築して、「git に手を加えない」という約束を項目ごとに検証します)。
python tools/drill.py
終了時にワークスペースは削除されます。保持するには TC_DRILL_KEEP=1 python tools/drill.py を実行してください(ドリルに失敗がある場合は、診断に役立つよう自動的に保持されます)。
MCP サーバーが起動することを確認します。serverInfo を含む JSON 1 行を返します。
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' | python scripts/tc_mcp.py
pip でインストールしたコピーには scripts/ がありません。最後の部分を ... | tc-mcp(または python -m tc_mcp)に変更してください。
環境変数
| 変数 | デフォルト | 意味 |
|---|---|---|
TC_STORE | <workspace>/.checkpoints | 保存ディレクトリ |
TC_WATCH | on | off にすると、バックグラウンド記録を無効にします |
TC_WATCH_INTERVAL | 15 | バックグラウンドのポーリング間隔(秒) |
TC_DRIFT_MAX_WAIT | 60 | 静穏期間の上限(秒) |
TC_GIT | on | off にすると、refs/checkpoints/... の作成を完全に停止します |
TC_GIT_VERIFY | on | 前後で git のフィンガープリントを取得し、リポジトリに変更がないことを証明します。off にすると、tc_save ごとの git サブプロセスをいくつか省略できます。その場合、git.unchanged は null を返します |
TC_SHA_REUSE | off | mtime とサイズが変わらない場合、再読み込みせずにインデックス済みの sha を再利用します。リスクについては「制限事項」を参照してください |
制限事項
機密ファイル:すべてをカバーするわけではないブラックリスト
機密ファイルについて保存されるのは、内容でもハッシュでもなく、mtime とサイズが変更されたかどうかだけです。パスに基づいて検出するため、両方向で見落としが発生します。
- 偽陰性:無害な名前の認証情報は検出されません。
config/database.yaml、docker-compose.yml、config.jsonはpayload/に平文で保存されます。認証情報をスキャン対象のパスに置かないでください。避けられない場合は、tc_init(exclude=[...])を使ってディレクトリ全体を除外してください。 - 偽陽性:機密ファイルと誤分類されたソースファイルは内容のコピーが保存されないため、ロールバック時に何も通知されずスキップされます(
plan.unrestorableにのみ表示されます)。これがリストを2段階にしている理由です。
ブロックされる対象:
- ディレクトリ名(ディレクトリ全体):
.ssh.aws.gnupg.docker.kube.env.envdir.secrets.tokens、または名前にsecret/credential/tokenが含まれるディレクトリ。 - 明確に判定できるファイル名:
.env.env.**.env*.envrc;*.pem*.key*.p12*.pfx*.p8*.jks*.keystore*.kdbx*.ppk*.ovpn*_rsa*_dsa*_ed25519*_ecdsa*_key;.netrc.git-credentials.npmrc.pypirc.pgpass.htpasswd.my.cnfmy.cnfpasswdshadow;kubeconfig*.kubeconfig*.tfstateterraform.tfvars*.tfvars*.jwt;credentials*creds*secret*secrets.jsontokentoken.jsontoken.txt*.token*_tokenauth.json;settings.pylocal_settings.pysettings.xmlwp-config.phpweb.configwrangler.toml.dev.vars。 - 曖昧な部分文字列(
*secret**password**passwd**credential**api_key**apikey**token**auth_token*):ファイル名が設定ファイル形式の拡張子で終わる場合にのみブロックされます。対象となる拡張子は.json.yaml.yml.toml.ini.cfg.conf.config.properties.xml.txt.env.envrc.cnf.sh.ps1.bat.cmd.sql.phpです。そのため、prod_credentials.jsonはブロックされますが、src/password_policy.py、src/tokenizer.py、docs/secrets.mdはブロックされません。
exclude パターンにも同じルールが適用されます。glob は単一の名前セグメント(ディレクトリ名、またはパスの最初のセグメント)に対して照合されます。exclude=["config"] は、どの深さにある config/ ディレクトリも除外しますが、特定のファイルだけを除外することはできません。config/database.yaml を除外すると、config/ 全体が除外されます。/ を含むパターンは、黙って無視されるのではなく、明示的に拒否されます。
これはプライバシー保護でも、コンプライアンスを保証するものでもありません。 ストアへのアクセス権限はご自身で管理してください。除外されていない認証情報、トークン、秘密鍵、個人データをスキャン対象のパスに置かないでください。
タイミングと粒度
- 待機時間は最大で約60秒です。ファイルの変更が続いている間、中間レコードには
partial: trueが設定されます。 - プロセスが突然終了すると、変更の末尾部分は次の
tc_save/tc_captureまで、まだ記録されていないパスとしてtc_resumeにのみ表示されます。
差分検出レイヤーが参照するのは mtime+サイズのみ
tc_capture とバックグラウンドスレッドは、mtime+サイズで変更を検出します。内容が変わっていても mtime と長さが同じ場合(cp -p、rsync -t、tar -x は mtime を保持します)、変更は検出されません。
tc_save はデフォルトで内容をハッシュするため影響を受けません。ただし、TC_SHA_REUSE=on の場合はタスクレイヤーにも同じ判定が適用されます。
ロールバック
- パーミッションビット(POSIX の実行ビット)は復元されますが、mtime は復元されません。古いタイムスタンプを書き戻すと、make のようなツールが変更なしと判断するためです。注:内容が同一のパーミッションのみの変更では書き換えが発生しないため、その場合はビットも変更されません。
- 復元できないファイル(機密ファイル、保存された内容がない100 MB超のファイル、ペイロードが失われたファイル)はスキップされ、残りは処理されます。スキップされたパスは
plan.unrestorableに表示されます。プレビューと実行では同じリストが使われるため、.envが1つあってもロールバック全体が失敗することはありません。 - バイナリは復元されますが、行単位の差分は表示されません。並行して行われた編集はマージされません。
大きなファイル
100 MB までのファイルは payload/ に内容をそのまま保存し、内容に基づいて重複排除されます。100 MB を超えるファイルについては、ストリーミングハッシュとメタデータのみが保持されます。内容は保存されないため、内容のロールバックはできません。
ストアは自動的には縮小しません
古いドリフト内容は、tc_compress を呼び出すまで残ります。デフォルトは 7 日間保持 なので、小規模なワークスペースでは、デフォルト設定で呼び出すと converted: 0 と報告されることがよくあります。レスポンスの keep_seconds / minimum / maximum / eligible / bytes_freed がその理由を示します。実際に容量を回収するには、より小さい keep_seconds を指定してください。ステップのベースラインと recovered レイヤーには一切触れません。
TC_SHA_REUSE=on のリスク(デフォルトでオフになっている理由)
デフォルトでは、タスクレイヤーは保存のたびに内容をハッシュ化します。mtime は信頼しません。そのため、ワークスペース内の機密情報を含まないすべてのファイルが保存のたびに読み込まれます(内容は保持されないため、メモリ使用量がワークスペースのサイズに応じて増えることはありません)。
TC_SHA_REUSE=on の場合、mtime とサイズが変わっていないファイルは再読み込みされず、インデックス済みの sha が再利用されます。mtime が復元された場合(os.utime)、ファイルシステムの mtime 精度が粗い場合(FAT、一部のネットワークドライブ)、またはツールが mtime を保持する場合(cp -p、rsync -t、tar -x、一部のジェネレーター)、内容の編集が完全に見逃されます。何も読み込まれず、新しい内容も保存されず、古い sha がステップの記録に残り、ロールバックしても古い内容が黙って返されます。デフォルト設定ではこの問題は発生しません。
どちらのモードでも、tc_resume と tc_show はファイル内容を読み込みません(mtime とサイズのみを確認します)。そのため、mtime を保持する編集を見逃す可能性があります。
引数と状態の制約
tc_restoreに指定できるのはindexまたはdrift_idのいずれか一方だけです。apply=trueは、クローズ済みのタスクを変更しようとすると拒否します。- 別のタスクの
task_idをtc_saveに渡すと、まずアクティブなタスクが切り替わります(元のタスクは一時停止状態になります)。その場合はactive_task_changed: trueで確認できます。元に戻すにはtc_switchを使ってください。 - ベースラインが存在し、未記録の変更が検出された場合、
tc_saveはステップを書き込む前に、その保存のマニフェストに変更を追加します。 tc_exportでは、保存先の親ディレクトリが存在している必要があります。tc_importはタスク ID とワークスペースパスを検証し、タスクの重複、..によるパストラバーサル、シンボリックリンクの参照先を拒否します。また、失敗した場合は書き込んだファイルをロールバックします。storeにワークスペースのルートを指定することはできません。ワークスペース内にカスタムのstoreを置いた場合は、スキャン対象から自動的に除外されます。
git
git リポジトリ内では、各 tc_save で参照を作成するための git サブプロセスが実行されるため、数百ミリ秒余分にかかります。これを避けるには TC_GIT=off または TC_GIT_VERIFY=off を設定してください。
ストレージ構成
<workspace>/.checkpoints/
├── current.json active-task pointer, keyed by workspace root (one store can serve many)
├── state.lock concurrency lock
├── server.log logs (never stdout; stdout carries MCP frames only)
├── payload/<sha2>/ content-addressed file copies, deduped by sha across tasks
└── tasks/<task_id>/
├── state.json
├── index.json baseline index: mtime/size/sha256 per file
├── steps/sNNNN.json task layer: one record per step
├── drifts/dNNNN.json drift layer: file changes
└── manifest/mNNNN.json consistency manifests (incremental chain, full anchor every 20)
アクティブポインターとベースラインインデックスはワークスペースごとに管理されます。複数のワークスペースで同じ store を共有しても、情報が互いに漏れることはありません。
リポジトリ構成
.
├── README.md this file
├── SKILL.md the agent-facing usage contract (part of the feature, ships with the package)
├── LICENSE MIT
├── pyproject.toml packaging; sources stay in scripts/, not a package dir
├── MANIFEST.in what goes into the sdist
├── server.json publish metadata for the official MCP Registry
├── glama.json ownership marker for the Glama directory
├── scripts/
│ ├── tc.py core
│ └── tc_mcp.py stdio MCP adapter + the human-facing command-line flags
├── tools/
│ └── drill.py end-to-end probe against a real workspace (not in the test suite, run by hand)
├── npm/ the npm launcher package (a shell; the server itself is not here)
├── tests/
│ ├── test_tc.py full acceptance suite (rollback safety, concurrency lock, git refs, return fields, packaging contract)
│ ├── test_tc_regressions.py targeted regressions for fixed defects
│ └── test_packaging_consistency.py the three version numbers / registry metadata / README ownership marker
└── .github/workflows/ci.yml CI: run the tests, build, validate server.json and the wheel
ビルド成果物はリポジトリに含めません。リリースチャネルは 2 つあります。主なチャネルは PyPI の task-checkpoint-mcp(pipx install task-checkpoint-mcp)で、wheel と sdist は GitHub Releases にも添付されています。
コントリビューション
Issue と PR を歓迎します。コードを変更する前にテストを実行してください(上記の「Verify」を参照。100 件以上のケースがあり、ここでは 2.5〜6 分かかります)。
tests/test_tc.pyは包括的な受け入れテストスイートです。ロールバックの安全性、同時実行ロック、git 参照の到達可能性、各分岐の戻り値フィールド、パッケージングの契約を検証します。tests/test_tc_regressions.pyには修正済みの不具合を対象とする回帰テストがあります。バグを修正した場合は、コードだけを変更するのではなく、こちらにテストケースを追加してください。
厳守すべき制約が 1 つあります。標準ライブラリのみを使用してください。 新しい依存関係は追加できません。テスト用の依存関係も同様です(テストには pytest ではなく unittest を使用しています)。
ライセンス
MIT — LICENSE を参照してください。
このコードを変更する方向けの実装上の注意事項(.git/index のバイト数、参照の衝突時の動作、ロック戦略、マニフェストのアンカー付け)については、上記の中国語のセクションを参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。