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

shack-gateway

v0.1.0

Published

Progressive-discovery, security-hardened MCP gateway and aggregator

Downloads

17

Readme

shack-gateway (TypeScript)

An aggregating MCP server that multiplexes multiple downstream MCP servers behind a single, security-hardened gateway. Speaks JSON-RPC 2.0 over stdio; STDOUT carries only protocol messages and all log output goes to STDERR.

What it does

  • Connects to one or more downstream MCP servers at startup and aggregates their tools and resources into a unified namespace (server__tool).
  • Exposes a progressive-discovery surface by default: four shack_* meta-tools let clients explore and invoke downstream tools without loading every schema at once. In full mode every downstream tool is exposed directly.
  • Runs every tool call through a security pipeline: workspace sandbox (path containment), declarative allow/deny permission rules, and optional pre/post shell hooks.
  • Redacts sensitive field names (tokens, secrets, keys, etc.) from log output automatically.

MCP tools

| Tool | Arguments | Description | |---|---|---| | shack_list_tools | query? (string), server? (string) | List downstream tools as compact {name, server, summary} entries. Filter by server name or a case-insensitive keyword. Returns no input schemas — use shack_describe_tool for a full schema. | | shack_describe_tool | name (string, required) | Return the full description and JSON input schema for one namespaced tool (server__tool). | | shack_call_tool | name (string, required), arguments? (object) | Invoke a downstream tool by namespaced name. Passes through the full sandbox, permission, and hook pipeline before routing. | | shack_list_servers | — | List connected downstream servers with their tool counts. |

In expose_mode: progressive (the default) only the four meta-tools above appear in tools/list. In expose_mode: full every downstream tool is listed directly.

Configuration

The gateway reads a JSON file (default shack-config.json). All fields except workspace_root are optional.

| Field | Type | Default | Description | |---|---|---|---| | workspace_root | string | required | Absolute path; tool arguments containing paths are checked to stay inside this directory. | | expose_mode | "progressive" or "full" | "progressive" | Controls how downstream tools are surfaced. | | servers | object | {} | Map of server name to {command, args?, env?} objects. | | permissions.default_decision | "allow" / "deny" / "prompt" | "allow" | Fallback when no allow/deny rule matches. | | permissions.allow | string[] | [] | Patterns that explicitly allow calls, e.g. fs__read(*). | | permissions.deny | string[] | [] | Patterns that explicitly block calls. Evaluated before allow. | | pre_tool_hook | string | none | Shell command run before every tool call; may modify arguments or deny. | | post_tool_hook | string | none | Shell command run after every tool call; may reject results. | | redact_fields | string[] | built-in list | JSON field names whose values are masked in logs. | | request_timeout_secs | integer | 30 | Per-request timeout applied to downstream calls. |

Permission rule syntax

Rules have the form tool_name(subject_pattern):

  • fs__write(*) — match any call to fs__write.
  • bash(rm -rf:*) — match calls where the subject starts with rm -rf.
  • git(checkout) — exact match on the subject value checkout.

The subject is extracted from the first matching well-known argument key: command, path, file_path, url, query, etc.

Minimal config example:

{
  "workspace_root": "/home/user/project",
  "expose_mode": "progressive",
  "servers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/project"]
    }
  }
}

Install

npm install

Build

npm run build

Run

node dist/main.js --config shack-config.json

The server reads newline-delimited JSON-RPC 2.0 from stdin and writes responses to stdout. Log output goes to stderr.

CLI flags

| Flag | Default | Description | |---|---|---| | --config / -c | shack-config.json | Path to the gateway JSON configuration file. |

Usage example

The following shows a complete JSON-RPC 2.0 interaction over stdio. Each request is one line; each response is one line.

Request — list available tools:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"shack_list_tools","arguments":{}}}

Response — compact tool list (empty with no configured downstream servers):

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"tools\":[],\"count\":0}"}]}}

Request — call a downstream tool by namespaced name:

{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"shack_call_tool","arguments":{"name":"filesystem__read_file","arguments":{"path":"src/main.ts"}}}}

Test

npm test

Unit tests cover config parsing, tool catalog registration and search, permission rule evaluation, sandbox path validation, redaction, and hook invocation. Integration tests in tests/proxy.test.ts spawn the gateway process over stdio and exercise the full JSON-RPC surface.