Metadata-Version: 2.1
Name: bees-md
Version: 0.1.1
Summary: A markdown-based ticket management system designed for LLMs
Author: Gabe Mahoney
Requires-Python: >=3.10,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: fastmcp (>=3.0.2,<4.0.0)
Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
Description-Content-Type: text/markdown

## Overview

Bees is an MCP server that implements a markdown-based ticket management system. The package name is `bees-md` and after install the `bees` command is available in your shell.

## Installation

```bash
# CLI only
pipx install bees-md

# CLI + MCP server (required for bees serve)
pipx install 'bees-md[serve]'
```

## Quick Start

### Claude Code

```bash
# HTTP
claude mcp add --transport http --scope user bees http://127.0.0.1:8000/mcp
bees serve --http > /tmp/bees_server.log 2>&1 &
```

Verify setup:

```bash
claude mcp list
```

Remove:

```bash
claude mcp remove bees
```

### OpenCode

Add to `~/.opencode/opencode.json`:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "bees": {
      "type": "remote",
      "url": "http://127.0.0.1:8000/mcp",
      "enabled": true,
      "oauth": false
    }
  }
}
```

Verify setup:

```bash
opencode mcp list
```

## MCP Client Configuration (stdio)

Stdio transport runs bees as a subprocess — no server to start or keep alive. Requires the `[serve]` extra:

```bash
pip install bees-md[serve]
```

### Claude Code

```bash
# stdio (no HTTP server required)
claude mcp add --transport stdio --scope user bees -- bees serve --stdio

# Project scope (writes to .mcp.json)
claude mcp add --transport stdio --scope project bees -- bees serve --stdio
```

Remove:

```bash
claude mcp remove bees
```

### OpenCode (`opencode.json`)

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "bees": {
      "type": "local",
      "command": "bees",
      "args": ["serve", "--stdio"]
    }
  }
}
```

## Usage

Use natural language with the LLM to:
- create, update and delete tickets
- add named queries the LLM can then later use
- run named queries to find tickets that match them

Tickets are stored as simple markdown files with yaml front-matter for metadata.
Suggested usage is for LLMs to create tickets (to keep metadata integrity).
Humans can modify the markdown. Humans can modify the yaml metadata as well.

## Hives

Bees supports grouping tickets into Hives which are simply folders where a group of related tickets are stored. Each ticket is stored in its own directory within the hive, with child tickets nested as subdirectories.

When you create new tickets you should tell the LLM which Hive to create them in. Modifying or deleting tickets does not require you to specify the Hive.

## Directory Structure

Tickets use a hierarchical directory layout where parent-child relationships are visible from the filesystem:

```
hive_root/
  b.Amx/
    b.Amx.md
    t1.X4F2/
      t1.X4F2.md
      t2.R8P2k/
        t2.R8P2k.md
```

- Each ticket is a directory containing its `.md` file
- Directory name matches ticket ID exactly
- Child tickets are subdirectories of their parent
- Bees (top-level tickets) are directories at hive root

## Index

Each Hive has an auto-generated `index.md` file which a human can use to navigate and view that Hive's tickets.

## Configuration

Bees uses a single global config file at `~/.bees/config.json`. The MCP server auto-creates this when you colonize your first hive.

Config uses **scoped patterns** to match repos to their settings. Scope keys are directory paths that support glob wildcards:
- Exact path: matches one specific repo
- `*` matches within a single path segment
- `**` matches recursively through subdirectories

First matching scope wins (declaration order).

```json
{
  "scopes": {
    "/Users/username/projects/myrepo": {
      "hives": {
        "features": {
          "path": "/Users/username/projects/myrepo/docs/tickets/features",
          "display_name": "Features",
          "created_at": "2026-02-03T04:15:00.000000",
          "child_tiers": {
            "t1": ["Epic", "Epics"],
            "t2": ["Task", "Tasks"]
          }
        },
        "bugs": {
          "path": "/Users/username/projects/myrepo/docs/tickets/bugs",
          "display_name": "Bugs",
          "created_at": "2026-02-03T04:15:00.000000",
          "child_tiers": {}
        },
        "backend": {
          "path": "/Users/username/projects/myrepo/docs/tickets/backend",
          "display_name": "Backend",
          "created_at": "2026-02-03T04:15:00.000000"
        }
      },
      "child_tiers": {
        "t1": ["Task", "Tasks"],
        "t2": ["Subtask", "Subtasks"]
      }
    },
    "/Users/username/projects/bees/**": {
      "hives": { ... },
      "child_tiers": { ... }
    }
  },
  "child_tiers": {
    "t1": ["Task", "Tasks"]
  },
  "schema_version": "2.0"
}
```

`colonize_hive` creates exact-path scope entries automatically. To share hives across multiple repos (e.g. worktrees), manually edit the scope key to use a wildcard pattern.

**Scope options:**

- **`hives`**: Registered hives with paths and metadata. Managed by the MCP server.
- **`child_tiers`**: Defines the ticket hierarchy per scope (see Ticket Relationships section below). Each project can define its own tier structure — one repo might use `Bee → Task → Subtask` while another uses `Bee → Epic → Task → Instruction`. Individual hives can override this with their own `child_tiers` (see below).

## Ticket Relationships

Tickets support hierarchical organization with configurable types defined in `child_tiers`.

### Ticket Type System

`child_tiers` defines the ticket hierarchy. Each tier is a dictionary entry with tier ID (`t1`, `t2`, `t3`, etc.) and an optional array of `[singular, plural]` friendly names.

```json
"child_tiers": {
  "t1": ["Task", "Tasks"],
  "t2": ["Subtask", "Subtasks"]
}
```

To add more tiers, continue the pattern with `t3`, `t4`, etc. To remove tiers, delete entries or use an empty dictionary `{}` for bees-only.

**Three-level resolution:** `child_tiers` can be set at hive, scope, or global level. For a given hive, the first defined level wins:

1. **Hive-level** `child_tiers` inside a hive entry — applies only to that hive
2. **Scope-level** `child_tiers` — default for all hives in the scope
3. **Global-level** `child_tiers` (top-level in config.json) — default for all scopes
4. **Bees-only** — if none of the above are set, only bees are allowed

If `child_tiers` is absent or null at a level, resolution falls through to the next level. If `child_tiers` is present — even as empty `{}` — it stops the chain (empty `{}` means bees-only for that hive).

In the config example above, the `features` hive uses `Epic → Task` (hive-level override), the `bugs` hive is bees-only (`child_tiers: {}` stops the chain), and the `backend` hive has no `child_tiers` key so it inherits `Task → Subtask` from the scope. If a scope also had no `child_tiers`, resolution would fall through to the global-level `child_tiers` (root-level in config.json, outside `scopes`).

When talking to the LLM you may use either tier IDs (`t1`, `t2`) or friendly names (`"Epic"`, `"Task"`).

### Dependencies

Tickets can depend on other tickets of the same type only (Bees depend on Bees, t1 on t1, t2 on t2, etc.). Dependencies work across any hive.

## Ticket ID Format

All tickets use type-prefixed format: `{type_prefix}.{shortID}`

**Format by tier:**
- Bee (t0): `b.XXX` (3-char) - Examples: `b.Amx`, `b.X4F`, `b.R8P`
- t1: `t1.XXXX` (4-char) - Examples: `t1.X4F2`, `t1.R8P9`
- t2: `t2.XXXXX` (5-char) - Examples: `t2.R8P2k`, `t2.AmxQz`
- Tier N: `t{N}.{N+3 chars}` - ShortID length = tier_number + 3

**Character set:** Modified Crockford Base32 (55 chars: `1-9, a-n, p-z, A-N, P-Z`)

IDs are globally unique across all hives in the repository.

## Recommended Config

Disallow your LLM agents from reading or writing to your Hive directories.
Otherwise LLMs may route around the MCP server and potentially write malformed tickets.

## CLI

The `bees` command provides direct terminal access to all ticket operations.

### Ticket Operations

```bash
bees create-ticket --type bee --title "Bug fix" --hive backend
bees show-ticket b.Amx t1.X4F
bees update-ticket b.Amx --status worker --labels '["urgent"]'
bees delete-ticket b.Amx [--clean-dependencies]
bees get-types [--hive backend]
```

### Query Operations

```bash
bees add-named-query open-bees --yaml "- ['type=bee', 'status=open']"
bees execute-named-query open-bees [--hives backend,frontend]
bees execute-freeform-query --yaml "- ['type=bee']" [--hives backend]
```

### Hive Management

```bash
bees colonize-hive --name Backend --path /abs/path [--child-tiers '{"t1":["Task","Tasks"]}']
bees list-hives
bees abandon-hive backend
bees rename-hive old_name new_name
bees sanitize-hive backend
```

### Utilities

```bash
bees generate-index [--status open] [--type bee] [--hive backend]
bees move-bee b.Amx b.X4F --destination backlog
bees undertaker --hive backend --yaml "- ['status=finished']"
```

### YAML Query Syntax

Queries are pipelines of filter stages. Each stage narrows the result set.

Filter bees by status:
```yaml
- ['type=bee', 'status=open']
```

Find tickets with a label:
```yaml
- ['label~bug']
```

Get children of a specific ticket:
```yaml
- ['id=b.Amx']
- ['children']
```

## MCP Commands

Human users do not need to interact with the MCP server. These commands are provided only for informational purposes.

- **list_hives** - No parameters
  - Lists all registered hives in the repository
- **colonize_hive** - `name, path`
  - Creates a new hive with validation and registration
- **abandon_hive** - `hive_name`
  - Stops tracking a hive without deleting ticket files
- **rename_hive** - `old_name, new_name`
  - Renames a hive by updating config and identity markers
- **move_bee** - `bee_ids, destination_hive`
  - Moves one or more bee tickets to a different hive
- **create_ticket** - `ticket_type, title, description, parent, children, up_dependencies, down_dependencies, labels, status, hive_name`
- **show_ticket** - `ticket_id`
- **get_types** - `hive_name` (optional)
- **update_ticket** - `ticket_id, title, description, parent, children, up_dependencies, down_dependencies, labels, status`
- **delete_ticket** - `ticket_ids`, `clean_dependencies`
- **add_named_query** - `name, query_yaml`
- **execute_named_query** - `query_name, hive_names`
- **execute_freeform_query** - `query_yaml, hive_names`
- **generate_index** - `status, type, hive_name`
- **health_check** - No parameters
- **resolve_eggs** - `ticket_id`

