bea-rs 0.8.0

A file-based task tracker CLI and MCP server for AI agent workflows
Documentation

bears ๐Ÿป

CI crates.io GitHub release License: MIT

A file-based task tracker for developers and AI agents.

Heavily inspired by Steve Yegge's Beads that didn't really fit my workflow.

Tasks live as Markdown files with YAML frontmatter in a .bears/ directory โ€” plain text, git-friendly, no database. Run bea from the terminal or expose the same functionality as an MCP server for AI coding agents.


Install

From crates.io

cargo install bea-rs

Homebrew

brew install lhelge/tap/bears

Pre-built binary

Download the latest release for your platform:

curl -fsSL https://raw.githubusercontent.com/LHelge/bea-rs/main/install.sh | sh

This detects your OS and architecture, downloads the right binary from GitHub Releases, and installs it to /usr/local/bin. Set BEA_INSTALL_DIR to change the install location. Falls back to cargo install if no pre-built binary is available.

From source

git clone https://github.com/LHelge/bea-rs.git
cd bea-rs
cargo install --path .

The binary is named bea.


Quick start

bea init
bea create "Design the API" --priority P1 --tag backend
bea create "Implement endpoints" --priority P1 --tag backend --depends-on <id>
bea list
bea ready           # what can I work on right now?
bea start <id>
bea done <id>

Task format

Each task is stored as .bears/{id}-{slug}.md:

---
id: a1b2
title: Implement OAuth flow
status: open
priority: P1
type: task
created: 2026-03-15T10:30:00Z
updated: 2026-03-15T10:30:00Z
tags: [backend, auth]
depends_on: [f4c9]
parent: x9k2
---

Any Markdown body goes here.

Statuses: open ยท in_progress ยท done ยท blocked ยท cancelled

Types: task (default) ยท epic (high-level objective grouping child tasks)

Priorities: P0 (critical) ยท P1 ยท P2 ยท P3 (low) โ€” sorted P0 first everywhere. A task inherits the highest priority of any task that depends on it, so a P3 task blocking a P0 task is effectively treated as P0.


Commands

bea init

Create the .bears/ directory and .bears.yml config in the current directory.

bea init

Optionally scaffold coding-agent integration files with one or more harness flags:

bea init --claude    # CLAUDE.md + .mcp.json + .claude/skills/ + .claude/agents/
bea init --copilot   # .github/copilot-instructions.md + .github/mcp.json + .github/skills/ + .github/agents/
bea init --codex     # AGENTS.md
bea init --claude --copilot   # combine flags

Flags are idempotent: re-running them on an already-initialized directory is safe and refreshes the files. When merging .mcp.json / .github/mcp.json, any pre-existing unrelated server entries are preserved. The generated MCP server entry always uses bea mcp (not cargo run).

bea create

bea create "Title" [--priority P0-P3] [--tag tag1,tag2] [--depends-on id1,id2] [--body "..."] [--epic]

Use --epic to create an epic instead of a regular task. Epics are high-level objectives that group child tasks via the --parent flag.

bea list

Hides done and cancelled tasks by default. Use --all / -a to show everything.

bea list
bea list --status open
bea list --priority P0
bea list --tag backend
bea list --epic <epic-id>
bea list --all

bea ready

Show tasks that are open and have all dependencies completed. Epics are excluded โ€” only actionable tasks appear. This is the key command for agent workflows โ€” always start here.

bea ready
bea ready --tag backend --limit 5
bea ready --epic <epic-id>

bea show

bea show <id>

bea update

bea update <id> --status blocked
bea update <id> --priority P0 --tag urgent,backend
bea update <id> --title "New title" --body "Updated description"
bea update <id> --parent <epic-id>    # reparent under an epic (use "" to detach)

bea epics

List all epics with progress (done/total children).

bea epics

bea start / bea done / bea cancel

Shortcuts for the most common status transitions:

bea start <id>    # โ†’ in_progress
bea done <id>     # โ†’ done
bea cancel <id>   # โ†’ cancelled

When all children of an epic are completed, the epic is automatically marked as done.

bea dep

bea dep add <id> <depends-on-id>    # add dependency (cycle-safe)
bea dep remove <id> <depends-on-id>
bea dep tree <id>                   # show dependency tree

Adding a dependency that would create a cycle is rejected with an error.

bea delete

Permanently delete a task file.

bea delete <id>

bea prune

Permanently delete cancelled tasks. Use --done to also delete completed tasks. For recoverable cleanup, prefer bea archive.

bea prune
bea prune --done

bea archive / bea restore / bea log

Move settled work out of the active set into .bears/archive/, keeping list/ready/search/graph/epics focused on active tasks. Unlike prune, archiving is reversible.

bea archive            # sweep: archive every archivable task
bea archive <id>       # archive one task (and its settled epic children)
bea restore <id>       # bring an archived task (and its deps + parent epic) back
bea list --archived    # list archived tasks
bea log [--limit N]    # archived tasks, most recently archived first

A task is archivable only when it is done/cancelled and no active task still depends on it (otherwise archiving is refused, naming the blockers). Archived tasks are hidden from all normal listings; bea show <id> still finds them (labelled as archived), but mutating an archived task is refused until you restore it.

bea graph

Show the dependency graph as a tree. Hides done and cancelled tasks by default; use --all / -a to include them.

bea graph
bea graph --all

bea search

Matches against title, body, tags, and ID. Hides done and cancelled tasks by default.

bea search "oauth"
bea search "oauth" --all

bea edit

Open a task's .md file in your $EDITOR for direct editing. Falls back to $VISUAL, then vi. After the editor exits, the file is re-parsed and validated.

bea edit <id>

bea completions

Generate shell completions for bash, zsh, or fish.

bea completions bash
bea completions zsh
bea completions fish

Add to your shell config to enable completions:

# zsh โ€” add to .zshrc
eval "$(bea completions zsh)"

# bash โ€” add to .bashrc
eval "$(bea completions bash)"

# fish โ€” add to ~/.config/fish/config.fish
bea completions fish | source

Interactive TUI

bea tui

A full-screen terminal UI for browsing and managing tasks, with live refresh when .bears/ changes on disk (e.g. while an AI agent edits tasks in the background). Press m to cycle the list view โ€” Open, Ready, Epics, Completed (done/cancelled still in the active set), Archive (loaded from .bears/archive/), All โ€” / to filter by text, and edit the selected task in your $EDITOR. The detail pane shows a task's direct dependencies, and for epics the full subtask tree.


JSON output

Every command accepts --json for machine-readable output:

bea --json list
bea --json ready --limit 3
bea --json create "New task" --priority P1

MCP server

bears can run as an MCP server, exposing all task operations as tools for AI coding agents.

bea mcp   # starts MCP server over stdio

Available MCP tools

Tool Description
list_ready Tasks ready to work on (limit?, tag?, epic?)
list_all_tasks All tasks with optional filters (status?, priority?, tag?, epic?, limit?, active_only?)
list_epics List all epics with progress
get_task Full task details (id); falls back to the archive, marking the result archived: true
create_task Create a task or epic (title, priority?, tags?, depends_on?, parent?, body?, type?)
update_task Update fields (id, title?, status?, priority?, tags?, assignee?, body?, parent?)
start_task Set status to in_progress (id)
complete_task Set status to done (id)
cancel_task Set status to cancelled (id)
prune_tasks Permanently delete cancelled tasks (include_done?)
add_dependency Add a dependency, cycle-safe (id, depends_on)
remove_dependency Remove a dependency (id, depends_on)
delete_task Permanently delete a task (id)
search_tasks Full-text search (query, limit?, active_only?)
plan_epic An epic's child tasks in topological execution order (id)
get_graph Bounded dependency adjacency list (include_done?, epic?, limit?)
archive_task Archive a task (and settled children), or sweep all archivable tasks (id?)
restore_task Restore an archived task and its cascade (id)
list_archived List archived tasks, most recent first (limit?)

Register with Claude Code

Add to your Claude Code MCP config (claude mcp add):

{
  "mcpServers": {
    "bears": {
      "command": "bea",
      "args": ["mcp"]
    }
  }
}

Library usage

The core is published as a library crate so an independent application can drive a bears repository directly, with no bea binary required on the user's machine.

The package is bea-rs; the library is bears:

[dependencies]
bears = { package = "bea-rs", version = "0.8", default-features = false }

default-features = false drops the CLI, TUI, and MCP frontends โ€” the library then pulls in ~33 crates instead of ~180.

use bears::{Priority, Status, service, store, task::TaskType};

let base = std::path::Path::new(".");
store::init(base)?;

// Every call re-reads the directory โ€” there is no cache and no daemon.
let tasks = store::load_all(base).await?;
let task = service::create_task(
    base,
    &tasks,
    "Design the API".to_string(),
    Priority::P0,
    vec!["backend".to_string()],   // tags
    vec![],                        // depends_on
    None,                          // parent epic
    String::new(),                 // markdown body
    TaskType::Task,
)?;

let tasks = store::load_all(base).await?;
for t in service::list_ready(&tasks, None, None, None) {
    println!("{} {} {}", t.id, t.priority, t.title);
}

service::set_status(base, &tasks, &task.id, Status::Done)?;

Layout

Module What it does
store Parse and write the .bears/ directory, including the archive
task Task, the frontmatter format, ID and slug generation
graph Dependency graph, readiness, effective priority, cycle detection
service Business logic โ€” create, update, reparent, archive, epic progress and auto-close
scaffold Write coding-agent integration files (CLAUDE.md, skills, MCP config)
error Error and Result

Most callers want service. It takes &HashMap<String, Task> from store::load_all and a base path, and writes changes straight to disk.

Features

Feature Default Effect
cli yes Builds the bea binary: CLI, MCP server, and TUI
schema via cli Derives schemars::JsonSchema on Status, Priority, and TaskType โ€” useful when exposing bears types in your own tool schemas

Errors

Library errors carry no frontend suggestions. Error::NotInitialized renders as not initialized: no `.bears` directory found โ€” it is up to your frontend to add whatever remediation hint fits. The bea binary attaches its own hints in hint_for() in main.rs.


Development

cargo build
cargo test
cargo clippy
cargo fmt

All three of fmt, clippy, and test must pass cleanly before committing.


Project layout

src/
  lib.rs         Library root โ€” public API (store, task, graph, service, ...)
  main.rs        `bea` binary entry point โ€” dispatch to CLI, MCP server, or TUI
  cli/
    mod.rs       CLI module root and dispatch
    args.rs      clap command and argument definitions
    cmd.rs       Command handlers (list, show, create, edit, graph, etc.)
  mcp/
    mod.rs       MCP module root and server setup
    params.rs    Tool parameter structs (serde + JSON Schema)
    tools.rs     MCP tool implementations and tests
  tui/           Interactive ratatui terminal UI (widgets, watcher, input)
  service.rs     Business logic (create, update, reparent, epic auto-close, archive)
  store.rs       Read/write .bears/ directory, incl. the archive layer
  task.rs        Task struct, frontmatter parse/render, ID & slug
  graph.rs       Dependency graph, ready computation, cycle detection
  scaffold.rs    `bea init` harness scaffolding (Claude/Copilot/Codex)
  config.rs      .bears.yml configuration
  editor.rs      $EDITOR integration for `bea edit` (binary-only)
  error.rs       Error types
templates/       Embedded harness templates for init scaffolding
.bears/          Task files (created by `bea init`)
  archive/       Archived task files