Task tracking in a single file. No database, no server, no dependencies β just TASKS.md and git. Inspired by beads, but much simpler.
- All state lives in git β full audit trail, easy to revert, works with branches
- No server or database to maintain β just a single Markdown (or CSV) file
- Works offline, works in any terminal, works with diffs
- AI-friendly β agents can read and write tasks through the CLI or MCP server
- Markdown format (
TASKS.md) for human-readable diffs - CSV format (
TASKS.csv) for spreadsheets and tooling, and clean git merges - Simple field extraction from input. Title is first sentense. Description is the rest. Type prefixes (
bug:,task:,feature:,idea:), Priority (P0-P5). - Task dependencies with automatic blocking detection
- Concurrent-write safe via optimistic locking β multiple processes or AI agents can write simultaneously
md primeprints LLM context,md mcpruns an MCP server over stdio
Binaries
Find the latest pre-compiled binaries here or download and install it now with
curl "https://i.jpillora.com/meads!?as=md" | bash
Source
go install github.com/jpillora/meads/cmd/md@latestmd add "Fix the login bug. 500 error when session cookie is expired"
# added task 1
md add "Write tests for login fix"
# added task 2
md ready
# 1. Fix the login bug
# 2. Write tests for login fix
md set-status 1 closed
# task 1 status set to closedThe resulting TASKS.md:
# TASKS
a [meads](https://github.com/jpillora/meads) (`md`) managed task log
* created: 2025-01-15T09:00:00Z
## 1. Fix the login bug
* status: closed
* created: 2025-01-15T09:00:00Z
500 error when session cookie is expired
## 2. Write tests for login fix
* status: open
* created: 2025-01-15T09:00:01Zmd add "title" Add a simple task
md add "bug: Fix login P1. Details" Rich input (type, priority, body)
md add --depends-on=1 "Write tests" Add with dependency
md create "title" Alias for add
md get <id> View a task
md list List all tasks
md ready Show unblocked open tasks (by priority)
md update <id> --priority=P1 Update task fields
md set-status <id> <status> Change status (draft|open|inprogress|closed)
md del <id> Delete a task
md add-dep <child> <parent> Add a dependency
md init Initialize a new tasks file
md convert TASKS.md Convert between Markdown and CSV formats
md doctor Detect and fix duplicate task IDs
md prime Print LLM context for using md
md mcp Start MCP server over stdio
md webui Launch web UI for this TASKS file
md webui hosts a localhost HTTP server with a web UI for viewing and
editing one TASKS.md (or .csv) file. It prints a single JSON line to
stdout on startup with the URL and access token:
md webui
# MEADS_WEBUI {"url":"http://127.0.0.1:54231","token":"β¦","file":"TASKS.md","format":"md"}Pass --open to launch the browser automatically, or --port 3000 for a
fixed port. All routes require the bearer token; change events are
streamed over Server-Sent Events at /api/events.
A VS Code extension in vscode/ registers itself as the default
renderer for TASKS.md / TASKS.csv and embeds the web UI. For v1 it
ships as a .vsix attached to each GitHub release β download from
Releases and install via
Extensions: Install from VSIXβ¦.
Add a task with type, priority, and body:
md add "bug: Fix login P1. Session cookie expires prematurely"View ready work (sorted by priority):
md readyCreate dependent tasks:
md add "feature: Build API endpoint" # returns ID 3
md add "Write tests for API" --depends-on=3 # blocked until 3 is closedTrack progress:
md set-status 3 inprogress # claim it
md set-status 3 closed # doneWhen multiple branches create tasks independently (common with AI agents working in parallel), they each assign the next available ID locally. After merging, this can result in duplicate task IDs in the same file.
To fix this, run:
md doctormd doctor scans for duplicate IDs and renumbers them. The first occurrence keeps its original ID; subsequent duplicates get new IDs. Any depends-on references within renumbered tasks are also updated to point to the correct new IDs.
- Format β Two storage backends, auto-detected by file extension:
TASKS.mdβ Markdown headings (## 1. Title) with* key: valuemetadata. Human-readable diffs.TASKS.csvβ Standard CSV with soft-delete and computed next-id. Easy to import into spreadsheets and other tools.
- Metadata β Built-in keys are
status,priority,type,depends-on,tags,close-reason,created, andupdated. - Concurrency β Concurrent writes are safe via optimistic file locking, so multiple processes (or AI agents) can write to the task file simultaneously without corruption.
- AI-friendly β Both formats are designed to be readable and writable by LLMs. Use
md primeto print context for an AI agent, ormd mcpto run an MCP server over stdio. - Minimal β Single static binary, no config files.