Skip to content

Backlog

Go

Manage the backlog of your project with just markdown in git. The goal is to provide a frictionless collaboration between AI agents and developers

Backlog is a zero-configuration task manager written in Go where tasks live inside a Git repository. It leverages plain Markdown files for task storage and a comprehensive command-line interface (CLI) for interaction. This design makes it exceptionally well-suited for AI agents thanks to its CLI and MCP (Model Context Protocol) integration.

The system is designed to be offline-first and completely portable, as the entire project state is contained within the Git repository.

Introduction

THIS SECTION IS FOR HUMANS

The context window deteriorates rapidly on large-scale projects. A workaround I found is to ask the agent to make a plan for X, write it to a markdown file and keep it updated with the ongoing tasks. It is a simple prompt. This technique has worked incredibly well, making refactoring and other significant code changes more resilient to failures, retries or rate-limiting from the model.

However, this approach cluttered the repository's root directory with files like plan.md or refactor_this_big_codebase.md. To solve this, I created an MCP server that I could understand and trust to handle these details, which has provided a much better experience when using AI tools for complex tasks. Through trial and error, I fine-tuned the parameters to get the results I needed from this project.

You can see an example in the .backlog folder of this repo. It has been generated with this prompt :

If you were to recreate this project from scratch, make a plan and break it down into tasks using backlog break down prompt.
Write that plan to a markdown file called "./docs/plan.md".
Check that the plan in ./docs/plan.md is consistent with the list of tasks in the backlog.
Add implementation plan to relevant tasks
All tasks should have at least one acceptance criteria.

Read the full instructions for backlog: ./internal/mcp/prompt-cli.md

Assuming that backlog is registered as an MCP server with the command backlog mcp. See configuration examples in .gemini and .claude.

Interestingly, while this codebase is mostly hand-written, the documentation, comments, examples, and some of the tests were generated with AI. I found that AI agents yield better results when the structure of the project is already there and exactly how you want it, with the libraries you want, in the code style you want. After that, it gets easier.

I used a few tools for learning purposes, all are paid tier:

  • gemini-2.5-pro
  • claude-sonnet4
  • github-copilot
  • amp

To instruct your AI tools to use backlog, see ./internal/mcp/prompt-cli.md or ./internal/mcp/prompt-mcp.md. It is available through backlog instructions > backlog_instructions.md

The rest of this document is mostly generated by AI (except the Inspiration section). Enjoy.

Philosophy

Simplicity Over Features: Backlog aims to handle fewer use cases well rather than many use cases poorly. It focuses on the core workflow of task management for developer-AI collaboration.

AI-First Design: Unlike traditional task managers designed for humans first, Backlog was designed from the ground up to work seamlessly with AI agents while still being useful for human developers.

Transparency: Everything is stored as human-readable Markdown files in Git. No databases, no proprietary formats, no lock-in.

Developer Control: You own your data completely. Everything lives in your Git repository and can be edited manually if needed.

Development Story

While this codebase is mostly hand-written, the documentation, comments, examples, and some tests were generated with AI assistance. I found that AI agents yield better results when:

  1. The project structure is already established exactly as desired
  2. The libraries and dependencies are already chosen
  3. The code style and patterns are already defined

After establishing these foundations, AI assistance becomes much more effective for implementation details.

Features

  • Task Management: Create, edit, list, and view tasks with rich metadata
  • Hierarchical Structure: Support for parent-child-grandchild task relationships (T01 → T01.01 → T01.01.01)
  • Search & Filter: Find tasks by content, status, parent relationships, and labels using the list command with the --query flag
  • AI-Friendly: MCP server integration and a dedicated instructions command for seamless AI agent collaboration
  • Git Integration: Tasks are stored as Markdown files with automatic Git commits
  • Offline-First: Works completely offline with local Git repository storage
  • Portable: Entire project state contained within the Git repository
  • Conflict Diagnosis: Automatic detection and resolution of task ID conflicts in Git workflows
  • Zero Configuration: No setup files or databases required

Quick Start

Installation

# Build from source
git clone https://github.com/veggiemonk/backlog
cd backlog
go build .

# Or install directly
go install github.com/veggiemonk/backlog@latest

# Or in a container
docker pull ghcr.io/veggiemonk/backlog:latest

You can also download the binary from the release page.

Using the Container

The backlog container is designed to work with your local project directory. Here are common usage patterns:

# Basic usage - mount current directory and set backlog folder
docker run --rm -it -v $(pwd):/data -e BACKLOG_FOLDER=/data/.backlog ghcr.io/veggiemonk/backlog list

# Create a task
docker run --rm -it -v $(pwd):/data -e BACKLOG_FOLDER=/data/.backlog ghcr.io/veggiemonk/backlog create "Fix bug in authentication"

# View a specific task
docker run --rm -it -v $(pwd):/data -e BACKLOG_FOLDER=/data/.backlog ghcr.io/veggiemonk/backlog view T01

# Edit a task
docker run --rm -it -v $(pwd):/data -e BACKLOG_FOLDER=/data/.backlog ghcr.io/veggiemonk/backlog edit T01 --status "in-progress"

# Start MCP server (for AI integration)
docker run --rm -it -v $(pwd):/data -e BACKLOG_FOLDER=/data/.backlog -p 8106:8106 ghcr.io/veggiemonk/backlog mcp --http --port 8106

Container Tips:

  • Mount your project directory to /data for file persistence
  • Set BACKLOG_FOLDER=/data/.backlog to store tasks in your project
  • Use -p 8106:8106 when running the MCP server to expose the port
  • The --rm flag removes the container after execution
  • All CLI commands work the same way in the container

Initialize Your Project

No initialization is needed.

Task Directory Resolution

Backlog stores tasks in a directory referred to as the "tasks folder". By default this is .backlog, but you can override it.

How to set the folder

  • CLI flag: --folder <path> (relative or absolute)
  • Environment variable: BACKLOG_FOLDER (used when set)
  • Default: .backlog

Resolution rules (applied to the chosen value)

  • Absolute path: used as-is.
  • Relative path: resolved with this precedence:
    • If <CWD>/<path> exists, use it.
    • Search parent directories; if <ancestor>/<path> exists, use it.
    • If a git repository is detected, use <gitRoot>/<path>.
    • Otherwise, fall back to <CWD>/<path> (created on demand).

Container tips

  • If your container does not include the .git directory, the resolver still works using the upward search and CWD fallback.
  • For predictable behavior, mount your tasks directory and set BACKLOG_FOLDER to its absolute mount point, or pass --folder with an absolute path.

Configuration

Backlog supports configuration through command-line flags and environment variables. Command-line flags take precedence over environment variables.

Available Configuration Options

Configuration Flag Environment Variable Default Description
Tasks Directory --folder BACKLOG_FOLDER .backlog Directory for backlog tasks
Auto Commit --auto-commit BACKLOG_AUTO_COMMIT false Auto-committing changes to git repository
Log Level --log-level BACKLOG_LOG_LEVEL info Log level (debug, info, warn, error)
Log Format --log-format BACKLOG_LOG_FORMAT text Log format (json, text)
Log File --log-file BACKLOG_LOG_FILE "" Log file path (defaults to stderr)

Configuration Examples

# Using command-line flags
backlog --folder /custom/path --log-level debug --auto-commit false list

# Using environment variables
export BACKLOG_FOLDER="/custom/path"
export BACKLOG_LOG_LEVEL="debug"
export BACKLOG_AUTO_COMMIT="false"
backlog list

# Flags override environment variables
export BACKLOG_FOLDER="/env/path"
backlog --folder "/flag/path" list  # Uses /flag/path

# Logging examples
backlog --log-format json --log-level debug list
BACKLOG_LOG_FILE="/tmp/backlog.log" backlog list

Configuration Notes

  • Environment Variables: All environment variables use the BACKLOG_ prefix
  • Precedence: Command-line flags > Environment variables > Default values
  • Log Output: When --log-file is not specified, logs are written to stderr
  • Boolean Values: For environment variables, use true/false strings (e.g., BACKLOG_AUTO_COMMIT=false)

AI Agent Integration

Backlog is designed for seamless integration with AI agents through two primary methods: the Model Context Protocol (MCP) server and direct CLI calls.

Backlog includes an MCP server that exposes task management capabilities as structured tools. This is the recommended approach for AI agents that support tool use, as it provides a clear, typed API for interaction.

Available Tools

  • task_create: Create new tasks with full metadata.
  • task_list: List and filter tasks.
  • task_view: Get detailed information for a specific task.
  • task_edit: Update existing tasks.
  • task_archive: Archive tasks so they are not displayed in lists but remain in the repository.

Usage

To make these tools available to an agent:

  1. Instruct your AI tools with backlog instructions --mcp
  2. Start the MCP server
# Instruct agent how to interact with backlog.
backlog instructions --mode mcp >> AGENTS.md

# Start MCP server for AI integration (HTTP transport)
backlog mcp --http --port 8106

# Or start the server using STDIO transport
backlog mcp

AI agents configured to use this server can then reliably perform task operations like creating tasks, breaking down large projects, and updating progress.

2. Direct CLI Usage

For agents that are proficient with shell commands, or for workflows where token usage is a concern, backlog can be used directly as a command-line tool. The agent can construct and execute backlog commands just as a human developer would.

This method bypasses the MCP server, which can reduce overhead and token consumption associated with JSON-based tool calls.

Example CLI Usage by an Agent

An agent could be instructed to use backlog with backlog instructions --cli

# Instruct agent how to interact with backlog.
backlog instructions --mode cli >> AGENTS.md

# Agent creates a new task
backlog create "Refactor the authentication module" -d "The current module is hard to test."

# Agent lists tasks to see what's next
backlog list --status "todo" --priority "high"

# Agent marks a task as complete
backlog edit T05 --status "done"

Choosing the Right Method

  • Use MCP Server when: Your agent has robust tool-use capabilities and you prefer structured, predictable interactions.
  • Use Direct CLI when: Your agent is skilled at generating shell commands, you want to minimize token usage, or you need the full flexibility of the CLI flags not exposed via MCP.

Usage Examples

AI Integration (MCP Server)

# Start MCP server for AI agents (backlog mcp --http transport)
backlog mcp --http  # default port 8106
backlog mcp --http --port 8106 # specify the port

# Start MCP server (stdio transport)
backlog mcp

See this repository .gemini or .claude for example configurations.

Basic Task Creation

# Simple task
backlog create "Fix the login button styling"

# Task with description
backlog create "Implement password reset" \
  -d "Users should be able to request a password reset link via email"

# Task with assignees and labels
backlog create "Update dependencies" \
  -a "alex" -a "jordan" \
  -l "maintenance,backend,security" \
  --priority "high"

Hierarchical Task Structure

# Create parent task
backlog create "Implement User Authentication"
# → Creates T01-implement_user_authentication.md

# Create subtask
backlog create "Add Google OAuth login" -p "T01"
# → Creates T01.01-add_google_oauth_login.md

# Create sub-subtask
backlog create "OAuth token validation" -p "T01.01"
# → Creates T01.01.01-oauth_token_validation.md

Advanced Task Creation

# Comprehensive task with acceptance criteria
backlog create "Build reporting feature" \
  -d "Create monthly performance reports in PDF format" \
  -a "drew" \
  -l "feature,frontend,backend" \
  --priority "high" \
  --ac "Report generation logic is accurate" \
  --ac "Users can select date range" \
  --ac "PDF export works correctly" \
  -p "23"

Task Dependencies

You can define dependencies between tasks using the --deps flag. A task cannot be started until its dependencies are complete.

# Create a task that depends on another
backlog create "Deploy to production" --deps "T10"

# Create a task with multiple dependencies
backlog create "Final release" --deps "T10,T11"

# Add a dependency to an existing task
backlog edit T12 --deps "T13"

Task Management

# List all tasks
backlog list

# Filter by status
backlog list --status "todo"
backlog list --status "in-progress"
backlog list --status "done"

# Filter by parent (show subtasks)
backlog list --parent "T01"

# Pagination for large task lists
backlog list --limit 10                         # First 10 tasks
backlog list --limit 5 --offset 10              # Tasks 11-15
backlog list --status "todo" --limit 3          # First 3 todo tasks

# Search with pagination
backlog list --query "api" --limit 5                  # First 5 API-related tasks
backlog list --query "bug" --limit 3 --offset 5       # Search results 6-8

# View specific task
backlog view T01.02

# Edit task
backlog edit T01 --status "in-progress" --assignee "alex"

Conflict Management

When working with Git branches, task ID conflicts can occur when multiple branches create tasks with the same IDs. Backlog provides automatic detection and resolution capabilities:

# Detect ID conflicts
backlog doctor                           # Text output
backlog doctor --json                    # JSON output

# Automatically fix conflicts
backlog doctor --fix                     # Fix using chronological strategy (default)
backlog doctor --fix --strategy=auto    # Fix using auto-renumber strategy
backlog doctor --fix --strategy=manual  # Create manual resolution plan
backlog doctor --fix --dry-run          # Preview changes without applying

Conflict Types Detected:

  • Duplicate IDs: Same ID appears in multiple task files
  • Orphaned Children: Tasks reference non-existent parent IDs
  • Invalid Hierarchy: Parent-child relationships don't match ID structure

Resolution Strategies:

  • Chronological: Keeps older tasks unchanged, renumbers newer conflicting tasks
  • Auto: Automatically renumbers conflicting IDs using available ID space
  • Manual: Creates a resolution plan requiring manual intervention

Git Integration:

Backlog automatically checks for conflicts during Git operations and can auto-resolve them during merges to maintain task integrity.

# Container usage for conflict management
docker run --rm -it -v $(pwd):/data -e BACKLOG_FOLDER=/data/.backlog ghcr.io/veggiemonk/backlog doctor
docker run --rm -it -v $(pwd):/data -e BACKLOG_FOLDER=/data/.backlog ghcr.io/veggiemonk/backlog doctor --fix --dry-run

Task File Structure

Tasks are stored as Markdown files with YAML front matter in the .backlog/ directory:

---
id: "01.02.03"
title: "Implement OAuth integration"
status: "todo"
parent: "01.02"
assigned: ["alex", "jordan"]
labels: ["feature", "auth", "backend"]
priority: "high"
created_at: 2024-01-01T00:00:00Z
updated_at: 2024-01-01T00:00:00Z
---

## Description

Integrate OAuth authentication with Google and GitHub providers.

## Acceptance Criteria

<!-- AC:BEGIN -->

- [ ] #1 Google OAuth integration works
- [ ] #2 GitHub OAuth integration works
- [x] #3 OAuth scope validation implemented
<!-- AC:END -->

## Implementation Plan

1. Setup OAuth app registrations
2. Implement OAuth flow handlers
3. Add token validation
4. Write integration tests

## Implementation Notes

- Use oauth2 package for Go
- Store tokens securely
- Handle refresh token rotation

File Naming Convention: T{ID}-{slugified-title}.md

  • T01-implement_user_auth.md (root task)
  • T01.01-setup_oauth.md (subtask)
  • T01.01.01-google_oauth.md (sub-subtask)

Project Structure

.backlog/                     # Task storage directory
├── T01-user_auth.md         # Root task (ID: T01)
├── T01.01-oauth_setup.md    # Subtask (ID: T01.01)
├── T01.02-password_reset.md # Sibling subtask (ID: T01.02)
└── T02-frontend_redesign.md # Another root task (ID: T02)

Development

# Build the project
make build

# Run tests
make test

# Generate CLI documentation
make docs

# Lint code
make lint

Inspiration

This project is inspired by

but backlog aims to be simpler and handle fewer use cases while remaining AI-friendly.

For the MCP server, a lot of good examples are in go-sdk.

For real production use cases, GoogleCloudPlatform/gke-mcp is highly recommended.

Contributors

This project is made possible by all its contributors.

Made with contrib.rocks.