My coding agents don't need a project management tool. They need markdown files. A developer built board.md, a local kanban board that reads and edits markdown task files already stored in a repository, after finding that coding agents only needed readable text files rather than a hosted project tracker. The tool derives in-progress and in-review states from git branches and pull requests, and a card drag rewrites only the single status line in a file's YAML frontmatter to avoid noisy diffs. It also exposes four CLI commands — list, new, set and check — so agents get the same guarantees as the board. My coding agents used to read their tasks from a hosted tracker. They never needed one. They needed a folder of markdown files, and I needed a small board to look at them. This is how I worked that out, and the tool that came from it: board.md https://www.npmjs.com/package/board.md , a local board for the markdown task files already in your repo. I was about to pay for a database when the only reader of the data was an agent that reads text. I run several projects with coding agents. The tasks lived in Notion, on the free plan, and the agents pulled task details through its MCP server. It worked. But with a few projects I was close to the free plan's limit, and the next step would have cost me about $40 a month. It would have gone the same way with Jira, Monday or ClickUp: the limit and the price differ, the problem doesn't. Before paying, I looked at what the agents actually did with a task. They read the title, the notes and a few fields. Then they changed a status. That was all. An agent needs a file it can read and edit. One markdown file per task, in the repo, with the fields in YAML frontmatter and the notes below: --- id: DEMO-4 title: "Projects CRUD" status: todo phase: P2 module: projects priority: P0 size: M branch: pr: --- DEMO-4 Projects CRUD Soft delete. Names unique per account, ignoring case. That format beats a hosted tracker for an agent in four ways: main always shows what is merged. git log on the file is the task's history. One of my projects already worked this way, with 88 task files. The agents were happy. I was the problem. I needed to see 88 files as columns and drag a card from one to the next. Nothing more. My first plan was something bigger, with a database behind it. I didn't need any of that: the files were already the database. The markdown kanban tools I looked at each wanted their own file layout, and I didn't want to convert files my agents already understood. So board.md reads the files you have. npx boardmd init looks at them and works out a config: the id format, the statuses, which fields become badges or filters. npx boardmd serve shows the board on localhost. image: Demo: a card dragged from Todo to In progress changes one line in its file; boardmd new creates a task and its card appears on the board "In progress" and "in review" are not written in any file. The board reads them from git each time it loads. task/demo-4-projects-crud , shows that task as in progress. todo gets a badge, so you can see the file is behind. This matters most with agents. My agent creates a branch, does the work and opens a pull request. The card moves across the board by itself, and nobody edits a status until the pull request sets it to done. When I drag a card, exactly one line of one file changes: -status: todo +status: in-progress This is the rule the tool is built around. The files belong to the agents and to code review. A board that re-serialises the YAML reorders keys, changes quotes and turns a status change into a noisy diff that conflicts with the next branch. So a drop does very little, on purpose: status: line is replaced. The key, spacing, quotes, any comment and the line ending stay as they were. A file with no status: line is refused, not given one. The board never commits or pushes; a banner lists the files you changed so you can. An agent gets the same guarantees as the board, through four commands. | Command | What it guarantees | |---|---| | boardmd list --json | Every open task with its fields, its file and its live state from git. | | boardmd new "