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

@ubuligan/create-mcp-server

v0.2.0

Published

Scaffold a production-ready MCP server (auth, rate limit, logging, deploy) in one command.

Readme

create-mcp-server

Scaffold a production-ready Model Context Protocol server in one command — not just a bare stub, but auth, rate limiting, structured logging, and deployment configs wired in from the start.

npm create @ubuligan/mcp-server my-server
# or
npx @ubuligan/create-mcp-server my-server

What you get

  • Transports — Streamable HTTP (remote) and/or stdio (local clients like Claude Desktop). The entry point auto-selects at runtime.
  • Auth (HTTP) — API key / Bearer, OAuth 2.1 resource server (JWKS + .well-known/oauth-protected-resource), or a pluggable hook.
  • Rate limiting (HTTP) — fixed-window limiter keyed by auth identity, with RateLimit-* headers.
  • Logging — structured pino to stderr (safe for stdio), with secret redaction.
  • Deployment — Docker (multi-stage), Cloudflare Workers, Fly/Railway/Vercel notes, Smithery manifest.
  • DX — TypeScript, tsx dev watch, tsup build, vitest tests, zod-validated env config.

Usage

Interactive:

npx @ubuligan/create-mcp-server

Non-interactive (CI / scripted):

npx @ubuligan/create-mcp-server api \
  --transport http --auth oauth --deploy docker,cloudflare --yes

Options

| Flag | Description | | --- | --- | | -y, --yes | Accept defaults, skip prompts | | -d, --description <s> | Project description | | --transport <list> | stdio,http | | --auth <mode> | apikey | oauth | none (HTTP only) | | --deploy <list> | docker,cloudflare,vercel,smithery | | --pm <name> | npm | pnpm | yarn | bun (default: auto-detect) | | --no-install | Skip dependency install | | --no-git | Skip git init |

Running the generated server

After scaffolding:

cd my-server
npm install
npm run build

stdio (local clients) — the server speaks MCP over stdin/stdout:

node dist/index.js

HTTP (remote) — Express server exposing /mcp and /health:

PORT=3000 node dist/index.js
curl http://localhost:3000/health   # -> 200

For HTTP with auth, set the relevant env (see the generated .env.example):

# apikey
MCP_API_KEY=secret PORT=3000 node dist/index.js
# call with: Authorization: Bearer secret

Connecting a client

Claude Desktop

Add to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude:

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["/absolute/path/my-server/dist/index.js"]
    }
  }
}

Claude Code

# local (stdio)
claude mcp add my-server -- node /absolute/path/my-server/dist/index.js

# remote (HTTP)
claude mcp add --transport http my-server http://localhost:3000/mcp

Cursor / other clients

Any MCP-compatible client uses the same shape: command + args for stdio, or the /mcp URL for HTTP. The client lists your tools and calls them on demand.

Adding a tool

Tools live in src/tools/. Copy the echo pattern — export an input shape, a pure handler, and a register function:

// src/tools/weather.ts
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

export const weatherInput = {
  city: z.string().describe("City name"),
};

export async function weather({ city }: { city: string }) {
  const r = await fetch(`https://api.example.com/weather?q=${city}`);
  const data = await r.json();
  return { content: [{ type: "text" as const, text: `${city}: ${data.temp}°C` }] };
}

export function registerWeather(server: McpServer): void {
  server.registerTool(
    "weather",
    { title: "Weather", description: "Get weather for a city.", inputSchema: weatherInput },
    weather,
  );
}

Register it in src/tools/index.ts:

import { registerWeather } from "./weather.js";

export function registerTools(server: McpServer): void {
  registerEcho(server);
  registerWeather(server); // <- add
}

The handler is exported separately so you can unit-test it without a transport — see test/echo.test.ts. Rebuild (npm run build) and the client picks up the new tool.

Development (this generator)

npm install
npm run build      # bundle CLI + copy templates into dist/
npm test           # unit tests (scaffold into a temp dir)
RUN_E2E=1 npm test # also install + typecheck + build generated projects

How it works

The generator composes template directories (src/templates/*) by selected features, deep-merges each feature's package.partial.json, and substitutes __TOKEN__ placeholders. See src/generator/ for the engine.

License

MIT