{"_id":"@eiaserinnys/sugarcoat","name":"@eiaserinnys/sugarcoat","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@eiaserinnys/sugarcoat","version":"0.2.0","description":"A lightweight stdio MCP to Streamable HTTP bridge with proper process lifecycle management","type":"module","bin":{"sugarcoat":"dist/index.js"},"scripts":{"build":"tsc","lint":"eslint src/","test":"vitest run","test:watch":"vitest","start":"node dist/index.js","prepublishOnly":"pnpm build"},"keywords":["mcp","model-context-protocol","stdio","http","bridge","streamable-http"],"publishConfig":{"access":"public"},"author":{"name":"eiaserinnys"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/eiaserinnys/sugarcoat.git"},"homepage":"https://github.com/eiaserinnys/sugarcoat#readme","bugs":{"url":"https://github.com/eiaserinnys/sugarcoat/issues"},"dependencies":{"@modelcontextprotocol/sdk":"^1.12.1","cors":"^2.8.5","cross-spawn":"^7.0.6","dotenv":"^16.4.7","express":"^4.21.2","shell-quote":"^1.8.2","yargs":"^17.7.2"},"devDependencies":{"@types/cors":"^2.8.17","@types/cross-spawn":"^6.0.6","@types/express":"^5.0.0","@types/shell-quote":"^1.7.5","@types/yargs":"^17.0.33","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","eslint":"^9.0.0","typescript":"^5.7.0","vitest":"^3.0.0"},"engines":{"node":">=18.0.0"},"_id":"@eiaserinnys/sugarcoat@0.2.0","gitHead":"d0147f59985799949aaf6461d48610f1d49fd499","_nodeVersion":"22.15.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-jZNdLQcXwoYFmoJ6P4PNElmhLEi76PH6exMz/+KZw8seWESJ74LiJGHmQg2oDTNsWWWOGL1vHGLbS1CIHzzjrQ==","shasum":"c56615f1c2b1c3f4f806c08dedf7c4489c72742d","tarball":"https://registry.npmjs.org/@eiaserinnys/sugarcoat/-/sugarcoat-0.2.0.tgz","fileCount":27,"unpackedSize":62525,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHvpwOmBiajHM8SB9tBPEJ+UKfGIChL3NZPczbqpOLn+AiEA8Wvv85/YNFEOwGok+uwnSGtN2eJdqtiSh+CtSp/seX8="}]},"_npmUser":{"name":"eiaserinnys","email":"eiaserinnys@gmail.com"},"directories":{},"maintainers":[{"name":"eiaserinnys","email":"eiaserinnys@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sugarcoat_0.2.0_1774106263118_0.48199329253003187"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-21T15:17:42.994Z","0.2.0":"2026-03-21T15:17:43.356Z","modified":"2026-03-21T15:17:43.547Z"},"maintainers":[{"name":"eiaserinnys","email":"eiaserinnys@gmail.com"}],"description":"A lightweight stdio MCP to Streamable HTTP bridge with proper process lifecycle management","homepage":"https://github.com/eiaserinnys/sugarcoat#readme","keywords":["mcp","model-context-protocol","stdio","http","bridge","streamable-http"],"repository":{"type":"git","url":"git+https://github.com/eiaserinnys/sugarcoat.git"},"author":{"name":"eiaserinnys"},"bugs":{"url":"https://github.com/eiaserinnys/sugarcoat/issues"},"license":"MIT","readme":"# sugarcoat\r\n\r\nA lightweight bridge that wraps stdio-based [MCP (Model Context Protocol)](https://modelcontextprotocol.io) servers and exposes them as [Streamable HTTP](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http) endpoints.\r\n\r\nBuilt to solve the zombie process problems that plague tools like supergateway on Windows.\r\n\r\n## Features\r\n\r\n- **Proper process lifecycle management** — child process trees are fully cleaned up on shutdown\r\n- **No shell intermediaries** — commands are parsed and spawned directly (`shell: false`), minimizing process tree depth\r\n- **Windows-first design** — handles `taskkill /F /T` for tree kill, SIGBREAK for console close, and `.cmd`/`.bat` resolution via [cross-spawn](https://github.com/moxystudio/node-cross-spawn)\r\n- **Built-in .env loading** — no need for wrapper scripts; `.env` files are loaded and injected into the child process environment without polluting the parent\r\n- **MCP Streamable HTTP spec compliant** — POST, GET (SSE), and DELETE endpoints per the MCP specification\r\n- **Single child process** — one sugarcoat instance manages one child process, shared across all HTTP sessions\r\n\r\n## Quick Start\r\n\r\n```bash\r\n# Run directly with npx (no install needed)\r\nnpx @eiaserinnys/sugarcoat --stdio \"npx -y @delorenj/mcp-server-trello\" --port 3102\r\n```\r\n\r\n## Installation\r\n\r\n```bash\r\n# Global install\r\nnpm install -g @eiaserinnys/sugarcoat\r\n\r\n# Or clone and build from source\r\ngit clone https://github.com/eiaserinnys/sugarcoat.git\r\ncd sugarcoat\r\npnpm install\r\npnpm build\r\n```\r\n\r\n## Usage\r\n\r\n```bash\r\n# Basic usage (npx)\r\nnpx @eiaserinnys/sugarcoat --stdio \"npx -y @delorenj/mcp-server-trello\" --port 3102\r\n\r\n# Basic usage (global install)\r\nsugarcoat --stdio \"npx -y @delorenj/mcp-server-trello\" --port 3102\r\n\r\n# With .env file for child process\r\nsugarcoat --stdio \"npx -y slack-mcp-server@latest\" --port 3101 --env-file ./services/mcp-slack/.env\r\n\r\n# Multiple .env files\r\nsugarcoat --stdio \"your-server\" --port 8000 --env-file .env.common --env-file .env.local\r\n\r\n# Custom endpoint paths\r\nsugarcoat --stdio \"your-server\" --port 8000 --path /api/mcp --health /api/health\r\n\r\n# Enable CORS\r\nsugarcoat --stdio \"your-server\" --port 8000 --cors\r\n\r\n# Debug logging\r\nsugarcoat --stdio \"your-server\" --port 8000 --log-level debug\r\n```\r\n\r\n## CLI Options\r\n\r\n| Option | Type | Default | Description |\r\n|---|---|---|---|\r\n| `--stdio` | string | *required* | The stdio MCP server command to wrap |\r\n| `--port` | number | `8000` | HTTP server port |\r\n| `--path` | string | `/mcp` | Streamable HTTP endpoint path |\r\n| `--env-file` | string[] | `[]` | Path(s) to .env file(s) for child process |\r\n| `--health` | string | `/health` | Health check endpoint path |\r\n| `--cors` | boolean | `false` | Enable CORS |\r\n| `--log-level` | string | `info` | Log level: `debug`, `info`, or `none` |\r\n\r\n## How It Works\r\n\r\n```\r\nClient (Claude Code, etc.)\r\n    │\r\n    ├── POST /mcp   → JSON-RPC request  → child stdin\r\n    ├── GET  /mcp   → SSE stream        ← child stdout\r\n    └── DELETE /mcp → session cleanup\r\n    │\r\nsugarcoat (HTTP server)\r\n    │\r\n    └── child process (stdio MCP server)\r\n        stdin  ← JSON-RPC messages (newline-delimited)\r\n        stdout → JSON-RPC responses (newline-delimited)\r\n```\r\n\r\n## Why Not supergateway?\r\n\r\n[supergateway](https://github.com/nicobrinkkemper/supergateway) offers two modes — **stateless** (new child per session) and **stateful** (shared child). Both have trade-offs that sugarcoat avoids:\r\n\r\n```\r\n                          supergateway    supergateway\r\n                          (stateless)     (stateful)      sugarcoat\r\n                          ─────────────   ─────────────   ─────────────\r\nProcess per session       Yes (new child  No (shared)     No (shared)\r\n                          each time)\r\n\r\nWindows zombie            No              No              Yes\r\nprevention                                                (taskkill /F /T)\r\n\r\nInit caching              N/A             No              Yes\r\n\r\nID namespacing            N/A             No              Yes\r\n\r\n.env loading              No              No              Yes (built-in)\r\n```\r\n\r\n**supergateway stateless** spawns a new child process per HTTP session. On Windows, these processes accumulate as zombies because `shell: true` creates `cmd.exe` intermediaries that survive parent death, and there is no process tree kill.\r\n\r\n**supergateway stateful** shares a single child process, but lacks init caching and request ID namespacing. Without init caching, each new HTTP session re-initializes the child, causing stateful MCP servers (e.g., chrome-devtools-mcp) to lose internal state. Without ID namespacing, concurrent sessions that send the same JSON-RPC id (e.g., both send `id: 1`) cause routing collisions.\r\n\r\n**sugarcoat** combines the shared-process model with init caching and ID namespacing, plus Windows-specific cleanup (`taskkill /F /T`, SIGBREAK handling, `.env` loading to avoid shell wrappers).\r\n\r\n## Limitations\r\n\r\n- **No shell operators** — Pipe (`|`), redirection (`>`), and other shell operators in the `--stdio` command are not supported. Commands are parsed and spawned directly without a shell.\r\n- **Shared child process** — A single child process is shared across all HTTP sessions. For stateful MCP servers, sugarcoat initializes the child once at startup and caches the init result, so subsequent sessions receive cached capabilities without re-initializing.\r\n- **Windows-first** — sugarcoat was designed for Windows environments. It works on Linux/macOS as well, but the primary use case and testing target is Windows.\r\n\r\n## Contributing\r\n\r\nIssues and pull requests are welcome.\r\n\r\nThis project uses [pnpm](https://pnpm.io/) as its package manager:\r\n\r\n```bash\r\npnpm install\r\npnpm build\r\npnpm test\r\n```\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md","_rev":"1-44d0c212d347ae4dded357af1ae94db4"}