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

@cyanmycelium/mcp-broker

v0.4.0

Published

WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.

Downloads

567

Readme

npm CI License

@cyanmycelium/mcp-broker

WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint, with WebSocket, Streamable HTTP, SSE, and stdio client transports.

This is the Node/TypeScript implementation of the broker. Architecture, wire protocol, and endpoints are documented language-neutrally in ../docs.

Install and run

# Run the broker without installing
npx @cyanmycelium/mcp-broker

# Or install globally
npm install -g @cyanmycelium/mcp-broker
mcp-broker

The broker starts on http://localhost:3000 by default.

  • Connect your MCP provider to: ws://localhost:3000/provider/<name>
  • Point an MCP client at: http://localhost:3000/<name>/mcp (Streamable HTTP) or http://localhost:3000/<name>/sse (legacy SSE) or ws://localhost:3000/<name> (raw WS)

Configuration

Two sources, env vars always win over the file. The file is the static baseline you ship with the broker; env vars are deploy-specific overrides.

Option A — .mcp-broker/ folder (recommended)

Drop a .mcp-broker/ folder next to where you launch the broker. Paths inside config.json are resolved against this folder, so it stays self-contained (certs, www, grammar overrides all next to the config).

your-project/
└── .mcp-broker/
    ├── config.json       ← broker configuration
    ├── certs/            ← TLS material (optional)
    ├── grammars/         ← local grammar overrides (optional)
    └── www/              ← static dev harness (optional)

Minimal config.json:

{
    "port": 3001,
    "locale": "fr",
    "tls": {
        "cert": "certs/cert.pem",
        "key":  "certs/key.pem"
    },
    "www": {
        "open":   false,
        "mounts": [{ "urlPrefix": "/", "dir": "www" }]
    },
    "stdioUpstreams": [
        {
            "name": "fs",
            "command": "npx",
            "args":   ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
        }
    ]
}

Start from the .mcp-broker.example/ template:

cp -r node_modules/@cyanmycelium/mcp-broker/.mcp-broker.example .mcp-broker

Full reference (every field, defaults, recipes, grammar overrides): docs/config.md.

Option B — Environment variables

| Variable | Default | Notes | |---|---|---| | MCP_BROKER_CONFIG | ./.mcp-broker/config.json | Path to a JSON config file (see above) | | MCP_BROKER_PORT | 3000 | TCP port to listen on | | MCP_BROKER_HOST | 0.0.0.0 | Interface to bind | | MCP_BROKER_PROVIDER_PATH | /provider | Prefix for provider WS connections | | MCP_BROKER_CLIENT_PATH | / | Prefix for raw WS clients | | MCP_BROKER_MCP_PATH | /mcp | Suffix for Streamable HTTP | | MCP_BROKER_WWW_DIR | (unset) | If set, serve this directory at / | | MCP_BROKER_BUNDLE_DIR | (unset) | If set, serve this directory at /bundle | | MCP_BROKER_OPEN | (unset) | 1 to auto-open the browser at the root URL on startup (requires MCP_BROKER_WWW_DIR) | | MCP_BROKER_TLS_CERT | (unset) | Path to a PEM certificate. Enables HTTPS/WSS | | MCP_BROKER_TLS_KEY | (unset) | Path to a PEM private key. Enables HTTPS/WSS | | MCP_BROKER_PROTOCOL | auto | http forces plain, https forces TLS, unset auto-detects from cert+key | | MCP_BROKER_STDIO_PROVIDER | (unset) | When set, bridge stdin/stdout JSON-RPC to this provider (Claude Desktop integration) |

Programmatic API

import { WsTunnelBuilder } from "@cyanmycelium/mcp-broker";

const broker = new WsTunnelBuilder()
    .withPort(3000)
    .withHost("0.0.0.0")
    .withProviderPath("/provider")
    .withMcpPath("/mcp")
    // Optional: bridge a local stdio MCP server as a provider.
    .withStdioUpstream("my-server", "node", ["./my-server.js"])
    // Optional: serve a dev harness at /
    .withStaticMount("/", "/abs/path/to/www")
    .build();

await broker.start();

All builder methods are documented inline. The full options interface is WsTunnelOptions, also exported.

TLS for local development

npm run gen-cert
# Writes ../certs/cert.pem and ../certs/key.pem (repo root)

$env:MCP_BROKER_TLS_CERT="../certs/cert.pem"
$env:MCP_BROKER_TLS_KEY="../certs/key.pem"
npm start

The generated certificate covers localhost, 127.0.0.1, ::1 for 365 days. Browsers will warn about an untrusted issuer on first visit. Click "Advanced → Proceed". MCP clients (Claude, Inspector) ignore certificate validation by default.

Docker

A multi-stage Dockerfile ships with the package: build stage compiles TypeScript and copies grammar JSON, runtime stage carries only the compiled dist/, production node_modules, and runs as a non-root user.

# From the node/ directory
docker build -t cyanmycelium/mcp-broker:0.1.0 .

# Run on host port 3000
docker run --rm -p 3000:3000 cyanmycelium/mcp-broker:0.1.0

# With a custom locale and host port
docker run --rm -p 4000:4000 \
    -e MCP_BROKER_PORT=4000 \
    -e MCP_BROKER_LOCALE=fr-CA \
    cyanmycelium/mcp-broker:0.1.0

Mounting TLS material

# Generate localhost certs on the host first
npm run gen-cert  # writes ../certs/cert.pem and ../certs/key.pem

docker run --rm -p 3000:3000 \
    -v "$(pwd)/../certs:/certs:ro" \
    -e MCP_BROKER_TLS_CERT=/certs/cert.pem \
    -e MCP_BROKER_TLS_KEY=/certs/key.pem \
    cyanmycelium/mcp-broker:0.1.0

Mounting a static dev harness

docker run --rm -p 3000:3000 \
    -v "$(pwd)/public:/www:ro" \
    -e MCP_BROKER_WWW_DIR=/www \
    cyanmycelium/mcp-broker:0.1.0

Health check

The image declares a HEALTHCHECK that opens a TCP socket on MCP_BROKER_PORT. Orchestrators (Docker Compose, Kubernetes liveness probe) pick it up automatically.

docker-compose snippet

services:
  broker:
    build: .
    # Or pull a published image once available:
    # image: ghcr.io/pandagaume/mcp-broker:0.1.0
    ports:
      - "3000:3000"
    environment:
      MCP_BROKER_PORT: "3000"
      MCP_BROKER_LOCALE: "en"
    restart: unless-stopped

Claude Desktop integration

The broker can act as a stdio MCP server for Claude Desktop, bridging to any provider it manages:

{
  "mcpServers": {
    "broker": {
      "command": "npx",
      "args": ["-y", "@cyanmycelium/mcp-broker"],
      "env": { "MCP_BROKER_STDIO_PROVIDER": "<your-provider-name>" }
    }
  }
}

In this mode all broker logging goes to stderr; stdout is reserved for the JSON-RPC stream Claude expects.

Development

npm install
npm run build      # tsc -b
npm test           # vitest run
npm run lint
npm start          # node dist/bin.js

Requires Node 20.11+.

Releasing

The package is published to npm by .github/workflows/release-node.yml, triggered by tags of the form node-v*.

# from the node/ directory:
npm version patch            # creates a "node-v0.1.1" tag (.npmrc sets the prefix)
git push --follow-tags

The workflow runs lint, build, test, then npm publish --access public --provenance and creates a GitHub Release with auto-generated notes.

License

Apache-2.0. See LICENSE.