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

@brxce/mcp-server

v2.1.0

Published

Model Context Protocol (MCP) server for BRXCE workspace management

Readme

BRXCE MCP Server

Model Context Protocol (MCP) server for BRXCE workspace management.

2.0.0: the default catalog is v2 — 29 domain tools (list/get/save per domain plus brxce_delete and brxce_delete_permanently), on stdio and on the remote POST /mcp. Breaking changes, the 1.x → v2 tool map and rollback (--catalog legacy, ?catalog=legacy, pin 1.3.0): docs/mcp/migration.md · CHANGELOG.

Installation

Default: remote URL + browser login (INT-5329)

The server is reachable over HTTP at the backend origin. Add the URL to your client, run the client's login command, sign in to BRXCE in the browser and approve the requested access. No token is copied by hand.

| Environment | URL | |---|---| | Production | https://api.brxce.com/mcp | | make backend-local | http://localhost:3000/mcp |

The desktop app shows the same URL and snippets under Settings → MCP (the URL is derived from the backend address the app is built for).

Client support table

Same table and terms as the app and ADR 2026-09-16 §2. "Supported" is only declared after the end-to-end run (register → login → read → write → revoke → reconnect, INT-5331) passes; until then the two CLIs are pending verification and Claude Desktop is unverified (only binary strings were probed; no setup path is documented here on purpose).

| Client | Probed version | Status | How to add | |---|---|---|---| | Claude Code | 2.1.272 | pending verification | claude mcp add --transport http brxce https://api.brxce.com/mcp then claude mcp login brxce | | Codex CLI | 0.153.4 | pending verification | config.toml: [mcp_servers.brxce] / url = "https://api.brxce.com/mcp", then codex mcp login brxce | | Claude Desktop | 2.110.0 | unverified | Use the URL above where the app adds a remote server; steps not verified | | Others (Cursor, ChatGPT, OpenClaw, …) | — | not a target | — |

Syntax source: official Claude Code and Codex CLI docs (probed 2026-09-16).

# Claude Code
claude mcp add --transport http brxce https://api.brxce.com/mcp
claude mcp login brxce
# Codex CLI — config.toml
[mcp_servers.brxce]
url = "https://api.brxce.com/mcp"
codex mcp login brxce

Connection states

The app's Connections panel and the API agree on the vocabulary:

| State | Meaning | Where it comes from | |---|---|---| | Connected | grant status: "active" | GET /api/v1/oauth/grants | | Revoked | grant status: "revoked" (all its tokens invalid) | DELETE /api/v1/oauth/grants/:id, password change, logout-all | | Needs re-auth | client gets 401 after a revoke → run the login command again | client behaviour after revoke | | Denied | consent declined → no grant is created, nothing is listed | consent page decision | | Failed | the grants list itself could not be loaded | app error state |

Compatibility mode: stdio + API key

Existing stdio setups keep working and nothing is revoked automatically. Generate an API key in the desktop app (Settings → MCP → Compatibility mode), then:

# Global installation
npm install -g @brxce/mcp-server

# Or use with npx (no installation needed). Pin the version so a stale npx cache
# or a moved `latest` tag cannot start a different catalog than the one you tested.
npx -y @brxce/[email protected]
npx -y @brxce/[email protected] --version   # prints the installed version

Codex/Claude Code setup, catalog modes (v2 default; consolidated / compat / legacy for rollback), migration and rollback: docs/mcp/migration.md. 1.x tool → v2 tool map: catalog-v2.md §6.

Claude Desktop Configuration

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "brxce-mcp": {
      "command": "npx",
      "args": ["-y", "@brxce/[email protected]"],
      "env": {
        "AUTH_TOKEN": "<API_KEY>"
      }
    }
  }
}

Migrating to the URL flow: re-add the client with the URL above, sign in, then revoke the old key in the app. The /mcp endpoint accepts API keys during the transition; the switch-off date is a separate decision (ADR §6).

Optional environment variables:

  • BACKEND_URL: Custom backend URL (default: Production)
  • MCP_DEBUG: Enable debug logging (default: false)

Agent Skill (Best-Practice Playbook)

This package ships a portable agent skill (brxce-mcp) that documents the v2 catalog (the 2.0.0 default — 29 tools: brxce_list_* / brxce_get_* to read, brxce_save_* to create or change, brxce_delete for restorable and brxce_delete_permanently for irreversible deletes), common workflows, and every known footgun. Upgrading from 1.x: re-run install-skill --force so the old tool names disappear from your agent's instructions. It works in both Claude Code and OpenClaw via the AgentSkills standard.

Install

# Auto-detect Claude Code and/or OpenClaw and install the skill there
npx @brxce/mcp-server install-skill

# Force a specific target
npx @brxce/mcp-server install-skill --target=claude
npx @brxce/mcp-server install-skill --target=openclaw
npx @brxce/mcp-server install-skill --target=both

# Overwrite an existing skill directory
npx @brxce/mcp-server install-skill --force

What it installs

  • ~/.claude/skills/brxce-mcp/ (Claude Code)
  • ~/.openclaw/workspace/skills/brxce-mcp/ (OpenClaw)

Each location receives a copy of SKILL.md plus the references/ directory (workflows, tool selection, footguns, error recovery).

After installing

Restart your agent so the skills cache picks up the new files:

  • Claude Code: end the session and start a new one
  • OpenClaw: openclaw gateway restart

The skill is version-locked with the MCP server it ships with. When you upgrade @brxce/mcp-server, re-run install-skill to refresh the docs.

Development

1. Build the server

pnpm build

2. Run with MCP Inspector (Recommended)

The easiest way to run the inspector with the config file:

# From project root
make mcp-inspect

This will:

  • Build the MCP server
  • Use inspector-config.json with AUTH_TOKEN included
  • Open the browser with Inspector UI
  • Test resources: user://me, workspace://{id}

First-time setup: If you don't have inspector-config.json:

  1. Copy from example: cp inspector-config.example.json inspector-config.json
  2. Add your AUTH_TOKEN (see "Getting an Auth Token" below)

Alternative methods:

Option A: Direct command with config file

npx @modelcontextprotocol/inspector --config inspector-config.json --server brxce-mcp

Option B: Using command line flags (not recommended)

npx @modelcontextprotocol/inspector \
  -e BACKEND_URL=http://localhost:3003/api/v1 \
  -e MCP_DEBUG=true \
  -e AUTH_TOKEN=your_token_here \
  node dist/index.js

Configuration

Environment Variables

Note: URL 설정은 @repo/config 패키지에서 중앙 관리됩니다. 자세한 환경 설정은 ENVIRONMENT.md 참조.

| 변수 | 설명 | 기본값 | |------|------|--------| | BRXCE_API_URL | API 엔드포인트 | (환경별 기본값) | | AUTH_TOKEN | JWT 인증 토큰 | (필수) | | REFRESH_TOKEN | JWT 리프레시 토큰 | (선택) | | MCP_DEBUG | 디버그 로깅 | false | | BRXCE_MCP_CATALOG | v2(기본, 도구 29개), 롤백용 consolidated(통합 8개)·compat(통합 8개 + legacy 별칭)·legacy(1.x 개별 도구) | v2 |

레거시 BACKEND_URL도 하위 호환성을 위해 지원됩니다.

Available Servers in Config

The inspector-config.json includes two pre-configured servers:

  • brxce-mcp: For Dev-Local environment (port 3003)
  • brxce-mcp-local: For Local environment (port 3000)

Resources

The MCP server exposes the following resources:

user://me

Returns current user information along with their accessible workspaces.

Example response:

{
  "user": {
    "id": "user-id",
    "email": "[email protected]",
    "username": "username",
    "name": "User Name",
    "createdAt": "2024-01-01T00:00:00.000Z",
    "updatedAt": "2024-01-01T00:00:00.000Z"
  },
  "workspaces": [
    {
      "id": "b7d3f0c8-4b91-4c2e-9c19-6f02c123abcd",
      "name": "My Workspace",
      "slug": "my-workspace",
      "description": "Workspace description",
      "workspaceType": "TEAM",
      "planType": "FREE",
      "spaceId": 1,
      "userRole": "OWNER"
    }
  ]
}

workspace://{id}

Returns detailed information for a specific workspace.

Example:

  • workspace://b7d3f0c8-4b91-4c2e-9c19-6f02c123abcd - Get details for workspace UUID b7d3f0c8-4b91-4c2e-9c19-6f02c123abcd
  • workspace://3f2c1a44-1b2c-4d5e-8f90-abcdef123456 - Get details for workspace UUID 3f2c1a44-1b2c-4d5e-8f90-abcdef123456

Development

Project Structure

src/
├── config/
│   └── environment.ts       # Environment configuration
├── resources/
│   ├── user-resource.ts     # User + Workspaces resource
│   └── workspace-resource.ts # Individual workspace resource
├── services/
│   └── api-client.ts        # HTTP client for backend API
└── index.ts                 # MCP server entry point

Scripts

# Development mode (watch)
pnpm dev

# Build
pnpm build

# Type checking
pnpm check-types

# Linting
pnpm lint

MCP gate (make test-mcp)

The blocking CI check for MCP changes (.github/workflows/mcp.yml) and the local command are the same script, scripts/ci/mcp-gate.sh:

make test-mcp        # build @repo/{db,config,shared} + this package, then:
                     #   mcp-server  tsc --noEmit + vitest run (whole package)
                     #   backend     tsc --noEmit + vitest run tests/mcp-transport tests/oauth tests/mcp-e2e
make test-mcp-fast   # same without the dist build (MCP_GATE_SKIP_BUILD=1)

apps/backend/tests/mcp-e2e/ drives the real @modelcontextprotocol/client (both protocol revisions) and this package's built stdio binary with the real SDK v1 client through discovery → PKCE → consent → code → tools → refresh → revoke → reconnect plus the security failure cases, against an in-memory OAuth store. pnpm --filter backend exec tsx tests/mcp-e2e/serve.ts --port 3011 boots the same harness stand-alone for claude mcp add --transport http … / codex mcp add … --url … checks (INT-5331).

Getting an Auth Token (local development / Inspector only)

End users never do this: they use the URL + login flow above, or an API key from the desktop app in compatibility mode. For the Inspector against a local backend you can use a session token:

  1. Using backend API:
# Login
curl -X POST http://localhost:3003/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "your-password"
  }'
  1. Copy the accessToken from the response

  2. Update inspector-config.json:

{
  "mcpServers": {
    "brxce-mcp": {
      ...
      "env": {
        ...
        "AUTH_TOKEN": "paste-your-token-here"
      }
    }
  }
}

Troubleshooting

"Failed to fetch user" error

  • Check if backend is running: curl http://localhost:3003/health
  • Verify BACKEND_URL matches your backend port
  • Ensure AUTH_TOKEN is valid and not expired

"Network error when calling" error

  • Verify backend is accessible
  • Check firewall/network settings
  • Ensure the backend port in BACKEND_URL is correct

Inspector not connecting

  • Make sure you've built the server first (pnpm build)
  • Check that dist/index.js exists
  • Verify the path in inspector-config.json is correct

Tool contract (INT-5330)

Every tool of the rollback catalogs (legacy / consolidated / compat), on both transports (stdio and the backend's POST /mcp), follows one contract applied at registration (src/registry/contract.ts). The v2 catalog has its own contract — per-tool outputSchema, annotations from the §1 table, structured errors with hint — described in catalog-v2.md §3 and src/tools/v2/README.md:

  • Annotations. title, readOnlyHint, destructiveHint, idempotentHint and openWorldHint are always present. They are derived from the effect classification in src/registry/effects.ts (the permission list), so readOnlyHint is true exactly for read operations and a registration that claims otherwise is refused. Rule: read → read-only/idempotent; create → additive, not idempotent; update/action → not destructive, idempotent; delete/purge → destructive, idempotent; mixed-effect tools take the strongest effect and are never idempotent; openWorldHint is always false. A tool may state a hint explicitly (see src/registry/annotations.ts).
  • Structured output. brxce_discover, brxce_describe, brxce_list_workspaces and brxce_list_workspace_members declare an outputSchema and return structuredContent; the JSON text in content is unchanged for text-only clients. The effect tools (brxce_read … brxce_purge) declare no output schema on purpose: a single-item call returns the operation's own result.
  • _meta. Every result carries _meta["brxce/server"] (name, version, revision) and _meta["brxce/tool"] (name, effects).
  • Errors. A failure is isError: true plus structuredContent.error (code, message, retryable, optional status, hint, requiredScopes, grantedScopes, workspaceIds, operation, details). Registry codes are kept as they are; backend refusals map to insufficient_scope (hint names the brxce:write scope), forbidden_workspace, UNAUTHENTICATED, FORBIDDEN, NOT_FOUND, CONFLICT, RATE_LIMITED, UPSTREAM_ERROR or INVALID_ARGUMENT. The original text is not rewritten.
  • Identity. serverInfo on initialize is brxce-mcp-server + the package version (src/version.ts); BRXCE_REVISION (the backend's /health key) adds the build sha. The brxce://server resource reports name, version, revision, transport (stdio | remote), protocolVersions and catalog.

v2 catalog (default since 2.0.0)

29 tools, one per domain action, each with its own input schema and outputSchema — no discover/describe round trip. Reads are brxce_list_* / brxce_get_*; brxce_save_* creates or updates (no id = create); deletes are brxce_delete (trash, project, share — restorable) and brxce_delete_permanently (everything else). Every write takes a required requestId, sent as the REST Idempotency-Key: replaying the same call with the same requestId returns the stored result (replayed: true) and changes nothing. Worknodes accept a uuid or "#<number>". Contract: catalog-v2.md; implementation notes: src/tools/v2/README.md.

{"name":"brxce_save_worknodes","arguments":{"requestId":"req-2026-09-24-001",
  "items":[{"workspaceId":"<ws>","title":"Copy review","nodeType":"todo"}]}}

Rollback: BRXCE_MCP_CATALOG=legacy or brxce-mcp --catalog legacy (remote: /mcp?catalog=legacy) restores the 1.x individual tools unchanged; consolidated and compat are also still selectable. They are kept for one release after 2.0.0.

Consolidated catalog (rollback; 1.x default)

The consolidated catalog was the 1.x default: eight tools — discover, describe, read, create, update, action, delete and purge (all prefixed brxce_). Discover returns compact, byte-bounded pages of operation IDs; describe returns the exact original schema on demand. Every registered operation stays reachable without operation-profile restarts, and the initial tool listing drops from ~139 KB to ~11 KB.

Selected with BRXCE_MCP_CATALOG=consolidated or --catalog consolidated; the CLI flag wins over the environment variable.

Transition: BRXCE_MCP_CATALOG=compat keeps the eight tools and also lists every legacy tool name as an alias with its original schema, so old prompts keep working in the same session. An alias refuses input that needs a stronger tool (batch delete → brxce_delete, batch update-status/update-priority → brxce_update). Retired legacy names answer FEATURE_REMOVED. See migration.md.

Pass existing arguments under input, for example:

{"name":"brxce_read","arguments":{"operation":"brxce_list_workspaces","input":{}}}

The candidate rejects unknown fields within input and effect mismatches. Mixed batch deletion must use brxce_delete, and batch update-status / update-priority must use brxce_update — the same tool the single-node update requires. Existing handlers, previews, permissions and resources remain in use. Node >=18.17 is required. The eight-tool design is a candidate: smaller initial discovery payload is measured, but full-task token/latency superiority is not yet established. See candidate validation and limitations.

One and many items in one envelope

Every executor takes either input (one item, identical to the legacy arguments) or items[] (many) — for every operation, including scalar ones such as a workspace update or a settings change, which are iterated with one outcome per item. mode is required with items and is never defaulted.

{"name":"brxce_action","arguments":{
  "operation":"brxce_batch_actions","mode":"commit","atomicity":"best_effort",
  "items":[{"clientRef":"a","input":{"action":"archive","nodeIds":["n1"]}}]}}

Every item is validated against the operation schema and re-checked against the tool's effect before the first item runs, so a rejected item cannot surface after part of the batch has already changed data. Per-item results carry clientRef, status and, on failure, a message; include:"full" returns whole payloads.

Durable operations use the same entrypoints

Operations that run on the durable execution ledger have dotted ids (worknode.status.update, …) and are reached through the same effect-specific tools — never a universal execute tool. The effect is fixed by the tool, sent to the backend, and the backend refuses an envelope whose operation has a different effect.

{"name":"brxce_update","arguments":{
  "operation":"worknode.status.update","schemaVersion":"2.0.0","mode":"commit",
  "requestId":"job-2026-09-16-1","items":[{"clientRef":"a","input":{"nodeId":"…","status":"done"}}]}}

schemaVersion and mode are required, requestId is required to commit (it is the idempotency key), and planToken carries a preview's plan. Anything the backend's own capability list rules out — wrong effect, wrong schema version, atomic without atomicChangeAndReceipt, preview without preview support, a plan-required operation without a token — is refused before the request is sent.

maxItemsPerRequest bounds one backend request, not one job: a larger envelope is split into requests of that size under a single jobId, so 100 items still go through an operation whose request cap is 10. brxce_describe states the two limits separately (maxItemsPerEnvelope, the server's BRXCE_MCP_MAX_ITEMS budget, and maxItemsPerRequest, with autoChunked: true). Two cases are refused instead of split, because splitting them would quietly break a promise: atomicity:"atomic" with more than one item (no request boundary can span them), and a commit of a plan-required operation with more items than one request holds (a planToken is bound to one request, so the later ones would run with the plan dropped). A preview larger than one request is previewed request by request and merged — every item result is kept and each chunk's plan is published in plans[] with the clientRefs it covers, under a chunked note. Durable operations are discovered lazily through brxce_discover (durableCatalog reports whether the catalog was reachable) and described through brxce_describe, so the initial tools/list stays at eight tools. When a legacy mutation has a durable equivalent, its response names it in guarantees.durableAlternative — but only after the backend's capability list confirms that operation exists with that effect.

Ids keep the backend allowlist's own spelling — dotted with camelCase (meeting.agendaItem.create, notification.markRead) or underscores (workspace.transfer_ownership, worknode.permanent_delete). The registry only recognises the dotted shape; the allowlist stays the authority on which ids exist and what effect each one has. When a capability publishes a per-item JSON Schema, brxce_describe resolves the generator's $ref wrapper and returns the item object itself (inputSchemaAvailable: true) so arguments can be built from describe alone; where the backend publishes none, describe says inputSchemaAvailable: false rather than inventing one. A commit answers with receiptId, results and counts at the top level, and adds chunks only when the job really was split across several durable requests.

The legacy path refuses requestId and planToken outright: it has no ledger, and accepting an idempotency key it cannot honour would be a false guarantee.

What the legacy path does not provide: the response reports it in guarantees. Items are iterated from this MCP process (execution:"client_iteration"), there is no durable request ledger, requestId is echoed but idempotency is not enforced, and atomicity:"atomic" is refused with ATOMICITY_UNSUPPORTED unless the operation declares real atomic support and the envelope carries exactly one item — an operation that is atomic per item is still executed item by item, so several items are never grouped into one transaction and the request is refused before any write rather than quietly downgraded. mode:"preview" is accepted only for operations whose own contract implements a preview flag; otherwise it is refused rather than quietly committing. Durable previews, receipts and idempotency are INT-5411.

Schema versions, errors and budgets

schemaVersion may be sent with any execution; if it does not match the operation's version nothing runs and SCHEMA_VERSION_MISMATCH comes back. Registry-level failures return a structured envelope — handler results and their errors pass through byte-identical to legacy, so existing clients keep working:

{"error":{"code":"INVALID_ARGUMENT","message":"…","retryable":false,
  "operation":"brxce_list_workspaces","details":{"issues":[{"path":"input.x","message":"…"}]}}}

Codes: UNKNOWN_OPERATION, SCHEMA_VERSION_MISMATCH, INVALID_ARGUMENT, INVALID_CURSOR, TOOL_EFFECT_MISMATCH, ATOMICITY_UNSUPPORTED, FEATURE_UNAVAILABLE, FEATURE_REMOVED (a legacy name an older release registered; details.replacement when one exists), RESPONSE_TOO_LARGE. Permission, plan and receipt codes from the execution contract are reserved and deliberately not emitted yet.

| Variable | Default | Effect | |---|---|---| | BRXCE_MCP_DISCOVER_BYTES | 8192 | Byte budget per discovery page. Whole operations move to the next page; entries are never cut in half. | | BRXCE_MCP_MAX_RESPONSE_BYTES | 0 (off) | When set, an oversized read fails with RESPONSE_TOO_LARGE (nothing ran; narrow it and call again). An oversized mutation is never turned into an error — the change already happened, so it comes back as status:"applied" with payloadOmitted:true and instructions to re-query rather than resend. Setting it back to 0 is the rollback. | | BRXCE_MCP_MAX_ITEMS | 1000 | Upper bound of items in one request. It is the only item cap: no operation is refused for being single-target — scalar operations are iterated with a per-item outcome. |

MCP cancellation is propagated to in-flight HTTP and attachment transfers only in the consolidated catalog, where the registry wraps every dispatch in the request signal context. The legacy (rollback) catalog registers handlers directly with the SDK, so its calls are not cancelled mid-flight. In neither mode does cancellation roll back a change the backend already applied.

brxce_discover cursors are opaque tokens bound to the catalog version and to the query/domain/effect filters, as required by the execution contract; reusing one under different filters returns INVALID_CURSOR instead of silently restarting. Discovery also reports domain, schemaVersion and availability, and states that permission is unknown until the backend evaluates the target resource — discovery is never an authorization decision. brxce_describe takes one operation or up to three operations and always returns complete schemas; it is intentionally exempt from the page budget because a truncated schema would look executable.