board-plannerBLOCK
One board. Your team works it. So do your agents. Kanban, sprints, REST API and MCP server — self-hosted, AGPL, with a PM agent and execution workers that run your tasks under your gates.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
One board. Your team works it. So do your agents.
A Kanban board, sprints and a dashboard small teams can actually run — plus an MCP server and a REST API, so coding agents pick up the same tasks under the same rules as everybody else.
Most trackers bolt automation on: a bot posts a comment, a script moves a card, and the real state of the work lives somewhere the board cannot see. Board Planner starts from the other end. The board, the REST API and the MCP server are three doors into one model, with the same permission checks behind each. An agent moving a task to In Review passes the same status rules as a person dragging the card, and leaves the same trail in the same hi
3f8f8b4dcdb3OBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add board-planner-worker --env AI_MONTHLY_TOKENS=${AI_MONTHLY_TOKENS} --env AI_TRIAL_TOKENS=${AI_TRIAL_TOKENS} --env API_KEY=${API_KEY} --env BOOTSTRAP_TOKEN=${BOOTSTRAP_TOKEN} -- npx -y [email protected]{
"mcpServers": {
"board-planner-worker": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"AI_MONTHLY_TOKENS": "${AI_MONTHLY_TOKENS}",
"AI_TRIAL_TOKENS": "${AI_TRIAL_TOKENS}",
"API_KEY": "${API_KEY}",
"BOOTSTRAP_TOKEN": "${BOOTSTRAP_TOKEN}"
}
}
}
}Exposed tools (36)
27 read · 9 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
Bare | read | |
Board | read | |
Bug | read | |
Builds | read | Installs dependencies and builds the project. |
Implement | read | |
Merge | write | Merges the pull request. Leave it out and a human decides. |
Name | read | Description |
Orbit | read | |
Proposes | write | Opens a pull request for a person to merge. |
Push | write | Pushes the branch to origin. |
Review | read | |
Reviewed | read | A second model reads the change with no memory of writing it. |
Runnable | read | |
Size | read | Refuses a change larger than the limit. |
Talkative | read | Reads the task, writes a plan, implements it in small steps, runs the tests after each, opens a pull request and leaves a summary of every decision for the reviewer. |
add_comment | write | |
assign_task | read | |
change_status | read | |
create_narrow_gamma | write | Write a gamma record |
create_task | write | Create a new task. Tasks are ALWAYS created in the project |
get_board_digest | read | Scan the open board for tasks missing acceptance criteria or a description, tasks sitting in the same column for a long time, and likely duplicates by title. Heuristic — confirm with get_task before acting. |
get_project_stats | read | Task counts by status for the project. |
get_task | read | Get full details of one task by key (e.g. CP-12). |
list_comments | read | List comments on a task (newest last). |
list_narrow_alpha | read | Read the alpha record |
list_narrow_beta | read | Read the beta record |
list_oauth_record | read | Read the record only a signed-in client may see |
list_orphans | read | |
list_tasks | read | List tasks in the project (compact: key, title, status, assignee, priority; an epic also says how many of its children are done). Use get_task for full details. |
list_thing | read | first |
notion-fetch | read | Read one page |
notion-search | read | Vendor-prefixed, so not read-shaped to isReadSafe |
notion-update-page | write | Append blocks to a page |
search_pages | read | Search pages in the workspace |
update_page | write | Append blocks to a page |
update_task | write | Update a task |
Trust audit
BLOCKgrade F · trust 48/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (3 observation(s))
- Network
- none-observed
- Shell
- declared (7 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
'(deny process-exec (literal "/bin/launchctl"))',
'(deny process-exec (regex #"/watchman$"))',
uri="mongodb://root:rootpw@bp965-mongo:27017/?authSource=admin"
scratch="mongodb://root:rootpw@bp965-scratch:27017/?authSource=admin"
console.log(`${apply ? "Resealed" : "Would reseal"} ${report.resealed} secret(s).`);{"type":"assistant","message":{"model":"claude-sonnet-5","id":"msg_011CdeMN5WMGasEc88hb1DEx","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"<redacted>","signature":"ErsKconst ANTHROPIC_KEY = "sk-ant-api03-7Vd2mQx_pLr8Kt3NwZa5Yb1Ce6Hg9Jk4Ml0Op2Qs";
const INTERNAL = "mongodb://mongo:[email protected]:27017";
const TUNNEL = "mongodb://mongo:[email protected]:54321/?authSource=admin&directConnection=true";
honest: { username: "someone", password: "a-long-enough-password", fullName: "Someone" },async function accept(page: Page, link: string, username: string, password = "chosen-by-the-invitee") {const token = "cps_e2eac00fdeadbeefdeadbeefdeadbeef";
const TOKEN = "ghp_e2e_audit_never_in_the_log";
const response = await PUT(put({ password: "a-brand-new-password" }), ctx());["a token pasted on its own", "ghp_abcdefghijklmnopqrstuvwxyz0123456789", "(not a web address)"],
openPr: vi.fn().mockResolvedValue("https://x-access-token:[email protected]/o/r/pull/7"),expect(said).not.toContain("ghp_0123456789abcdefghijklmnopqrstuvwxyz");await createReporter(api, statuses).noted(task, "removed ghp_0123456789abcdefghijABCDEFGHIJ012345.test.js");
"https://x-access-token:[email protected]/o/r/pull/7",
"-----BEGIN OPENSSH PRIVATE KEY-----",
next-path.test.ts
worker-user.test.ts
.release-please-manifest.json
new Function(script.textContent ?? "")();
const patch = "+PAYLOAD_KEY=eval(atob(ZXZpbA==));";
Gates applied: no_behavioural_pass.
3f8f8b4dcdb3full audit observations/trust-audit/mcp-server/rafalpodles__board-planner.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | 3f8f8b4dcdb3 | BLOCK | F | 48 | first audit |
Questions
What is the board-planner MCP server?
One board. Your team works it. So do your agents. Kanban, sprints, REST API and MCP server — self-hosted, AGPL, with a PM agent and execution workers that run your tasks under your gates.
What tools does board-planner expose?
36 in total: 27 read-only, 9 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is board-planner safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (48/100) and found 4 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What credentials does board-planner need?
It reads AI_MONTHLY_TOKENS, AI_TRIAL_TOKENS, API_KEY, BOOTSTRAP_TOKEN, CP_API_TOKEN, DEMO_PASSWORD, E2E_LICENCE_PUBLIC_KEY, E2E_PASSWORDLESS_PORT, E2E_PASSWORDLESS_SERVER, ENCRYPTION_KEY, ENCRYPTION_KEYS_OLD and GITHUB_OAUTH_BASE_URL from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How current is this page?
The grade is for one exact copy of the source (3f8f8b4dcdb3), read on 2026-10-11. The repository is watched and re-audited when it changes.