{"_id":"@bwb03/mcp-gateway","name":"@bwb03/mcp-gateway","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@bwb03/mcp-gateway","version":"0.1.0","description":"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.","keywords":["mcp","model-context-protocol","gateway","http","rest","agents","ai","llm","tools","openai","anthropic","claude","stdio","oauth","proxy","bridge"],"homepage":"https://github.com/BWB03/mcp-gateway#readme","bugs":{"url":"https://github.com/BWB03/mcp-gateway/issues"},"repository":{"type":"git","url":"git+https://github.com/BWB03/mcp-gateway.git"},"license":"MIT","author":{"name":"Brett Bohannon"},"type":"module","bin":{"mcp-gateway":"dist/index.js"},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","dev":"tsx src/index.ts","start":"tsx src/index.ts","authorize":"tsx scripts/authorize.ts","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run build"},"engines":{"node":">=18"},"dependencies":{"@modelcontextprotocol/sdk":"^1.12.1","yaml":"^2.6.0","zod":"^3.24.4"},"devDependencies":{"@types/node":"^22.15.3","tsup":"^8.4.0","tsx":"^4.19.4","typescript":"^5.8.3","vitest":"^3.1.3"},"gitHead":"4f239d33e6c44b699826df8ec8a319498d777a11","_id":"@bwb03/mcp-gateway@0.1.0","_nodeVersion":"24.14.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-DAbjdUNpfgabvBOqSjR1qByBVeBdlmakaVaDpJrBBXDqb4XmuvhHB70a0C2r7zgBleQPNRNhjz7fv73VOb1r0w==","shasum":"90f11cde188e9925885040ae2a7e557690c4f0a4","tarball":"https://registry.npmjs.org/@bwb03/mcp-gateway/-/mcp-gateway-0.1.0.tgz","fileCount":8,"unpackedSize":79149,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBeBjpSvR8+MhPtwP+shXvULriS2jrtxvLT3t01i9kN2AiBulDFueMb5pecefmnhqSUNehDz2irPrrdeo5tN562rKQ=="}]},"_npmUser":{"name":"bwb03","email":"brett@voartex.com"},"directories":{},"maintainers":[{"name":"bwb03","email":"brett@voartex.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-gateway_0.1.0_1775861083209_0.9098362476475916"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-10T22:44:43.149Z","0.1.0":"2026-04-10T22:44:43.398Z","modified":"2026-04-10T22:44:43.629Z"},"maintainers":[{"name":"bwb03","email":"brett@voartex.com"}],"description":"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.","homepage":"https://github.com/BWB03/mcp-gateway#readme","keywords":["mcp","model-context-protocol","gateway","http","rest","agents","ai","llm","tools","openai","anthropic","claude","stdio","oauth","proxy","bridge"],"repository":{"type":"git","url":"git+https://github.com/BWB03/mcp-gateway.git"},"author":{"name":"Brett Bohannon"},"bugs":{"url":"https://github.com/BWB03/mcp-gateway/issues"},"license":"MIT","readme":"# mcp-gateway\n\n> **Use any MCP server from any agent framework — over plain HTTP.**\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org/)\n[![MCP SDK](https://img.shields.io/badge/MCP%20SDK-1.12-blue)](https://modelcontextprotocol.io/)\n\n`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.\n\n![mcp-gateway demo](docs/demo/demo.gif)\n\n```\n┌─────────────┐         ┌──────────────┐         ┌──────────────────┐\n│  Any Agent  │  HTTP   │ mcp-gateway  │  MCP    │   MCP Server     │\n│  Framework  │ ──────► │              │ ──────► │ (stdio or HTTP)  │\n└─────────────┘  REST   └──────────────┘  proto  └──────────────────┘\n```\n\n---\n\n## Why?\n\nThe 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:\n\n1. Hand-code an HTTP wrapper for every MCP server you want to use, or\n2. Implement the MCP protocol yourself in your agent framework\n\nThis gateway does #1 generically. **Add a server to a YAML file → its tools become HTTP endpoints**. No custom code per provider.\n\n## What It Does\n\n- **Wraps any MCP server** — stdio (subprocess) or HTTP (remote) transport\n- **Auto-discovers tools** — calls `listTools()` and dynamically generates REST endpoints\n- **Auto-generates `/manifest`** — agents can introspect available tools and their input schemas\n- **Handles auth** — OAuth 2.1 + PKCE with token persistence, API keys, or no-auth\n- **Multi-server** — run many MCP servers behind one gateway, each on its own port\n- **Zero hand-coding** — same gateway binary works with Filesystem, GitHub, Intentwise, Pacvue, anything\n\n---\n\n## Quick Start\n\n```bash\ngit clone git@github.com:BWB03/mcp-gateway.git\ncd mcp-gateway\nnpm install\ncp gateway.config.example.yaml gateway.config.yaml\nnpm start\n```\n\nThat's it. Out of the box this wraps the [Filesystem MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem) (pointed at `$HOME`) and exposes its 14 tools at `http://localhost:3045`. Try it:\n\n```bash\ncurl http://localhost:3045/health\ncurl http://localhost:3045/manifest\n```\n\nThen edit `gateway.config.yaml` to add more servers — see the example file for templates covering stdio, OAuth, API key, and no-auth servers.\n\n---\n\n## Demo: Two Servers, Side By Side\n\nA 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.\n\n**`gateway.config.yaml`:**\n\n```yaml\nservers:\n  filesystem:\n    transport: stdio\n    command: npx\n    args:\n      - \"-y\"\n      - \"@modelcontextprotocol/server-filesystem\"\n      - \"/Users/me/projects\"\n    port: 3045\n\n  intentwise:\n    transport: http\n    url: https://mcp.intentwise.com/mcp\n    port: 3033\n    auth:\n      type: oauth\n      client_id: \"your-client-id\"\n      redirect_uri: \"https://your-callback.example.com/callback\"\n```\n\n**Start the gateway:**\n\n```bash\n$ npm run authorize intentwise   # one-time OAuth\n$ npm start\n\n[intentwise] listening on http://localhost:3033\n[intentwise] discovered 5 tool(s):\n  POST /get_organization        — Returns the list of Intentwise organizations...\n  POST /get_intentwise_accounts — Returns the list of AMS accounts for a given organization...\n  POST /search_schema           — Search Intentwise schema for relevant tables...\n  POST /get_insights            — Generate and execute a BigQuery SQL query from natural language...\n  POST /query                   — Generate and execute a BigQuery SQL query (deprecated alias)...\n\n[filesystem] listening on http://localhost:3045\n[filesystem] discovered 14 tool(s):\n  POST /read_file               — Read the complete contents of a file as text...\n  POST /write_file              — Create a new file or completely overwrite an existing file...\n  POST /edit_file               — Make line-based edits to a text file...\n  POST /list_directory          — Get a detailed listing of all files and directories...\n  POST /search_files            — Recursively search for files and directories matching a pattern...\n  POST /get_file_info           — Retrieve detailed metadata about a file or directory...\n  ... and 8 more\n```\n\n**Use it from anywhere — any language, any framework, any agent:**\n\n```bash\n# stdio MCP server (Filesystem)\n$ curl -X POST http://localhost:3045/list_directory \\\n    -H \"Content-Type: application/json\" \\\n    -d '{\"path\":\"/Users/me/projects/mcp-gateway/src\"}'\n\n\"[DIR] auth\\n[FILE] config.ts\\n[FILE] constants.ts\\n[FILE] gateway.ts\\n[FILE] index.ts\\n[FILE] server.ts\"\n```\n\n```bash\n# Remote HTTP MCP server (Intentwise — OAuth-authenticated)\n$ curl -X POST http://localhost:3033/get_organization \\\n    -H \"Content-Type: application/json\" \\\n    -d '{}'\n\n{\n  \"organizations\": [\n    { \"organization_id\": 42280, \"name\": \"Voartex\" }\n  ]\n}\n```\n\n```bash\n# Health check\n$ curl http://localhost:3045/health\n\n{\"status\":\"ok\",\"server\":\"filesystem\",\"connected\":true,\"tool_count\":14}\n```\n\n```bash\n# Tool discovery — agents can introspect everything\n$ curl http://localhost:3033/manifest\n\n{\n  \"name\": \"mcp-gateway:intentwise\",\n  \"version\": \"0.1.0\",\n  \"transport\": \"http\",\n  \"upstream\": \"https://mcp.intentwise.com/mcp\",\n  \"tools\": [\n    {\n      \"name\": \"get_organization\",\n      \"method\": \"POST\",\n      \"path\": \"/get_organization\",\n      \"description\": \"Returns the list of Intentwise organizations...\",\n      \"input_schema\": { \"type\": \"object\", \"properties\": { ... } }\n    },\n    ...\n  ]\n}\n```\n\nThat'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.\n\n---\n\n## Endpoints (per server)\n\nEach configured server gets its own port and exposes:\n\n| Endpoint | Method | Description |\n|---|---|---|\n| `/manifest` | GET | All discovered tools with their input schemas |\n| `/health` | GET | Connection status + tool count |\n| `/{tool_name}` | POST | One endpoint per discovered tool — JSON body matches the tool's input schema |\n\n### Example: `/manifest` response\n\n```json\n{\n  \"name\": \"mcp-gateway:intentwise\",\n  \"version\": \"0.1.0\",\n  \"transport\": \"http\",\n  \"upstream\": \"https://mcp.intentwise.com/mcp\",\n  \"base_url\": \"http://localhost:3033\",\n  \"tools\": [\n    {\n      \"name\": \"get_organization\",\n      \"method\": \"POST\",\n      \"path\": \"/get_organization\",\n      \"description\": \"Returns the list of Intentwise organizations...\",\n      \"input_schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name_filter\": { \"type\": \"string\" }\n        }\n      }\n    }\n  ]\n}\n```\n\nAgents can hit `/manifest` once to learn everything about what's available.\n\n---\n\n## CLI\n\n```bash\nmcp-gateway                  # Start all servers from gateway.config.yaml\nmcp-gateway start <server>   # Start a specific server\nmcp-gateway tools <server>   # List discovered tools for a server (no HTTP listener)\nmcp-gateway status           # Show all configured servers\nmcp-gateway --version\nmcp-gateway --help\n```\n\nOAuth setup (one-time per HTTP server with `auth.type: oauth`):\n\n```bash\nnpm run authorize <server_name>\n```\n\n---\n\n## Configuration Reference\n\n### Common fields\n\n| Field | Required | Description |\n|---|---|---|\n| `transport` | ✅ | `\"http\"` or `\"stdio\"` |\n| `port` | ✅ | Local port the gateway listens on for this server |\n| `path_prefix` | optional | URL prefix for all tool paths (e.g., `intentwise` → `/intentwise/get_organization`) |\n\n### `transport: http` fields\n\n| Field | Required | Description |\n|---|---|---|\n| `url` | ✅ | Remote MCP server URL |\n| `auth` | ✅ | Auth config (oauth / api_key / none) |\n\n### `transport: stdio` fields\n\n| Field | Required | Description |\n|---|---|---|\n| `command` | ✅ | Executable to run (e.g., `npx`, `node`, `python`) |\n| `args` | optional | Command-line arguments |\n| `env` | optional | Environment variables for the subprocess (`${VAR}` expanded from `process.env`) |\n| `cwd` | optional | Working directory for the subprocess |\n\n### Auth types (for HTTP transport)\n\n```yaml\n# OAuth 2.1 with PKCE\nauth:\n  type: oauth\n  client_id: \"...\"\n  redirect_uri: \"https://...\"\n  scope: \"...\"          # optional\n  token_file: \"...\"     # optional, defaults to ~/.mcp-gateway/tokens/{server}.json\n\n# API key in header\nauth:\n  type: api_key\n  header: X-API-Key\n  env: MY_API_KEY       # value pulled from process.env at startup\n\n# Public / no auth\nauth:\n  type: none\n```\n\n---\n\n## How It Compares\n\n|  | mcp-gateway | Hand-coded HTTP adapter | Claude Managed Agents |\n|---|---|---|---|\n| **Works with non-Claude agents** | ✅ | ✅ | ❌ |\n| **Self-hosted** | ✅ | ✅ | ❌ Anthropic only |\n| **stdio MCP support** | ✅ | One-off code | ✅ |\n| **Remote HTTP MCP support** | ✅ | One-off code | ✅ |\n| **Multi-server in one process** | ✅ | ❌ Build it | ✅ |\n| **Auto-discovers tools** | ✅ | ❌ Hand-coded | ✅ |\n| **Auto-generated manifests** | ✅ | ❌ Hand-coded | N/A (native tool calls) |\n| **Effort to add a new MCP server** | YAML entry | Days of code | Add to agent config |\n| **Cost** | Free (your infra) | Free | Per session-hour + tokens |\n\n**Use Claude Managed Agents** if your agents are Claude-based and you want zero infrastructure.\n**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.\n\n---\n\n## Architecture\n\n```\nmcp-gateway/\n  src/\n    index.ts              # CLI entry — reads config, starts gateways\n    config.ts             # YAML parser + Zod validation + ${ENV} expansion\n    gateway.ts            # Core: MCP client wrapper + transport selection + discovery\n    server.ts             # HTTP server with dynamic routes per discovered tool\n    auth/\n      oauth-provider.ts   # Generic OAuth 2.1 + PKCE implementation\n  scripts/\n    authorize.ts          # Browser-based OAuth bootstrap\n  gateway.config.yaml     # Your server definitions (gitignored)\n```\n\n### How a tool call flows\n\n```\n1. Agent: POST http://localhost:3033/get_organization { }\n2. Gateway: routes path to upstream tool name \"get_organization\"\n3. Gateway → MCP Client → Upstream MCP Server: callTool(\"get_organization\", {})\n4. Upstream returns MCP CallToolResult with text content\n5. Gateway extracts text, parses as JSON\n6. Agent receives plain JSON response\n```\n\nThe gateway is a thin proxy. It doesn't transform, cache, or rate-limit by default — those are planned as optional middleware.\n\n---\n\n## Roadmap\n\n- [x] **Phase 1: Core gateway** — config, discovery, dynamic routes, manifest, OAuth\n- [x] **Phase 1.5: stdio support** — wrap any subprocess MCP server\n- [ ] **Phase 2: Multi-server validation** — battle-test with 5+ different MCP servers\n- [ ] **Phase 3: Middleware** — universal envelope wrapper, response cache, rate limiting, structured logging\n- [ ] **Phase 4: Hosted mode** — Docker + Railway deployment, multi-tenant token storage\n\nSee the [project plan](https://github.com/BWB03/mcp-gateway/blob/main/docs/plan.md) for details.\n\n---\n\n## Development\n\n```bash\nnpm install\nnpm run dev          # Run via tsx\nnpm run build        # Build with tsup\nnpm test             # Unit tests (vitest)\n```\n\nProject uses native `node:http` (no Express/Fastify), `@modelcontextprotocol/sdk` for MCP, `zod` for validation, and `yaml` for config parsing.\n\n---\n\n## Contributing\n\nContributions welcome. See [CONTRIBUTING.md](CONTRIBUTING.md). For security issues, see [SECURITY.md](SECURITY.md).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","readmeFilename":"README.md","_rev":"1-c6d7bc48ffe55712541f191af4491dfe"}