Every team I've worked with has the same gap. The tracker says one thing, and git says another. By the end of a sprint, the board is a guess.
We use Plane, self-hosted. Our work happens in the terminal, more and more through a coding agent, and in git. Typing it all into Plane afterwards is the chore nobody does.
The idea
Git already records what changed, when, and by whom. Conventional commits even say what kind of change: fix(auth): ... or feat(billing): .... Instead of asking people to update the tracker, read the history and propose the tracker entries.
What I built
plane-workflow-mcp is an MCP server and CLI for Plane. It works with Claude Code, Codex, Cursor, Claude Desktop, OpenCode, and Zed. The backfill flow has four steps:
-
Plan (read-only). It runs
git loglocally and groups commits into work items: first by a path map you give it (apps/web/→ Web), then by commit scope, then by folder. A group splits when work pauses for more than a few days. - Date. Start and target dates come from the first and last commit. They're moved onto the project's business days, so weekend commits land on a working day.
- Review. You (or your agent) rename, regroup, or skip items. Nothing is written yet.
- Apply. Each item is created, started on its real first-commit date, and completed with a comment listing its commits.
What broke when I ran it on real projects
I spent a day backfilling several real projects. Everything that broke became a fix:
-
Rate limits. Plane returns 429 quickly when you create, start, and complete dozens of items. Requests now back off and honor
Retry-After. -
Timeouts that succeed. A create can time out on the client and still succeed on the server. A naive retry duplicates it. Every create now carries a stable
external_idderived from the item's first commit, so a retry, or a whole re-run, finds the existing item instead. - Misleading errors. A 429 used to surface as "work item not found". Now only a real 404 says that.
- Projects without estimates. Strict planning mapped complexity to estimate points that didn't exist, and Plane answered with a bare 400. Now you get a sentence telling you what to change.
Honesty rules
A backfilled item is not a verified one. The completion comment says the evidence is the commits and that no tests were run during the backfill. Plane stamps completed_at with the current time, so the real dates live in the start and target dates and in the comment.
Try it
uv tool install plane-workflow-mcp
plane-workflow setup --client claude-code # or codex, cursor, claude-desktop
plane-workflow backfill --since 2026-09-01 # prints the plan; add --apply to write
Or ask your agent:
Read this repo's git history since September 1 and propose Plane work items with plan_git_backfill. Show me the plan as a table. Don't write anything until I approve.
Day to day, the same server plans, starts, and completes work items under your team's rules (assignee, labels, estimates, business-day dates), with dry-run previews and briefings on overdue and unassigned work.
It's MIT licensed, a community project, and not affiliated with Plane. If you use Plane, I'd like to hear where your tracker drifts from reality most. Issues and stars on GitHub are very welcome.

Top comments (2)
Git history is valuable evidence, but it needs a human-readable bridge from commits to decisions. Linking PR context, incident notes, and the reason a trade-off was accepted makes archaeology faster without pretending the commit message alone tells the whole story.
The timeout that still succeeds is the detail worth keeping. Deriving external_id from the first commit stops a retry from turning into a duplicate.