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

@behavioralstate/bsp-mcp

v1.5.11

Published

MCP server for any BSP-compliant endpoint — exposes commands and queries as tools for LLM clients

Readme

bsp-mcp

MCP server for any BSP-compliant endpoint. Exposes the BSP command and query surface as MCP tools so any LLM client (ChatGPT Desktop, Claude Desktop, GitHub Copilot, Cursor) can discover and interact with a BSP service.

Supports multiple named connections in a single server instance — useful for admins who need to operate across tenant-scoped and platform-level surfaces, or across entirely separate BSP applications.


Start with AI

Paste either prompt into your LLM client to get configured in under a minute.

Configure bsp-mcp — generates the exact env vars and mcpServers JSON for your client:

Configure bsp-mcp so I can use my BSP service from [VS Code Copilot / Claude Desktop / Cursor].

Service base URL: [https://api.example.com/bsp]
API key: [my-api-key]
Tenant ID: [my-tenant-id]  ← remove this line if not multi-tenant

Output the exact env vars and mcpServers JSON block to add to my client config.

bsp-mcp docs: https://behavioralstate.io/docs/transports/mcp

Make your service BSP-compliant — scaffolds the four required endpoints in your framework:

Make my [ASP.NET Core / Express / FastAPI / Spring Boot] service BSP-compliant.

I need these four endpoints:
- GET /.well-known/bsp — discovery manifest
- GET /commands — catalogue listing accepted commands with JSON Schema
- POST /commands — CloudEvents 1.0 entry point
- GET /queries — query catalogue

Auth: X-Api-Key header. Set authentication.type = "apikey" in the manifest.

Spec reference: https://behavioralstate.io/docs

Tools

| Tool | What it does | |---|---| | list_connections | List all configured connections with names, endpoints, and descriptions (only shown when multiple connections are configured) | | get_command_catalogue | List all commands this endpoint accepts | | get_command_schema | Fetch the full JSON Schema for a command type — learn the exact fields required | | send_command | Send a command (CloudEvent 1.0 envelope built automatically) | | send_command_and_wait | Send a command then poll a query until a condition is met | | get_query_catalogue | List all read queries this endpoint exposes | | get_query_schema | Fetch the JSON Schema for a query — learn parameters and response shape | | execute_query | Execute a query and return current state synchronously |

Intended LLM flow: get_command_catalogue → pick a command → get_command_schema → gather fields → send_command.

When multiple connections are configured all operation tools gain an optional connection parameter. If the LLM is not certain which connection the user intends, it calls list_connections and asks the user to confirm before proceeding.


Setup

1. Install and build

cd mcp-server
npm install
npm run build

2. Configure

There are three configuration modes. Use whichever fits your setup — they are mutually exclusive and checked in the order listed.


Mode 1 — Per-app env vars (recommended)

One set of BSP_<APP>_* variables per application. The app name is a single uppercase word (letters and digits, no underscores), e.g. TRADING, HR, ACCOUNTING.

Required

| Variable | Description | |---|---| | BSP_<APP>_BASE_URL | Root URL of the BSP HTTP surface | | BSP_<APP>_API_KEY | Credential — not required when AUTH_TYPE=none |

Optional

| Variable | Default | Description | |---|---|---| | BSP_<APP>_TENANT_ID | — | When set, auto-generates two connections: <app>/tenant (tenant-scoped) and <app>/platform (platform-level). When omitted, generates one connection: <app>. | | BSP_<APP>_AUTH_TYPE | apikey | How the credential is sent — see Auth types below. Defaults to apikey in Mode 1 (unlike Modes 2 and 3 which default to bearer). | | BSP_<APP>_AUTH_HEADER | X-Api-Key | Header name — only used when AUTH_TYPE=apikey and AUTH_IN=header | | BSP_<APP>_AUTH_IN | header | Where the key is sent when AUTH_TYPE=apikey: header or query | | BSP_<APP>_AUTH_PARAM | apikey | Query parameter name — only used when AUTH_IN=query |

Auth types

Default differs by mode. Mode 1 defaults to apikey because BSP services typically use API key headers. Modes 2 and 3 default to bearer for backward compatibility.

| AUTH_TYPE | What it does | Extra vars needed | |---|---|---| | apikey (Mode 1 default) | Sends the key in a custom header or query param | AUTH_HEADER (header name, default X-Api-Key) or AUTH_IN=query + AUTH_PARAM | | bearer (Modes 2 & 3 default) | Sends Authorization: Bearer <key> | none | | none | No credentials sent (public endpoint) | API_KEY not required |

Examples

Single app, tenant + platform surfaces (most common admin setup):

BSP_TRADING_BASE_URL=https://api.example.com/bsp
BSP_TRADING_API_KEY=your-api-key
BSP_TRADING_TENANT_ID=your-tenant-id
BSP_TRADING_AUTH_TYPE=apikey

This generates two connections automatically:

  • trading/tenanthttps://api.example.com/bsp/tenants/your-tenant-id
  • trading/platformhttps://api.example.com/bsp

Two separate apps:

BSP_TRADING_BASE_URL=https://trading.example.com/bsp
BSP_TRADING_API_KEY=trading-key
BSP_TRADING_TENANT_ID=tenant-abc
BSP_TRADING_AUTH_TYPE=apikey

BSP_HR_BASE_URL=https://hr.example.com/bsp
BSP_HR_API_KEY=hr-key
BSP_HR_TENANT_ID=tenant-abc
BSP_HR_AUTH_TYPE=apikey

This generates four connections: trading/tenant, trading/platform, hr/tenant, hr/platform.

App with no tenant scope:

BSP_MYAPP_BASE_URL=https://api.example.com/bsp
BSP_MYAPP_API_KEY=your-api-key

Generates one connection: myapp.

MCP client config (stdio)

{
  "mcpServers": {
    "bsp": {
      "command": "npx",
      "args": ["bsp-mcp"],
      "env": {
        "BSP_TRADING_BASE_URL": "https://api.example.com/bsp",
        "BSP_TRADING_API_KEY": "your-api-key",
        "BSP_TRADING_TENANT_ID": "your-tenant-id",
        "BSP_TRADING_AUTH_TYPE": "apikey"
      }
    }
  }
}

Mode 2 — BSP_CONNECTIONS JSON array

For advanced scenarios where per-app vars are not flexible enough. Set BSP_CONNECTIONS to a JSON array of connection objects — each connection is fully explicit with no auto-generation.

Each object:

| Field | Required | Default | Description | |---|---|---|---| | name | yes | — | Connection identifier used in the connection tool parameter | | endpoint | yes | — | Fully-resolved base URL (no {tenantId} placeholder) | | apiKey | yes* | — | Credential (*not required when authType is none) | | authType | no | bearer | bearer · apikey · none | | authHeader | no | X-Api-Key | Header name when authType=apikey and authIn=header | | authIn | no | header | header or query | | authParam | no | apikey | Query param name when authIn=query | | description | no | — | Human-readable description surfaced to the LLM for connection selection |


Mode 3 — Legacy single connection

For simple single-endpoint setups. Use the flat BSP_* variables:

| Variable | Required | Default | Description | |---|---|---|---| | BSP_ENDPOINT | yes | — | Base URL of the BSP HTTP surface | | BSP_API_KEY | yes* | — | Credential (*not required when BSP_AUTH_TYPE=none) | | BSP_AUTH_TYPE | no | bearer | bearer · apikey · none | | BSP_AUTH_HEADER | no | X-Api-Key | Header name when AUTH_TYPE=apikey | | BSP_AUTH_IN | no | header | header or query | | BSP_AUTH_PARAM | no | apikey | Query param name when AUTH_IN=query |


Transport options

stdio — VS Code Copilot, Cursor, Claude Desktop

MCP_TRANSPORT defaults to stdio. Add to your client's MCP config (see Mode 1 example above).

HTTP — ChatGPT Desktop

Start in HTTP mode and expose via a tunnel:

MCP_TRANSPORT=http MCP_HTTP_PORT=3001 \
  BSP_TRADING_BASE_URL=https://api.example.com/bsp \
  BSP_TRADING_API_KEY=<key> \
  BSP_TRADING_AUTH_TYPE=apikey \
  node dist/index.js

ngrok http 3001

Then in ChatGPT Desktop: Settings → Apps & Connectors → Create, connector URL: https://<subdomain>.ngrok.app/mcp


CloudEvent source field

When sending a command, send_command requires a source value. The required value is documented in the schema description returned by get_command_schema — always read it from there, never invent it.


Publishing to npm

Never run npm publish directly — the release is fully automated via CI:

git tag -a mcp/v<x.y.z> -m "Release mcp/v<x.y.z>"
git push origin mcp/v<x.y.z>