beans-mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited beans-mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Use this skill whenever you need to:
.beans/Do not use this skill for:
.beans/ records| Tool | Purpose |
|---|---|
beans_init | Initialize Beans in a workspace |
beans_archive | Archive completed/scrapped beans |
beans_view | View one or more beans by ID |
beans_create | Create one bean |
beans_bulk_create | Create many beans |
beans_update | Update bean metadata/body |
beans_bulk_update | Update many beans |
beans_edit | Metadata-only update helper |
beans_reopen | Reopen a completed/scrapped bean |
beans_complete_tasks | Complete markdown checklist tasks in body |
beans_delete | Delete one or more beans |
beans_query | Query/list/filter/sort/ready/graphql operations |
beans_bean_file | Read/create/edit/delete .beans files |
beans_output | Read extension output logs |
When the user asks for bean work and intent is unclear, default to this sequence:
beans_query with operation: "ready" (or refresh if broad list needed)beans_view for the specific bean(s)beans_update (or bulk variants) with minimal required changesbeans_complete_tasks for checklist completionbeans_update to completed/scrapped, then beans_archive when appropriateUse alternatives only when this default is insufficient.
beans_create, beans_bulk_create)| Field | Required | Notes |
|---|---|---|
title | ✅ | String, max 1024 chars |
type | ✅ | e.g. task, bug, feature, epic, milestone |
status | — | e.g. todo, in-progress, draft, completed, scrapped |
priority | — | critical, high, normal, low, deferred |
body | — | Markdown body content |
description | — | Deprecated alias for body; use body instead |
parent | — | Parent bean ID |
beans_update, beans_bulk_update)| Field | Notes |
|---|---|
beanId | Required — ID of bean to update |
status | New status |
type | New type |
priority | New priority |
parent | Assign to a new parent |
clearParent | Set true to detach from current parent |
blocking | Array of bean IDs this bean now blocks |
blockedBy | Array of bean IDs this bean is blocked by |
body | Full body replacement (cannot combine with bodyAppend/bodyReplace) |
bodyAppend | Append text to the end of the body |
bodyReplace | Array of { old, new } string substitutions in the body |
ifMatch | Optimistic concurrency guard — pass the bean's etag |
Use beans_archive to archive completed/scrapped beans.
{}Use beans_query with operation: "graphql" for CLI parity with beans query --json.
{
"operation": "graphql",
"graphql": "{ beans(filter: { type: [\"bug\"] }) { id title status } }"
}With variables:
{
"operation": "graphql",
"graphql": "query($q: String!) { beans(filter: { search: $q }) { id title } }",
"variables": { "q": "authentication" }
}beans_view / beans_query over ad-hoc file parsing for bean state.beans_bulk_create / beans_bulk_update for batch parent/relationship updates.beans_complete_tasks for markdown checklist completion inside a bean body.beans_archive only after work is completed/scrapped and user intent is to archive.beans_update rejects combining body with bodyAppend/bodyReplace in one request.beans_delete allows only draft/scrapped unless force: true.beans_reopen requires the current status to match requiredCurrentStatus (completed or scrapped).beanId produces a validation hint; prefer beanId (not id).ifMatch with the current bean etag from beans_view.milestone, epic, bug, feature, taskin-progress, todo, draft, completed, scrappedcritical, high, normal, low, deferredbody for full replacement.bodyAppend to append content.bodyReplace for exact replacements.body with bodyAppend/bodyReplace in one request.ifMatch with a current etag from beans_view when concurrent edits are possible.{
"beans": [
{ "title": "Design API schema", "type": "task" },
{ "title": "Implement endpoints", "type": "task" },
{ "title": "Write tests", "type": "task" }
],
"parent": "feature-auth-42"
}Each item can specify its own parent to override the top-level parent.
{
"beans": [{ "beanId": "task-001", "status": "todo" }, { "beanId": "task-002" }, { "beanId": "task-003" }],
"parent": "epic-q2-roadmap"
}{ "operation": "refresh" }{
"operation": "filter",
"statuses": ["in-progress", "todo"],
"types": ["bug", "feature"],
"tags": ["auth"]
}{ "operation": "search", "search": "authentication", "includeClosed": false }{ "operation": "sort", "mode": "updated" }Modes: status-priority-type-title (default), updated, created, id
{ "operation": "ready" }{ "operation": "llm_context", "writeToWorkspaceInstructions": true }Writes to .github/instructions/beans-prime.instructions.md when writeToWorkspaceInstructions is true.
beans_bean_file).beans/ prefix — it is resolved automatically.foo.md and .beans/foo.md are accepted; the leading .beans/ is stripped.update_frontmatter to atomically update frontmatter fields without rewriting the body.update_frontmatter defaultsupdate_frontmatter over edit when changing only metadata fields.parent_id, tags, blocking_ids, blocked_by_ids, pr, branch) to null to remove them.{ "operation": "read", "path": "task-abc--fix-login.md" }{
"operation": "edit",
"path": "task-abc--fix-login.md",
"content": "---\ntitle: \"Fix login timeout\"\nstatus: in-progress\ntype: bug\n---\n\nBody here.\n"
}{
"operation": "create",
"path": "my-note.md",
"content": "---\ntitle: \"My note\"\n---\nContent.\n",
"overwrite": false
}{ "operation": "delete", "path": "old-note.md" }{
"operation": "update_frontmatter",
"path": "task-abc--fix-login.md",
"fields": {
"status": "in-progress",
"pr": "123",
"branch": "feature/cascade-status-and-skills-npm"
}
}title values are always double-quoted in frontmatter.title: "Fix login timeout"title: Fix login timeout2026-01-01T00:00:00Ztitle, status, type, priority, tags, parent_id, blocking_ids, blocked_by_ids, pr, branch, created_at, updated_atThe server caches unfiltered list calls (no status/type/search filter) using a two-layer strategy:
id + updatedAt for all beans. If nothing has changed, the full cached result is returned without a full GraphQL round-trip.create, update, and delete always invalidate the cache immediately.Filtered queries (status/type/search) are never cached and always hit the CLI.
// Step 1 — create the parent epic
{ "title": "User Authentication", "type": "epic", "status": "todo", "priority": "high" }
// Step 2 — bulk create children under it
{
"beans": [
{ "title": "Design auth schema", "type": "task" },
{ "title": "Implement JWT flow", "type": "task" },
{ "title": "Add refresh token support", "type": "task" },
{ "title": "Write integration tests", "type": "task" }
],
"parent": "<epic-id-from-step-1>"
}{
"beanId": "task-xyz",
"status": "in-progress",
"bodyAppend": "\n## Progress\n\n- [x] Schema designed\n- [ ] Implementation started\n"
}{
"beans": [{ "beanId": "task-001" }, { "beanId": "task-002" }, { "beanId": "task-003" }],
"parent": "epic-new-parent"
}This skill should trigger for prompts like:
This skill should not trigger for prompts like:
Use evals/evals.json as the canonical test set and iterate in iteration-N/ workspace folders.
Use this file layout:
evals/evals.jsonevals/files/If you add scripts later, keep them non-interactive, expose --help, and emit structured output (JSON) on stdout.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.