Beans Mcp

io.github.voxslopuliPublished by GitHub account voxslopuliv0.7.1Updated Nov 3, 2026

Interact with the Beans CLI issue tracker agentically

VerifiedSTDIODesktop onlyDeveloper Tools

Overview

Beans's local MCP server; no sign-in required; STDIO; 14 tools.

No AI overview yet: these facts come from the registry entry and the server itself.

Installation

In SourceWeft

  1. Open Beans Mcp in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

@voxslopuli/beans-mcp 🫘

[beans-mcp icon]

[Test & Build] [codecov] [NPM Version]

MCP (Model Context Protocol) server for Beans issue tracker. Provides programmatic and CLI interfaces for AI-powered interactions with Beans workspaces.

Documentation: beans-mcp.voxslopuli.org

🤖 Try Beans fully-integrated with GitHub Copilot in VS Code! Install the selfagency.beans-vscode extension.

Usage

bash
npx @voxslopuli/beans-mcp /path/to/workspace

Bundled beans CLI

The beans CLI binary is bundled via platform-specific optional dependencies (@voxslopuli/beans-cli-darwin-arm64, -darwin-x64, -linux-arm64, -linux-x64, -win32-x64), pinned to the supported Beans version (0.4.2). At startup the server resolves the bundled binary first and falls back to the beans command in PATH. An explicit --cli-path always wins.

To release new platform packages when Beans publishes a new version:

bash
# 1. Bump beansCli.version + optionalDependencies in package.jsonpnpm fetch-beans-binaries --version <beans-version># 2. Verify staged binaries in build/beans-cli/, then publishpnpm publish-beans-cli            # add --dry-run to preview

Or dispatch the Release beans CLI packages workflow on GitHub Actions.

Versioning

@voxslopuli/beans-mcp has its own package versioning. Compatibility with the Beans CLI is tracked separately.

At startup, the server compares the installed beans CLI version against the hardcoded supported Beans version: 0.4.2. If they differ, it prints a warning to stderr and continues startup.

Parameters

  • --workspace-root or positional arg: Workspace root path
  • --cli-path: Path to Beans CLI
  • --port: MCP server port (default: 39173)
  • --log-dir: Log directory
  • -h, --help: Print usage and exit

Summary of public MCP tools

ToolDescription
beans_initInitialize the workspace (optional prefix).
beans_archiveArchive completed/scrapped beans.
beans_viewFetch full bean details by beanId or beanIds.
beans_createCreate a new bean (title/type + optional body/parent).
beans_bulk_createCreate multiple beans in one call, optionally under a shared parent.
beans_updateConsolidated metadata + body updates (status/type/priority/parent/clearParent/blocking/blockedBy/body/bodyAppend/bodyReplace) plus optional optimistic concurrency hint (ifMatch).
beans_bulk_updateUpdate multiple beans in one call, optionally reassigning them to a shared parent.
beans_complete_tasksMark all markdown checklist tasks within a bean as complete.
beans_deleteDelete one or many beans (beanId or beanIds, optional force).
beans_reopenReopen a completed or scrapped bean to an active status.
beans_queryUnified list/search/filter/sort/ready operations, with GraphQL passthrough.
beans_bean_fileRead/edit/create/delete files under .beans.
beans_outputRead extension output logs or show guidance.
Notes
  • The beans_query tool is intentionally broad: prefer it for listing, searching, filtering or sorting beans, and for generating Copilot instructions (operation: 'llm_context').
  • All file and log operations validate paths to keep them within the workspace or the VS Code log directory. The .beans/ prefix is automatically stripped from paths — you can pass either some-bean.md or .beans/some-bean.md and the result is the same.
  • beans_update replaces many fine-grained update tools; callers should use it to keep the public tool surface small and predictable.
  • beans_archive provides CLI parity for archiving completed/scrapped beans.
  • Closing a parent bean via beans_update (status: completed or status: scrapped) cascades the same status to all descendants.
  • Reopening a parent bean via beans_reopen cascades the target status to closed descendants (completed / scrapped).
  • beans_bulk_create and beans_bulk_update are best-effort: they process each item sequentially and return a per-item result array with success/error entries rather than failing atomically.
  • Frontmatter title: values are automatically double-quoted on write. Pass raw titles — quoting and escaping is handled for you.
  • beans_bean_file supports update_frontmatter for atomic frontmatter-only writes; supported fields include pr and branch.
  • Unfiltered list results are cached with a short burst TTL and a timestamp-probe refresh strategy. Mutation tools (beans_create, beans_update, beans_delete, etc.) invalidate the cache immediately.
  • Version mismatches between beans-mcp and the Beans CLI are warning-only and non-blocking by design.
  • When beanId is missing in tool input, validation errors include a hint: Did you mean \beanId`?`.

Examples

beans_init

Request:

json
{ "prefix": "project" }

Response (structuredContent):

json
{ "initialized": true }
beans_view

Request:

json
{ "beanId": "bean-abc" }

Request (multiple beans):

json
{ "beanIds": ["bean-abc", "bean-def"] }

Response (structuredContent):

json
{  "bean": {    "id": "bean-abc",    "title": "Fix login timeout",    "status": "todo",    "type": "bug",    "priority": "critical",    "body": "...markdown...",    "createdAt": "2025-12-01T12:00:00Z",    "updatedAt": "2025-12-02T08:00:00Z"  }}
beans_archive

Request:

json
{}

Response (example):

json
{ "archived": true, "archivedCount": 3 }
beans_create

Request:

json
{  "title": "Add dark mode",  "type": "feature",  "status": "todo",  "priority": "normal",  "body": "Implement theme toggle and styles",  "parent": "epic-123"}

description is accepted as a deprecated alias for body.

Response (structuredContent):

json
{  "bean": {    "id": "new-1",    "title": "Add dark mode",    "status": "todo",    "type": "feature"  }}
beans_bulk_create

Request:

json
{  "parent": "epic-123",  "beans": [    { "title": "Design mockups", "type": "task" },    { "title": "Implement API", "type": "task", "priority": "high" },    { "title": "Write tests", "type": "task", "parent": "epic-456" }  ]}

The top-level parent is applied as a default to any bean that does not specify its own parent. Here Design mockups and Implement API are assigned to epic-123; Write tests overrides with epic-456.

Response (structuredContent):

json
{  "requestedCount": 3,  "successCount": 3,  "failedCount": 0,  "results": [    { "bean": { "id": "task-1", "title": "Design mockups" } },    { "bean": { "id": "task-2", "title": "Implement API" } },    { "bean": { "id": "task-3", "title": "Write tests" } }  ]}
beans_bulk_update

Request (move a batch of tasks to in-progress and assign them to a parent):

json
{  "parent": "epic-123",  "beans": [    { "beanId": "task-1", "status": "in-progress" },    { "beanId": "task-2", "status": "in-progress" },    { "beanId": "task-3", "status": "in-progress", "parent": "epic-456" }  ]}

Response (structuredContent):

json
{  "requestedCount": 3,  "successCount": 3,  "failedCount": 0,  "results": [    { "beanId": "task-1", "bean": { "id": "task-1", "status": "in-progress" } },    { "beanId": "task-2", "bean": { "id": "task-2", "status": "in-progress" } },    { "beanId": "task-3", "bean": { "id": "task-3", "status": "in-progress" } }  ]}

Both bulk tools are best-effort: partial failures are reported per-item rather than aborting the whole batch.

beans_update

Request (change status and add blocking):

json
{  "beanId": "bean-abc",  "status": "in-progress",  "blocking": ["bean-def"],  "ifMatch": "etag-value"}

Request (atomic body modifications):

json
{  "beanId": "bean-abc",  "bodyReplace": [    { "old": "- [ ] Task 1", "new": "- [x] Task 1" },    { "old": "- [ ] Task 2", "new": "- [x] Task 2" }  ],  "bodyAppend": "## Summary\n\nAll checklist items completed."}

Note: body (full replacement) cannot be combined with bodyAppend or bodyReplace in the same request.

Response (structuredContent):

json
{  "bean": {    "id": "bean-abc",    "status": "in-progress",    "blockingIds": ["bean-def"]  }}
beans_delete

Request:

json
{ "beanId": "bean-old", "force": false }

Response:

json
{ "deleted": true, "beanId": "bean-old" }

Batch request:

json
{ "beanIds": ["bean-old", "bean-older"], "force": false }

Batch response (summary):

json
{  "requestedCount": 2,  "deletedCount": 2,  "failedCount": 0,  "results": [    { "beanId": "bean-old", "deleted": true },    { "beanId": "bean-older", "deleted": true }  ]}
beans_reopen

Request:

json
{  "beanId": "bean-closed",  "requiredCurrentStatus": "completed",  "targetStatus": "todo"}

Response:

json
{ "bean": { "id": "bean-closed", "status": "todo" } }
beans_complete_tasks

Request:

json
{ "beanId": "bean-abc" }

Response:

json
{  "bean": {    "id": "bean-abc",    "status": "todo"  },  "totalTaskCount": 5,  "updatedTaskCount": 3,  "unchangedTaskCount": 2}
beans_query examples

Refresh (list all beans):

json
{ "operation": "refresh" }

Response (partial):

json
{ "count": 12, "beans": [] }

Filter (statuses/types/tags):

json
{  "operation": "filter",  "statuses": ["in-progress", "todo"],  "types": ["bug", "feature"],  "tags": ["auth"]}

Search (full-text):

json
{ "operation": "search", "search": "authentication", "includeClosed": false }

Sort (modes: status-priority-type-title, updated, created, id):

json
{ "operation": "sort", "mode": "updated" }

Ready (actionable beans only):

json
{ "operation": "ready" }

LLM context (generate Copilot instructions; optional write-to-workspace):

json
{ "operation": "llm_context", "writeToWorkspaceInstructions": true }

Response (structuredContent):

json
{  "graphqlSchema": "...",  "generatedInstructions": "...",  "instructionsPath": "/workspace/.github/instructions/beans-prime.instructions.md"}

Raw GraphQL passthrough (CLI parity with beans query):

json
{  "operation": "graphql",  "graphql": "{ beans(filter: { type: [\"bug\"] }) { id title status } }"}

With variables:

json
{  "operation": "graphql",  "graphql": "query($q: String!) { beans(filter: { search: $q }) { id title } }",  "variables": { "q": "authentication" }}
beans_bean_file

Request (read):

json
{ "operation": "read", "path": "beans-vscode-123--title.md" }

Response:

json
{  "path": "/workspace/.beans/beans-vscode-123--title.md",  "content": "---\n...frontmatter...\n---\n# Title\n"}

Request (atomic frontmatter update):

json
{  "operation": "update_frontmatter",  "path": "beans-vscode-123--title.md",  "fields": {    "status": "in-progress",    "pr": "123",    "branch": "feature/cascade-status-and-skills-npm"  }}

Response:

json
{  "path": "/workspace/.beans/beans-vscode-123--title.md",  "bytes": 256,  "updatedFields": ["status", "pr", "branch"],  "frontmatter": {    "status": "in-progress",    "pr": "123",    "branch": "feature/cascade-status-and-skills-npm"  }}
beans_output

Request (read last 200 lines):

json
{ "operation": "read", "lines": 200 }

Response:

json
{  "path": "/workspace/.vscode/logs/beans-output.log",  "content": "...log lines...",  "linesReturned": 200}

Programmatic usage

Installation

bash
npm install beans-mcp

Example

typescript
import { createBeansMcpServer, parseCliArgs } from '@voxslopuli/beans-mcp';
const server = await createBeansMcpServer({  workspaceRoot: '/path/to/workspace',  cliPath: 'beans', // or path to beans CLI});
// Connect to stdio transport or your own transport

API

createBeansMcpServer(opts)

Creates and initializes a Beans MCP server instance.

Options:

  • workspaceRoot (string): Path to the Beans workspace
  • cliPath (string, optional): Path to Beans CLI executable (default: 'beans')
  • name (string, optional): Server name (default: 'beans-mcp-server')
  • version (string, optional): Server version
  • logDir (string, optional): Directory for server logs
  • backend (BackendInterface, optional): Custom backend implementation

Returns: { server: McpServer; backend: BackendInterface }

startBeansMcpServer(argv)

CLI-compatible entrypoint for launching the server.

Utility Functions

  • parseCliArgs(argv: string[]): Parse CLI arguments
  • isPathWithinRoot(root: string, target: string): boolean: Check if path is contained within root
  • sortBeans(beans, mode): Sort beans by specified mode

Types & Schemas

Export of GraphQL schema, Zod validation schemas, and TypeScript types for Beans records and operations.

Agent Skills (skills-npm, skills.sh)

This package ships a built-in Agent Skill under skills/ and also publishes that skill in a format that fits the broader open skills ecosystem surfaced by skills.sh.

  • Skill path in package: skills/beans-mcp/SKILL.md
  • Published skill artifact: https://beans-mcp.voxslopuli.org/.well-known/agent-skills/beans-mcp/SKILL.md
  • Published discovery index: https://beans-mcp.voxslopuli.org/.well-known/agent-skills/index.json
  • Compatible with discovery tools that scan: node_modules/**/skills/*/SKILL.md

That means you can use it with npm-based workflows such as skills-npm, while also pointing ecosystem tooling at the published skill artifact and discovery index used by skills catalogs like skills.sh.

To symlink installed npm-packaged skills into your agent workspace, you can use skills-npm in your consuming project.

License

MIT

Source: README.md at commit cde19dd

Tools

14

beans_init

Initialize Beans Workspace

Initialize Beans in the current workspace, equivalent to the extension init command.

Parametersprefix

beans_archive

Archive Beans

Archive completed or scrapped beans, equivalent to the beans CLI archive command.

Takes no parameters.

beans_view

View Bean

Fetch full bean details by ID.

ParametersbeanIdbeanIds

beans_create

Create Bean

Create a new bean.

Parametersbodytyperequiredtitlerequiredparentstatusprioritydescription

beans_edit

Edit Bean Metadata

Update bean metadata fields (status/type/priority/parent/blocking).

Takes no parameters.

beans_reopen

Reopen Bean

Reopen a completed or scrapped bean into a non-closed status.

Takes no parameters.

beans_update

Update Bean

Update bean metadata fields (status/type/priority/parent/blocking). Consolidated replacement for per-field update tools.

Takes no parameters.

beans_delete

Delete Bean

Delete a bean (intended for draft/scrapped beans).

ParametersforcebeanIdbeanIds

beans_bulk_create

Bulk Create Beans

Create multiple beans in one call. Optionally assign all of them (or a subset) to a shared parent.

Parametersbeansrequiredparent

beans_bulk_update

Bulk Update Beans

Update multiple beans in one call. Optionally assign all of them (or a subset) to a shared parent.

Parametersbeansrequiredparent

beans_complete_tasks

Complete Markdown Tasks

Mark all markdown checklist tasks within a bean as completed.

Takes no parameters.

beans_query

Query Beans

Unified query tool for refresh, filter, search, and sort operations.

ParametersmodetagstypessearchgraphqlstatusesoperationvariablesincludeClosedwriteToWorkspaceInstructions

beans_bean_file

Bean File Operations

Read, create, edit, or delete files under .beans (operation param).

Parameterspathrequiredfieldscontentoperationrequiredoverwrite

beans_output

Beans Output Tools

Read extension output log or show guidance (operation param).

Parameterslinesoperation

Version history

1
  1. v0.7.1LatestNov 3, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts