basic BMAD setup
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# Store starter: GitHub Issues. `scripts/read_store.py` reads this file as the base layer; the project's
|
||||
# _bmad/custom/ticketing-store-config.toml names the store, fills the empty fields below, and replaces
|
||||
# any other key here, key by key.
|
||||
# It updates with the skill and holds only what is specific to this store: the rules every store shares
|
||||
# are in references/board.md. Comments and `description` are never loaded; `description` is for choosing a store.
|
||||
#
|
||||
# One tool: the gh CLI, 2.94 or later (sub-issues and dependencies). Labels carry type and status,
|
||||
# sub-issues carry hierarchy, blocked-by relations carry blocking, milestones put initiatives on the roadmap.
|
||||
# Using the defaults below: the repo needs the type, status, and hitl labels; `setup` creates them.
|
||||
|
||||
description = "GitHub Issues through the gh CLI: labels, sub-issues, blocked-by, milestones. For teams whose code and planning already live on GitHub."
|
||||
|
||||
[tickets]
|
||||
store = "github"
|
||||
key = "" # ids are the repo's issue numbers; leave empty
|
||||
repo = "" # OWNER/REPO; empty = the repo of the current checkout (origin)
|
||||
access = """
|
||||
Use the gh CLI against `repo`, passing `-R <repo>` on every call when it is set. Needs gh 2.94+; check `--help` when a flag is doubted.
|
||||
"""
|
||||
|
||||
fields = """
|
||||
risk is a label risk:<value>; severity is a label P0-P3. `setup` creates them with the other
|
||||
labels; publish and update set them like any label. estimate is a label est:<value> (`setup` creates none; add on first use). Empty field: no label.
|
||||
"""
|
||||
|
||||
reference = """
|
||||
GitHub renders urls as links; nothing more to do.
|
||||
"""
|
||||
|
||||
[verbs]
|
||||
setup = """
|
||||
Connect, unless `gh auth status` already shows a login: `gh auth login`.
|
||||
Labels must exist before they are used. List the repo's labels (`gh label list --limit 1000 --json name`)
|
||||
and run `gh label create <name>` for each of these it lacks, comparing names ignoring case: the
|
||||
[tickets.types] values except initiative (a milestone), the [tickets.status] values except done and
|
||||
dropped (closed states), `hitl`, risk:low, risk:medium, risk:high, and P0-P3. A create that fails with
|
||||
"already exists" found the label after all: leave it. Never `--force`: it recolours a label the repo
|
||||
already has.
|
||||
"""
|
||||
|
||||
write = """
|
||||
One issue per new ticket. tracker_id is the issue number and remote its url.
|
||||
Create with content only: `gh issue create --title <t> --body-file <b> --label <type>,<[tickets.status].<state>>[,hitl,risk:<r>,P<n>]
|
||||
[--milestone <initiative>]`, and mirror tracker_id and remote from the url it prints before anything else. Then add the
|
||||
relations with `gh issue edit <n> --parent <n> --add-blocked-by <n,n>`, leaving out any that `gh issue view <n> --json
|
||||
parent,blockedBy` already shows, since adding one twice fails. Keep --parent and --blocked-by off the create: gh adds them
|
||||
after the issue exists, and when that step fails it exits non-zero without printing the url, so a rerun files the ticket
|
||||
twice. A create that fails with no url may still have made the issue: before creating again, list the newest issues
|
||||
(`gh issue list --state all --limit 100 --json number,title,body,createdAt`) twice, a few seconds apart since the list can
|
||||
trail a create, and take the one whose title and body are what was sent. None matches and the list does not reach back to
|
||||
the failed create: ask before creating again. Changes go through `gh issue edit <n>` (--body-file, --add-assignee,
|
||||
--add-blocked-by, label swaps; --add-sub-issue on the parent). No parent: omit --parent; no initiative: omit --milestone.
|
||||
Status is a label swap on an open issue. done: remove the status label and `gh issue close <n>`;
|
||||
dropped: the same with `--reason "not planned"`. An initiative is a
|
||||
milestone (`gh api repos/{owner}/{repo}/milestones -f title=<name>`) holding its tree's issues.
|
||||
"""
|
||||
|
||||
query = """
|
||||
One issue: `gh issue view <n> --json
|
||||
number,title,labels,assignees,state,stateReason,milestone,parent,blockedBy,subIssuesSummary,body`.
|
||||
Type, hitl, risk, severity, and status are labels — except done and dropped, the closed states per
|
||||
[tickets.status]; after is blockedBy; the body's covers holds the source requirement ids. Children: `gh issue view <n>
|
||||
--json subIssues`. Words: `gh issue list --search "<words>" --state all`, narrowed by
|
||||
--label. An initiative's issues are the ones in its milestone; a standalone ticket has no milestone.
|
||||
"""
|
||||
|
||||
# BMad type -> this store's type.
|
||||
[tickets.types]
|
||||
initiative = "milestone" # an initiative is a milestone, not an issue; its epics carry it
|
||||
epic = "epic"
|
||||
story = "story"
|
||||
spike = "spike"
|
||||
bug = "bug"
|
||||
|
||||
# BMad state -> this store's status.
|
||||
[tickets.status]
|
||||
backlog = "backlog"
|
||||
in-progress = "in-progress"
|
||||
review = "review"
|
||||
done = "closed" # state, not a label
|
||||
dropped = "closed: not planned" # state, not a label
|
||||
@@ -0,0 +1,83 @@
|
||||
# Store starter: Jira Cloud. `scripts/read_store.py` reads this file as the base layer; the project's
|
||||
# _bmad/custom/ticketing-store-config.toml names the store, fills the empty fields below, and replaces
|
||||
# any other key here, key by key.
|
||||
# It updates with the skill and holds only what is specific to this store: the rules every store shares
|
||||
# are in references/board.md. Comments and `description` are never loaded; `description` is for choosing a store.
|
||||
#
|
||||
# One tool: acli, Atlassian's official CLI (`acli jira workitem ...`): create with --parent, transition,
|
||||
# links, comments, assign, JQL. The Atlassian Rovo MCP server (https://mcp.atlassian.com/v1/mcp/authv2)
|
||||
# is the alternative for an org that prefers MCP; it has no link-creation tool.
|
||||
|
||||
description = "Jira Cloud through acli: work types, transitions, links, JQL. For teams already on Jira, usually with an admin who can adjust the project workflow."
|
||||
|
||||
[tickets]
|
||||
store = "jira"
|
||||
key = "" # the default Jira project key, e.g. "SHOP"; Jira assigns the number. A container's own `key` overrides it for everything under it
|
||||
site = "" # https://yourorg.atlassian.net
|
||||
access = """
|
||||
Use acli against `site`. Custom fields go through `--from-json`; check a subcommand's spelling
|
||||
with `acli jira workitem --help` before first use.
|
||||
"""
|
||||
|
||||
fields = """
|
||||
severity is Jira's priority: P0 = Highest, P1 = High, P2 = Medium, P3 = Low; set it at create
|
||||
(--priority, or --from-json when the flag is absent) and change it the same way. risk is a label
|
||||
risk-low, risk-medium, or risk-high. estimate is the Story Points field on a story and a label est:<value> on an epic, through --from-json. Empty field: default priority, no label.
|
||||
"""
|
||||
|
||||
reference = """
|
||||
acli creates no web links; the description line is the reference.
|
||||
"""
|
||||
|
||||
[verbs]
|
||||
setup = """
|
||||
Connect, unless acli is already installed and signed in to `site`: install acli (on macOS,
|
||||
`brew tap atlassian/homebrew-acli && brew install acli`; elsewhere, per Atlassian's acli install
|
||||
guide), then `acli jira auth login --web --site <site>`.
|
||||
acli cannot create work types or statuses; those live in the project's settings. At first publish,
|
||||
read an existing work item (`acli jira workitem view <key> --json --fields issuetype,status`) and
|
||||
the project's work types, compare with [tickets.types] and [tickets.status], and tell the user
|
||||
exactly what to add in Jira or which map entry to set in the project's store config. Jira's defaults (To Do, In
|
||||
Progress, Done; resolution Won't Do) need no setup; [tickets.status] also expects an In Review status.
|
||||
Do not ask for a level above Epic: by default the initiative stays local and everything below it
|
||||
publishes. A team-managed project's admin adds a status as a board column under
|
||||
Project settings, Board; a company-managed project needs a Jira admin to add it to the workflow.
|
||||
"""
|
||||
|
||||
write = """
|
||||
The project is the ticket's own `key`, else that of the nearest container above it, else `key` here.
|
||||
tracker_id is the work item's key and remote its url.
|
||||
Create:
|
||||
`acli jira workitem create --project <key> --type <per [tickets.types]> --summary <t>
|
||||
--description-file <b> --parent <key> --label <type>[,hitl,risk-<risk>]`, priority per `fields` on
|
||||
a bug. Changes: `edit` (body, labels), `assign`, `transition --status <[tickets.status].<state>>` —
|
||||
status never moves by edit — `link create --out <blocker> --in <blocked> --type "Blocks"`,
|
||||
`comment create`. No parent: omit --parent — the item sits loose in the project. Custom fields go through --from-json; when dropped shares a status with done,
|
||||
set the resolution the same way so the two stay distinct.
|
||||
Epics sit loose in the project while [tickets.types].initiative is empty. Set that type only when the
|
||||
project has a level above Epic; then epics take it as --parent.
|
||||
"""
|
||||
|
||||
query = """
|
||||
One work item: `acli jira workitem view <key> --json --fields
|
||||
key,issuetype,summary,status,assignee,parent,labels,issuelinks,resolution,description`. after is the
|
||||
"is blocked by" links; Done with resolution Won't Do is dropped; the description's covers holds the source requirement ids. Children:
|
||||
`search --jql "parent = <key>"`. Words: `search --jql 'project = <key> AND text ~ "<words>"'`,
|
||||
narrowed by issuetype or status per the maps.
|
||||
"""
|
||||
|
||||
# BMad type -> this store's type.
|
||||
[tickets.types]
|
||||
initiative = "" # empty: the initiative stays local. Jira's default hierarchy is Epic > Story > Subtask; a level above Epic needs Plans (Premium or Enterprise). Set to "Initiative" only when the project has that level.
|
||||
epic = "Epic"
|
||||
story = "Story"
|
||||
spike = "Task" # plus label spike
|
||||
bug = "Bug"
|
||||
|
||||
# BMad state -> this store's status.
|
||||
[tickets.status]
|
||||
backlog = "To Do"
|
||||
in-progress = "In Progress"
|
||||
review = "In Review" # not a default Jira status; `setup` asks for it. With no review status, set it to the in-progress one
|
||||
done = "Done"
|
||||
dropped = "Done" # Jira default has no separate status; resolution Won't Do distinguishes it
|
||||
@@ -0,0 +1,75 @@
|
||||
# Store starter: Linear. `scripts/read_store.py` reads this file as the base layer; the project's
|
||||
# _bmad/custom/ticketing-store-config.toml names the store, fills the empty fields below, and replaces
|
||||
# any other key here, key by key.
|
||||
# It updates with the skill and holds only what is specific to this store: the rules every store shares
|
||||
# are in references/board.md. Comments and `description` are never loaded; `description` is for choosing a store.
|
||||
#
|
||||
# One tool: Linear's official MCP server. Initiatives hold projects, parent issues are epics, labels carry
|
||||
# type, relations carry blocking. Linear ships no CLI; community CLIs are not used here.
|
||||
|
||||
description = "Linear through its MCP server: projects, parent issues, relations, labels. For product teams on Linear."
|
||||
|
||||
[tickets]
|
||||
store = "linear"
|
||||
key = "" # Linear team key, e.g. "SHOP"; Linear assigns the number
|
||||
team = "" # the default team, key or name. A container's own `key` overrides it for everything under it
|
||||
access = """
|
||||
Use the Linear MCP (create_issue, update_issue, create_project, update_project, get_issue,
|
||||
list_issues, list_issue_statuses, create_issue_label, create_comment) against `team`. Confirm from the tool schema whether parent
|
||||
and blockedBy take identifiers (SHOP-12) or ids, and the exact tool names against the server's list at first use.
|
||||
"""
|
||||
|
||||
fields = """
|
||||
severity is Linear's priority, set on the issue: P0 = Urgent, P1 = High, P2 = Medium, P3 = Low.
|
||||
risk is a label risk:<value>; `setup` creates the three. estimate is Linear's estimate field on a story; a label est:<value> on an epic. Empty field: no priority, no label.
|
||||
"""
|
||||
|
||||
reference = """
|
||||
Also pass the url in the issue's links so it shows in the sidebar.
|
||||
"""
|
||||
|
||||
[verbs]
|
||||
setup = """
|
||||
Connect, unless the Linear tools already answer: add the MCP server https://mcp.linear.app/mcp to
|
||||
the agent tool in use (in Claude Code, `claude mcp add --transport http linear-server https://mcp.linear.app/mcp`),
|
||||
then sign in over OAuth. Do not use the deprecated /sse endpoint.
|
||||
`create_issue_label` for every non-empty value in [tickets.types], `hitl`, and risk:low, risk:medium,
|
||||
risk:high that the team lacks. States
|
||||
cannot be created from the MCP: `list_issue_statuses`, compare with [tickets.status], and tell the
|
||||
user what to add under Settings, Teams, Issue statuses, or which map entry to set in the project's
|
||||
store config. Linear's defaults (Backlog, Todo, In Progress, Done, Canceled) need no setup; [tickets.status]
|
||||
also expects an In Review state in the Started group.
|
||||
"""
|
||||
|
||||
write = """
|
||||
The team is the ticket's own `key`, else that of the nearest container above it, else `team` here.
|
||||
tracker_id is the issue's identifier and remote its url.
|
||||
`create_issue` creates, `update_issue` changes — title, description, state, assignee, parent,
|
||||
blockedBy, labels, priority, project. The issue's state is [tickets.status].<state>. Labels carry type, hitl, and
|
||||
risk:<value>; priority carries severity per `fields`. A standalone ticket: omit parent and project.
|
||||
Epics are parent issues. Set [tickets.types].initiative to map onto a Linear Initiative only when the
|
||||
server exposes initiative tools.
|
||||
"""
|
||||
|
||||
query = """
|
||||
One issue: `get_issue` with includeRelations — labels, priority, state, assignee, parent,
|
||||
project, relations, description; after is the "blocked by" relations, and the description's
|
||||
covers holds the source requirement ids. Many: `list_issues` by project, parent, label, state, or
|
||||
query words.
|
||||
"""
|
||||
|
||||
# BMad type -> this store's type.
|
||||
[tickets.types]
|
||||
initiative = "" # empty: the initiative stays local. Linear has no Epic object and Projects cannot nest; set to "initiative" only to map onto Linear Initiatives, which nest five deep and allow several parents, so the tree cannot round-trip.
|
||||
epic = "epic" # label on a parent issue
|
||||
story = "story"
|
||||
spike = "spike"
|
||||
bug = "bug"
|
||||
|
||||
# BMad state -> this store's status.
|
||||
[tickets.status]
|
||||
backlog = "Backlog" # or "Todo" — the team's choice
|
||||
in-progress = "In Progress"
|
||||
review = "In Review" # not a default Linear state; `setup` asks for it. With no review state, set it to the in-progress one
|
||||
done = "Done"
|
||||
dropped = "Canceled"
|
||||
@@ -0,0 +1,78 @@
|
||||
# Store starter: Notion. `scripts/read_store.py` reads this file as the base layer; the project's
|
||||
# _bmad/custom/ticketing-store-config.toml names the store, fills the empty fields below, and replaces
|
||||
# any other key here, key by key.
|
||||
# It updates with the skill and holds only what is specific to this store: the rules every store shares
|
||||
# are in references/board.md. Comments and `description` are never loaded; `description` is for choosing a store.
|
||||
#
|
||||
# One tool: Notion's official MCP server. One database holds every ticket; properties carry type,
|
||||
# status, assignee, and hitl; two self-relations carry hierarchy (Parent) and blocking (Blocked by);
|
||||
# a board view grouped by Status is the kanban. `setup` creates all of it.
|
||||
|
||||
description = "Notion through its MCP server: one tickets database with a board view, relations for hierarchy and blocking. For teams that plan in Notion and want tickets beside their docs."
|
||||
|
||||
[tickets]
|
||||
store = "notion"
|
||||
key = "" # prefix of the database's ID property, e.g. "SHOP" gives SHOP-12; empty = page ids only
|
||||
database = "" # url or id of the tickets database; empty = `setup` creates it
|
||||
access = """
|
||||
Use the Notion MCP (notion-fetch, notion-create-pages, notion-update-page,
|
||||
notion-query-data-sources, notion-create-comment, notion-get-users) against `database`. Confirm
|
||||
from the tool schema how relation and person properties are passed; `notion-get-users` resolves a name.
|
||||
An empty `database` means `setup` has not run.
|
||||
"""
|
||||
|
||||
fields = """
|
||||
risk and severity are select properties: Risk (low, medium, high) and Severity (P0-P3); `setup`
|
||||
creates them, publish and update set them. estimate is a text property Estimate, created with the rest. Empty field: property left empty.
|
||||
"""
|
||||
|
||||
reference = """
|
||||
Notion renders urls as links; a Notion page url becomes a mention.
|
||||
"""
|
||||
|
||||
[verbs]
|
||||
setup = """
|
||||
Connect, unless the Notion tools already answer: add the MCP server https://mcp.notion.com/mcp to
|
||||
the agent tool in use (in Claude Code, `claude mcp add --transport http notion https://mcp.notion.com/mcp`),
|
||||
then sign in over OAuth. Either way, share the database, or the page it will be created under, with
|
||||
the connection.
|
||||
When `database` is empty: ask which page to create under, then `notion-create-database` named
|
||||
Tickets with properties Title (title), Type (select, options per [tickets.types]), Status (status,
|
||||
options per [tickets.status]), Parent (relation to this database), Blocked by (relation to this
|
||||
database), Assignee (person), Covers (text), Risk (select: low, medium, high), Severity (select:
|
||||
P0, P1, P2, P3), Estimate (text), hitl (checkbox), and, when `key` is set, ID (unique id
|
||||
with that prefix). Then `notion-create-view`: a board grouped by Status. Give the user the url and
|
||||
put it in `database` in the project's store config.
|
||||
When `database` is set: `notion-fetch` it and compare its properties and options with the maps;
|
||||
add a missing option with `notion-update-data-source`, and tell the user about anything the
|
||||
schema needs a person to change.
|
||||
"""
|
||||
|
||||
write = """
|
||||
tracker_id is the ID property when `key` is set, else the page id; remote is the page url.
|
||||
`notion-create-pages` into `database` creates; `notion-update-page` changes any property or the
|
||||
content — Status, Assignee, Parent, Blocked by, Covers, Risk, Severity, hitl. Status is [tickets.status].<state>. No parent: leave the Parent relation empty. An initiative
|
||||
is a page of Type initiative with no Parent. The body is the page content.
|
||||
"""
|
||||
|
||||
query = """
|
||||
One page: `notion-fetch` — Title, Type, Status, Assignee, Parent, Blocked by, Covers, Risk,
|
||||
Severity, hitl, and the content; after is Blocked by. Many: `notion-query-data-sources` on `database` filtered by any
|
||||
property; `notion-search` scoped to `database` for a looser match.
|
||||
"""
|
||||
|
||||
# BMad type -> this store's type (Type select options; `setup` creates them).
|
||||
[tickets.types]
|
||||
initiative = "initiative"
|
||||
epic = "epic"
|
||||
story = "story"
|
||||
spike = "spike"
|
||||
bug = "bug"
|
||||
|
||||
# BMad state -> this store's status (Status property options; `setup` creates them).
|
||||
[tickets.status]
|
||||
backlog = "Backlog"
|
||||
in-progress = "In Progress"
|
||||
review = "Review"
|
||||
done = "Done"
|
||||
dropped = "Dropped"
|
||||
@@ -0,0 +1,57 @@
|
||||
# Store starter: tickets as files in the repo, the default. `scripts/read_store.py` reads this file as the
|
||||
# base layer; the project's _bmad/custom/ticketing-store-config.toml names the store and replaces any key
|
||||
# here, key by key. With no project file this starter is the whole config.
|
||||
# It updates with the skill and holds only what is specific to this store: the rules every store shares
|
||||
# are in references/board.md. Comments and `description` are never loaded; `description` is for choosing a store.
|
||||
#
|
||||
# Tickets and artifacts live together as markdown files under `output_folder` (layout in SKILL.md,
|
||||
# The ticket tree), committed in the monorepo or in a repo of their own. Status and assignee change by commit, and the skill never pushes,
|
||||
# so others see them only after a push and pull.
|
||||
|
||||
description = "Quick setup, and the default when nothing else is chosen. Tickets are markdown files under version control: in the monorepo, or in their own repo (recommended for mono and poly repos alike). No tracker or account needed. The simplest store — right for a solo developer or a very small team with no other tracking."
|
||||
|
||||
[tickets]
|
||||
store = "repo"
|
||||
|
||||
access = """
|
||||
Read and write the files under `output_folder`.
|
||||
"""
|
||||
|
||||
fields = """
|
||||
risk and severity live in the frontmatter (risk: low|medium|high on any ticket; severity: P0-P3
|
||||
on bugs); estimate the same way. Nothing else carries them.
|
||||
"""
|
||||
|
||||
[verbs]
|
||||
setup = """
|
||||
Tickets live in `output_folder` beside the documents. To keep them outside the project, set `output_folder`
|
||||
under `[core]` in `_bmad/custom/config.toml` to a folder beside it — the session then launches one level
|
||||
up — or in the workspace that already holds the repos. `git init` a new folder so tickets have
|
||||
history; skip that when the user picks a folder already under git, the monorepo included. Then
|
||||
create `backlog/` and the active initiative's folder there when they do not exist.
|
||||
"""
|
||||
|
||||
write = """
|
||||
Every change is an edit to the ticket's file, its `tickets.toml` entry, or, for a leaf's status and assignee, its plan through `tickets.py mark`.
|
||||
Commit only the files you wrote on the current branch. Root not in a git repo: skip the commit and say so.
|
||||
"""
|
||||
|
||||
query = """
|
||||
The files are the store: `tickets.py find`, `next`, and `status` answer from them. By a frontmatter field: `grep -rl "^type: bug" <folder>`.
|
||||
"""
|
||||
|
||||
# BMad type -> this store's type.
|
||||
[tickets.types]
|
||||
initiative = "initiative"
|
||||
epic = "epic"
|
||||
story = "story"
|
||||
spike = "spike"
|
||||
bug = "bug"
|
||||
|
||||
# BMad state -> this store's status.
|
||||
[tickets.status]
|
||||
backlog = "backlog"
|
||||
in-progress = "in-progress"
|
||||
review = "review"
|
||||
done = "done"
|
||||
dropped = "dropped"
|
||||
@@ -0,0 +1,76 @@
|
||||
# Store starter: Trello. `scripts/read_store.py` reads this file as the base layer; the project's
|
||||
# _bmad/custom/ticketing-store-config.toml names the store, fills the empty fields below, and replaces
|
||||
# any other key here, key by key.
|
||||
# It updates with the skill and holds only what is specific to this store: the rules every store shares
|
||||
# are in references/board.md. Comments and `description` are never loaded; `description` is for choosing a store.
|
||||
#
|
||||
# One tool: the official Trello MCP server. Trello is flat: lists carry status, labels carry type, card
|
||||
# urls in descriptions carry hierarchy and blocking. Using the defaults below: the board needs the lists
|
||||
# Backlog, In Progress, Review, Done, Initiatives, Epics and a label per type plus hitl; `setup` says how. Members, comments, attachments, and label creation
|
||||
# are not in the MCP yet. Weakest fit of the shipped configs; expect to tune it.
|
||||
|
||||
description = "Trello through its MCP server: lists as status, labels as type, card links as hierarchy. For small teams that run a Trello board and want to keep it."
|
||||
|
||||
[tickets]
|
||||
store = "trello"
|
||||
key = "" # ids are card short links (from the card url); leave empty
|
||||
board = "" # the board url
|
||||
access = """
|
||||
Use the Trello MCP (trelloReadBoard, trelloReadCard, trelloWriteCard, trelloWriteChecklist,
|
||||
trelloSearch) against `board`. Write tools take the server's ids, not urls: resolve a url with
|
||||
`trelloReadCard get` first.
|
||||
"""
|
||||
|
||||
fields = """
|
||||
risk is a label risk:<value>; severity a label P0-P3. The MCP cannot create labels: `setup` asks
|
||||
the user to add them with the type labels. estimate is an `estimate:` line in the description. Empty field: no label.
|
||||
"""
|
||||
|
||||
reference = """
|
||||
Attachments are not in the MCP yet; the description line is the reference.
|
||||
"""
|
||||
|
||||
[verbs]
|
||||
setup = """
|
||||
Connect, unless the Trello tools already answer: add the MCP server https://mcp.trello.com/v1 to
|
||||
the agent tool in use (in Claude Code, `claude mcp add --transport http trello https://mcp.trello.com/v1`),
|
||||
then sign in over OAuth with write permission.
|
||||
The MCP can create a board but not lists or labels. When `board` is empty, offer to create one;
|
||||
then ask the user to add the lists in [tickets.status] (Backlog, In Progress, Review, Done) plus
|
||||
Initiatives and Epics, and labels for every value in [tickets.types] plus hitl, risk:low, risk:medium, risk:high, and
|
||||
P0-P3. Check with
|
||||
`trelloReadBoard` before first publish and name what is still missing.
|
||||
"""
|
||||
|
||||
write = """
|
||||
tracker_id is the card's short link and remote its url.
|
||||
`trelloWriteCard create` makes a card, `update` changes description or labels, `move` changes
|
||||
list, `archive` is dropped. Status is the list [tickets.status].<state>; initiative cards live in the Initiatives list,
|
||||
epics in Epics, both carrying a `status:` line at the top of the description. Labels carry type,
|
||||
hitl, risk, severity. Trello has no fields for the rest — conventions in the description:
|
||||
`parent: <card url>` as its first line, an `assignee:` line (no member tools yet), after as
|
||||
card urls; the parent card keeps a checklist with each child's url. A standalone ticket: no parent line.
|
||||
The body is the description, and the `assignee:` line stays in it.
|
||||
"""
|
||||
|
||||
query = """
|
||||
One card: `trelloReadCard get` by url — name, list, labels, description (assignee, parent,
|
||||
covers, after live there), checklists; a container's children are its checklist items. Many:
|
||||
`trelloSearch` scoped to `board`, or `trelloReadBoard` filtered by the maps.
|
||||
"""
|
||||
|
||||
# BMad type -> this store's type.
|
||||
[tickets.types]
|
||||
initiative = "initiative"
|
||||
epic = "epic"
|
||||
story = "story"
|
||||
spike = "spike"
|
||||
bug = "bug"
|
||||
|
||||
# BMad state -> this store's status.
|
||||
[tickets.status]
|
||||
backlog = "Backlog"
|
||||
in-progress = "In Progress"
|
||||
review = "Review"
|
||||
done = "Done"
|
||||
dropped = "archived"
|
||||
Reference in New Issue
Block a user