npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@burningbrosdabi/bbpm-mcp

v0.8.3

Published

Burningbros BBPM MCP — Model Context Protocol server exposing the BB Project Management API to Claude. Create issues, assign tasks, comment, and query the board from a chat prompt.

Readme

Burningbros BBPM MCP

The Burningbros BBPM MCP server bridges ClaudeBurningbros BB Project Management. Lets internal staff create issues, attach screenshots, comment, link specs, search across projects, and query the board from a chat prompt — no need to open the web UI.

┌──────────────────┐    stdio / HTTP    ┌─────────────────────────┐   HTTPS    ┌─────────────────────┐
│  Claude Desktop  │ ─────────────────► │  Burningbros BBPM MCP   │ ─────────► │  pm.burningbros.kr  │
│  Claude Code     │                    │  (this repo)            │            │  /api/external/*    │
└──────────────────┘                    └─────────────────────────┘            └─────────────────────┘
                                              │
                                              ▼
                                  BBPM_API_KEY  (per-user, X-API-Key)
                                       — or —
                                  OAuth 2.1 PKCE  (claude.ai connector)

What you can ask Claude

"Tạo cho tôi 1 task trên project PITB, title 'Fix subtask hover radius', high priority, assign cho Phạm Tùng."

"What's on my plate today?" → Claude calls whoami + list_my_assignments.

"Tạo bug cho login crash" (kèm screenshot dán vào chat) → Claude calls get_create_rulescreate_issue with the screenshot as an inline attachment, formatted per the team's bug template.

"Project DW tuần qua thế nào?" → get_project_digest({ projectKey: 'DW', days: 7 }).

"Đính spec UserAuth vào PITB-42" → list_specs + link_issue_to_spec.

"Mark PITB-12 as today's focus" → set_focus_today.

Tools exposed (31 total, grouped by domain)

Issues — read

| Tool | What it does | |---|---| | get_issue | Fetch full detail of an issue (+ comments, activities) | | list_issues | List or summarize issues; rich filters (assignee/priority/type/text/dueIn/hasOverdue) + sparse fields + mode=summary | | list_my_assignments | Cross-project shortcut: issues currently assigned to the caller | | list_comments | Page through comments on an issue | | list_activities | Audit trail (status / assignee / priority / etc. changes) | | list_issue_spec_links | Specs (and sections) linked to an issue | | list_attachments_for_issue | All attachments on an issue + uploader profile | | search_issues | Cross-project case-insensitive title (optionally description) search |

Issues — write

| Tool | What it does | |---|---| | create_issue | Create task / bug / epic / sub-task. Accepts inline attachments[] (base64 images, uploaded post-creation). Returns { issue, warnings?, attachments? }. | | update_issue | Edit title, description, status, priority, assignee, reviewer, labels | | comment_on_issue | Post a comment with optional @mention (triggers Slack DM) | | attach_image_to_issue | Attach a screenshot to an existing issue (base64; returns URL + embed markdown) | | set_focus_today | Mark an issue as today's focus (or any date, or clear it) | | archive_issue / unarchive_issue | Manual archive/restore (soft-warns when archiving non-terminal) | | add_label_to_issue / remove_label_from_issue | Manage labels by name; idempotent; reports unknown names instead of failing | | link_issue_to_spec / unlink_issue_from_spec | Connect issue ↔ spec (optional sectionSlug for deep-link) | | delete_attachment | Remove an attachment (uploader-only) |

Specs

| Tool | What it does | |---|---| | list_specs | List specification documents, filter by category or status | | get_spec | Fetch a single spec (HTML body) | | get_spec_markdown | Spec body rendered as markdown — LLM-friendly | | create_spec | Create a new spec | | update_spec | Patch title / content / category / status / order |

Workspace meta

| Tool | What it does | |---|---| | whoami | Identity of the calling user (resolves "me") | | list_projects | All BB PM projects you can access | | list_members | Project members (to resolve names → user IDs) | | list_labels | Labels defined in a project | | get_project_digest | Project snapshot over N days: counts + per-assignee + overdue / upcoming / recent buckets + activity stream | | get_create_rules | Workspace-wide per-IssueType rules (title pattern, description template, required fields, defaults, enforced labels) — call before create_issue |

Token efficiency

The default list_issues response is intentionally sparse — only [id, number, title, status, priority, type, assignee.name]. Opt into heavier fields explicitly:

{ "projectKey": "PITB", "fields": ["description", "labels", "dates"] }

For project-state questions ("how is project X going?"), prefer the aggregate path — returns counts only, no row payloads, ~95% smaller:

{ "projectKey": "PITB", "mode": "summary" }

Server-side filters (assignee, priority, type, text, updatedSince, dueIn, hasOverdue) let the LLM narrow the result before it leaves the database — much cheaper than paging through everything.

Rules-driven create_issue

Each workspace ships with per-IssueType rules (configured at /admin/issue-rules):

  • title pattern (regex like /^\[BUG\]/ or a hint string)
  • description template (markdown skeleton)
  • required fields (soft — missing fields come back as warnings)
  • default values (auto-applied when missing)
  • enforced labels (auto-attached, created in the project on demand)

The LLM is expected to call get_create_rules({ type }) first so the resulting issue matches the team's expected format. The response surfaces both the rules and the markdown template the LLM uses as the starting point for description. Any unmet rule comes back from create_issue as soft warnings, never a hard reject — so the LLM can follow up with update_issue to patch.

Setup — Claude Desktop (NPX, recommended for individual users)

1. Generate an API key

  1. Open BB PM → ProfileAPI KeysGenerate
  2. Copy the raw key (shown once — looks like bbpm_<56 hex chars>)
  3. Store it in a password manager

2. Add to claude_desktop_config.json

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the platform equivalent:

{
  "mcpServers": {
    "bbpm": {
      "command": "npx",
      "args": ["-y", "@burningbrosdabi/bbpm-mcp"],
      "env": {
        "BBPM_API_KEY": "bbpm_paste_your_key_here",
        "BBPM_API_BASE": "https://pm.burningbros.kr/api",
        "BBPM_FRONTEND_URL": "https://pm.burningbros.kr"
      }
    }
  }
}

Restart Claude Desktop. The tools should appear in the tools panel.

Setup — Claude Code (CLI)

claude mcp add bbpm npx -y @burningbrosdabi/bbpm-mcp \
  --env BBPM_API_KEY=bbpm_paste_your_key_here \
  --env BBPM_API_BASE=https://pm.burningbros.kr/api \
  --env BBPM_FRONTEND_URL=https://pm.burningbros.kr

Setup — Remote HTTP (team-hosted)

The recommended workflow on a VPS uses the bundled Makefile:

curl -fsSL https://raw.githubusercontent.com/burningbrosdabi/bbpm-internal-mcp/main/Makefile -o Makefile
make redeploy                     # pull newest npm + recreate container
make redeploy VERSION=0.6.1       # pin a specific npm version
make status                       # docker ps + healthz + discovery probes
make logs                         # follow container logs

The container is intentionally just node:22-alpine with the package installed at boot via npm i -g. No image to maintain — bumping VERSION is enough.

Or manually:

docker run -d --name bbpm-mcp \
  -e BBPM_API_BASE=https://pm.burningbros.kr/api \
  -e BBPM_FRONTEND_URL=https://pm.burningbros.kr \
  -e MCP_PUBLIC_URL=https://mcp.burningbros.kr \
  -e PORT=3333 \
  -p 127.0.0.1:3334:3333 \
  node:22-alpine \
  sh -c 'npm i -g @burningbrosdabi/bbpm-mcp@latest && bbpm-mcp-http'

Each user still configures their own BBPM_API_KEY on the client side (Claude Code / Claude Desktop sends it in the per-session env), so the remote server never holds keys at rest. Point clients at https://mcp.burningbros.kr/mcp.

For claude.ai custom connectors, the remote HTTP transport also speaks OAuth 2.1 PKCE — see oauth-server-design.md in the BB PM repo and scripts/oauth-playground.mjs here.

Local development

pnpm install
cp .env.example .env
# edit .env with your local BBPM_API_KEY and BBPM_API_BASE
pnpm dev          # stdio transport — test with `npx @modelcontextprotocol/inspector`
pnpm dev:http     # HTTP transport — POST JSON-RPC to http://localhost:3333/mcp

To test interactively, point the MCP Inspector at pnpm dev:

npx @modelcontextprotocol/inspector pnpm dev

Architecture notes

  • One client class (BbpmClient) wraps the BB PM REST API. Every request injects either X-API-Key: bbpm_<hex> (personal key) or Authorization: Bearer bbpm_at_<…> (OAuth 2.1). Errors come back as BbpmApiError with status + path + message so tool output can quote them verbatim.
  • One server builder (buildServer) registers all tools. Transports (stdio / HTTP) wrap the same instance.
  • Tool definitions are colocated with their Zod input schemas in src/tools/. Each exports a ToolDefinition consumed by buildServer.
  • Idempotency: write tools (create_issue, update_issue, comment_on_issue, etc.) are not idempotent at the protocol layer — the LLM is responsible for not repeating them. BBPM's outbox handles its own delivery guarantees downstream of the API.

BB PM API surface consumed

All endpoints are guarded by ApiKeyGuard (accepts API key or OAuth bearer):

Issues

  • POST /external/issues — create (accepts inline attachments[])
  • PATCH /external/issues/:projectKey/:issueNumber — update
  • GET /external/issues/:projectKey/:issueNumber — get one
  • GET /external/issues/:projectKey — list (with filters, summary mode, sparse fields)
  • POST /external/issues/:projectKey/:issueNumber/comments — comment
  • GET /external/issues/:projectKey/:issueNumber/comments — list comments
  • GET /external/issues/:projectKey/:issueNumber/activities — audit log
  • POST /external/issues/:projectKey/:issueNumber/attachments — base64 image upload
  • GET /external/issues/:projectKey/:issueNumber/attachments — list attachments
  • DELETE /external/attachments/:id — delete attachment (uploader-only)
  • GET /external/search?q=... — cross-project ILIKE search
  • PATCH /external/issues/:projectKey/:issueNumber/focus — set/clear focusDate
  • POST /external/issues/:projectKey/:issueNumber/archive / /unarchive
  • POST /external/issues/:projectKey/:issueNumber/labels — add labels by name
  • DELETE /external/issues/:projectKey/:issueNumber/labels — remove labels by name
  • POST /external/issues/:projectKey/:issueNumber/spec-links — link to spec
  • GET /external/issues/:projectKey/:issueNumber/spec-links — list links
  • DELETE /external/issues/:projectKey/:issueNumber/spec-links/:linkId

Specs

  • GET /external/projects/:projectKey/specs — list (filter category/status)
  • GET /external/projects/:projectKey/specs/:specId — get one (HTML body)
  • GET /external/projects/:projectKey/specs/:specId/markdown — markdown body
  • POST /external/projects/:projectKey/specs — create
  • PATCH /external/projects/:projectKey/specs/:specId — update

Workspace meta

  • GET /external/me — calling user profile (whoami)
  • GET /external/me/assignments — cross-project assigned issues
  • GET /external/projects — projects the caller is a member of
  • GET /external/projects/:projectKey/members — project members
  • GET /external/projects/:projectKey/labels — project labels
  • GET /external/projects/:projectKey/digest?days=N — N-day digest
  • GET /external/issue-rules?type=BUG — global per-IssueType creation rules

Versioning

Tracked in CHANGELOG.md. Recent highlights:

  • v0.8.0search_issues (cross-project ILIKE), list_attachments_for_issue, delete_attachment. Closes the read/manage loop on attachments and adds workspace-wide search.
  • v0.7.0whoami, list_my_assignments, set_focus_today, archive_issue, unarchive_issue, add_label_to_issue, remove_label_from_issue. Productivity shortcuts for the daily workflow.
  • v0.6.0get_project_digest, full specs CRUD (5 tools), issue ↔ spec links (3 tools). Documentation surface unlocked for the LLM.
  • v0.5.0get_create_rules, attach_image_to_issue. Sparse list_issues defaults + summary mode + 9 filters. Rules-driven create_issue with soft warnings.
  • v0.4.x — OAuth 2.1 (DCR + PKCE + token revocation) for claude.ai custom connectors.