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

@bwb03/mcp-gateway

v0.1.0

Published

Generic MCP-to-HTTP gateway — auto-discovers any MCP server's tools and exposes them as REST endpoints. Wraps stdio or remote HTTP MCP servers so any agent framework can use them.

Readme

mcp-gateway

Use any MCP server from any agent framework — over plain HTTP.

License: MIT Node MCP SDK

mcp-gateway is a generic bridge that connects to any MCP server (stdio subprocess or remote HTTP) and exposes its tools as REST endpoints. Configure once with YAML, and any agent — OpenAI Assistants, custom code, OpenClaw, your own Python script — can use MCP servers without speaking the MCP protocol.

mcp-gateway demo

┌─────────────┐         ┌──────────────┐         ┌──────────────────┐
│  Any Agent  │  HTTP   │ mcp-gateway  │  MCP    │   MCP Server     │
│  Framework  │ ──────► │              │ ──────► │ (stdio or HTTP)  │
└─────────────┘  REST   └──────────────┘  proto  └──────────────────┘

Why?

The Model Context Protocol is a great way to expose tools to AI agents — but right now it's mostly used inside Claude apps (Desktop, Code, Managed Agents). If you're building with anything else (OpenAI, LangChain, custom frameworks, your own bot), you have to either:

  1. Hand-code an HTTP wrapper for every MCP server you want to use, or
  2. Implement the MCP protocol yourself in your agent framework

This gateway does #1 generically. Add a server to a YAML file → its tools become HTTP endpoints. No custom code per provider.

What It Does

  • Wraps any MCP server — stdio (subprocess) or HTTP (remote) transport
  • Auto-discovers tools — calls listTools() and dynamically generates REST endpoints
  • Auto-generates /manifest — agents can introspect available tools and their input schemas
  • Handles auth — OAuth 2.1 + PKCE with token persistence, API keys, or no-auth
  • Multi-server — run many MCP servers behind one gateway, each on its own port
  • Zero hand-coding — same gateway binary works with Filesystem, GitHub, Intentwise, Pacvue, anything

Quick Start

git clone [email protected]:BWB03/mcp-gateway.git
cd mcp-gateway
npm install
cp gateway.config.example.yaml gateway.config.yaml
npm start

That's it. Out of the box this wraps the Filesystem MCP server (pointed at $HOME) and exposes its 14 tools at http://localhost:3045. Try it:

curl http://localhost:3045/health
curl http://localhost:3045/manifest

Then edit gateway.config.yaml to add more servers — see the example file for templates covering stdio, OAuth, API key, and no-auth servers.


Demo: Two Servers, Side By Side

A single config file wraps a stdio MCP server (Filesystem) and a remote HTTP MCP server (Intentwise) at the same time. Each gets its own port. Each becomes pure HTTP.

gateway.config.yaml:

servers:
  filesystem:
    transport: stdio
    command: npx
    args:
      - "-y"
      - "@modelcontextprotocol/server-filesystem"
      - "/Users/me/projects"
    port: 3045

  intentwise:
    transport: http
    url: https://mcp.intentwise.com/mcp
    port: 3033
    auth:
      type: oauth
      client_id: "your-client-id"
      redirect_uri: "https://your-callback.example.com/callback"

Start the gateway:

$ npm run authorize intentwise   # one-time OAuth
$ npm start

[intentwise] listening on http://localhost:3033
[intentwise] discovered 5 tool(s):
  POST /get_organization        — Returns the list of Intentwise organizations...
  POST /get_intentwise_accounts — Returns the list of AMS accounts for a given organization...
  POST /search_schema           — Search Intentwise schema for relevant tables...
  POST /get_insights            — Generate and execute a BigQuery SQL query from natural language...
  POST /query                   — Generate and execute a BigQuery SQL query (deprecated alias)...

[filesystem] listening on http://localhost:3045
[filesystem] discovered 14 tool(s):
  POST /read_file               — Read the complete contents of a file as text...
  POST /write_file              — Create a new file or completely overwrite an existing file...
  POST /edit_file               — Make line-based edits to a text file...
  POST /list_directory          — Get a detailed listing of all files and directories...
  POST /search_files            — Recursively search for files and directories matching a pattern...
  POST /get_file_info           — Retrieve detailed metadata about a file or directory...
  ... and 8 more

Use it from anywhere — any language, any framework, any agent:

# stdio MCP server (Filesystem)
$ curl -X POST http://localhost:3045/list_directory \
    -H "Content-Type: application/json" \
    -d '{"path":"/Users/me/projects/mcp-gateway/src"}'

"[DIR] auth\n[FILE] config.ts\n[FILE] constants.ts\n[FILE] gateway.ts\n[FILE] index.ts\n[FILE] server.ts"
# Remote HTTP MCP server (Intentwise — OAuth-authenticated)
$ curl -X POST http://localhost:3033/get_organization \
    -H "Content-Type: application/json" \
    -d '{}'

{
  "organizations": [
    { "organization_id": 42280, "name": "Voartex" }
  ]
}
# Health check
$ curl http://localhost:3045/health

{"status":"ok","server":"filesystem","connected":true,"tool_count":14}
# Tool discovery — agents can introspect everything
$ curl http://localhost:3033/manifest

{
  "name": "mcp-gateway:intentwise",
  "version": "0.1.0",
  "transport": "http",
  "upstream": "https://mcp.intentwise.com/mcp",
  "tools": [
    {
      "name": "get_organization",
      "method": "POST",
      "path": "/get_organization",
      "description": "Returns the list of Intentwise organizations...",
      "input_schema": { "type": "object", "properties": { ... } }
    },
    ...
  ]
}

That's the whole story: one YAML, two MCP servers (one local subprocess, one remote OAuth), every tool available as a plain HTTP endpoint. No custom code per provider.


Endpoints (per server)

Each configured server gets its own port and exposes:

| Endpoint | Method | Description | |---|---|---| | /manifest | GET | All discovered tools with their input schemas | | /health | GET | Connection status + tool count | | /{tool_name} | POST | One endpoint per discovered tool — JSON body matches the tool's input schema |

Example: /manifest response

{
  "name": "mcp-gateway:intentwise",
  "version": "0.1.0",
  "transport": "http",
  "upstream": "https://mcp.intentwise.com/mcp",
  "base_url": "http://localhost:3033",
  "tools": [
    {
      "name": "get_organization",
      "method": "POST",
      "path": "/get_organization",
      "description": "Returns the list of Intentwise organizations...",
      "input_schema": {
        "type": "object",
        "properties": {
          "name_filter": { "type": "string" }
        }
      }
    }
  ]
}

Agents can hit /manifest once to learn everything about what's available.


CLI

mcp-gateway                  # Start all servers from gateway.config.yaml
mcp-gateway start <server>   # Start a specific server
mcp-gateway tools <server>   # List discovered tools for a server (no HTTP listener)
mcp-gateway status           # Show all configured servers
mcp-gateway --version
mcp-gateway --help

OAuth setup (one-time per HTTP server with auth.type: oauth):

npm run authorize <server_name>

Configuration Reference

Common fields

| Field | Required | Description | |---|---|---| | transport | ✅ | "http" or "stdio" | | port | ✅ | Local port the gateway listens on for this server | | path_prefix | optional | URL prefix for all tool paths (e.g., intentwise/intentwise/get_organization) |

transport: http fields

| Field | Required | Description | |---|---|---| | url | ✅ | Remote MCP server URL | | auth | ✅ | Auth config (oauth / api_key / none) |

transport: stdio fields

| Field | Required | Description | |---|---|---| | command | ✅ | Executable to run (e.g., npx, node, python) | | args | optional | Command-line arguments | | env | optional | Environment variables for the subprocess (${VAR} expanded from process.env) | | cwd | optional | Working directory for the subprocess |

Auth types (for HTTP transport)

# OAuth 2.1 with PKCE
auth:
  type: oauth
  client_id: "..."
  redirect_uri: "https://..."
  scope: "..."          # optional
  token_file: "..."     # optional, defaults to ~/.mcp-gateway/tokens/{server}.json

# API key in header
auth:
  type: api_key
  header: X-API-Key
  env: MY_API_KEY       # value pulled from process.env at startup

# Public / no auth
auth:
  type: none

How It Compares

| | mcp-gateway | Hand-coded HTTP adapter | Claude Managed Agents | |---|---|---|---| | Works with non-Claude agents | ✅ | ✅ | ❌ | | Self-hosted | ✅ | ✅ | ❌ Anthropic only | | stdio MCP support | ✅ | One-off code | ✅ | | Remote HTTP MCP support | ✅ | One-off code | ✅ | | Multi-server in one process | ✅ | ❌ Build it | ✅ | | Auto-discovers tools | ✅ | ❌ Hand-coded | ✅ | | Auto-generated manifests | ✅ | ❌ Hand-coded | N/A (native tool calls) | | Effort to add a new MCP server | YAML entry | Days of code | Add to agent config | | Cost | Free (your infra) | Free | Per session-hour + tokens |

Use Claude Managed Agents if your agents are Claude-based and you want zero infrastructure. Use mcp-gateway if you're using OpenAI / LangChain / custom frameworks, need self-hosting, or want a drop-in HTTP layer for any MCP server.


Architecture

mcp-gateway/
  src/
    index.ts              # CLI entry — reads config, starts gateways
    config.ts             # YAML parser + Zod validation + ${ENV} expansion
    gateway.ts            # Core: MCP client wrapper + transport selection + discovery
    server.ts             # HTTP server with dynamic routes per discovered tool
    auth/
      oauth-provider.ts   # Generic OAuth 2.1 + PKCE implementation
  scripts/
    authorize.ts          # Browser-based OAuth bootstrap
  gateway.config.yaml     # Your server definitions (gitignored)

How a tool call flows

1. Agent: POST http://localhost:3033/get_organization { }
2. Gateway: routes path to upstream tool name "get_organization"
3. Gateway → MCP Client → Upstream MCP Server: callTool("get_organization", {})
4. Upstream returns MCP CallToolResult with text content
5. Gateway extracts text, parses as JSON
6. Agent receives plain JSON response

The gateway is a thin proxy. It doesn't transform, cache, or rate-limit by default — those are planned as optional middleware.


Roadmap

  • [x] Phase 1: Core gateway — config, discovery, dynamic routes, manifest, OAuth
  • [x] Phase 1.5: stdio support — wrap any subprocess MCP server
  • [ ] Phase 2: Multi-server validation — battle-test with 5+ different MCP servers
  • [ ] Phase 3: Middleware — universal envelope wrapper, response cache, rate limiting, structured logging
  • [ ] Phase 4: Hosted mode — Docker + Railway deployment, multi-tenant token storage

See the project plan for details.


Development

npm install
npm run dev          # Run via tsx
npm run build        # Build with tsup
npm test             # Unit tests (vitest)

Project uses native node:http (no Express/Fastify), @modelcontextprotocol/sdk for MCP, zod for validation, and yaml for config parsing.


Contributing

Contributions welcome. See CONTRIBUTING.md. For security issues, see SECURITY.md.

License

MIT — see LICENSE.