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

@karlbur/kick

v0.2.2

Published

CLI scaffolding tool for LLM-Konnector MCP servers and host servers

Downloads

340

Readme

@karlbur/kick — Project Generator

A zero-dependency CLI that scaffolds new MCP server and konnector host server packages from battle-tested templates. It reads .tpl files under templates/, substitutes {{PLACEHOLDER}} tokens, and writes the result to your chosen target directory.

Reference: The templates are derived from samples/oxb/ — the canonical working sample in this monorepo.


Table of Contents

  1. Quick Start
  2. Installation
  3. Commands
  4. Options Reference
  5. Name Validation Rules
  6. Dependency Modes
  7. Generated Project Structure
  8. Placeholder Variables
  9. Post-Generation Steps
  10. Recipes
  11. Architecture

Quick Start

# Generate an MCP server (inside monorepo)
pnpm run gen mcp acme

# Generate a host server
pnpm run gen server acme

# Add a single tool/prompt/resource to an existing MCP server (run in its dir)
pnpm run gen mcp-t tool get-orders

# Shorthand — first positional arg defaults to "mcp"
pnpm run gen acme

Each command prints a summary of created files and next-step instructions.


Installation

Inside the monorepo

No installation needed — tsx is already a root devDependency. The root package.json exposes these scripts:

{
  "gen": "tsx tools/scaffold/cli.ts", // unified entry
  "gen:mcp": "tsx tools/scaffold/gen-mcp.ts", // direct MCP generator
  "gen:server": "tsx tools/scaffold/gen-server.ts", // direct server generator
}

Outside the monorepo (published package)

npx @karlbur/kick mcp acme
# or
npx @karlbur/kick server acme

The published package exposes three binary names:

| Binary | Entry point | | ---------------------- | ----------- | | kick | ./cli.ts | | llm-konnect-scaffold | ./cli.ts | | lk-scaffold | ./cli.ts |

kick matches the package name, so npx @karlbur/kick mcp acme auto-detects it without needing --package flags.


Commands

The unified CLI (cli.ts) supports both subcommand and shorthand syntax:

npx @karlbur/kick <subcommand> <name> [options]
pnpm run gen <subcommand> <name> [options]

scaffold mcp <name>

Generates a complete MCP server package at <target>/mcp-<name>/.

pnpm run gen mcp acme

MCP-specific option:

| Flag | Default | Description | | ----------- | ----------------------- | -------------------------------------------------------------- | | --api-url | http://localhost:3201 | Upstream API URL (written to .env.example as AUTH_API_URL) |

See Options Reference for all shared flags.

scaffold server <name>

Generates a konnector host server at <target>/server-<name>/.

pnpm run gen server acme

Server-specific options:

| Flag | Default | Description | | ----------- | ----------------------- | ------------------------------------------------------------------- | | --mcp-url | http://localhost:3101 | MCP server URL (written to .env.example as MCP_SERVERS) | | --api-url | http://localhost:3201 | Upstream auth API URL (written to .env.example as AUTH_API_URL) |

scaffold mcp-t <type> <name> [--kind term|formula]

Generates a single tool, prompt, or resource file inside an existing MCP server project. Run this from the MCP server's root directory (where package.json lives). The brand name is auto-detected from package.json.

# Must be inside an MCP server directory (mcp-*/):
pnpm run gen mcp-t tool get-orders                        # → src/tools/get-orders.ts
pnpm run gen mcp-t prompt comparison                      # → src/prompts/comparison.ts
pnpm run gen mcp-t resource guide-deposit                  # → src/resources/guide-deposit.md (term)
pnpm run gen mcp-t resource promo-cashback --kind formula  # → src/resources/promo-cashback.md (formula)

Arguments:

| Argument | Description | | -------- | ------------------------------------------------------------------------- | | <type> | One of: tool, prompt, resource | | <name> | Item name (lowercase letters, numbers, hyphens; must start with a letter) | | --kind | (resource only) term (default) or formula |

Generated file locations:

| Type | Output path | | ---------- | ------------------------- | | tool | src/tools/<name>.ts | | prompt | src/prompts/<name>.ts | | resource | src/resources/<name>.md |

The generated tool template includes a standalone handler, a ToolDefinition array, and TODO placeholders. After generation, you need to manually add the export to the relevant index.ts aggregator (the CLI prints a reminder).

Resource Kinds: Term vs Formula

The --kind flag (resource type only) selects between two structured templates:

| Kind | Purpose | Template sections | | --------- | --------------------------------------------------- | ------------------------------------------------------- | | term | Policies, guidelines, rules (default) | Rules & Conditions, Important Notes, Terms & Conditions | | formula | Promotions, commissions, rank benefits (calculable) | Eligibility, Formula, Period & Boundary Rules, Examples |

Why two kinds? Term resources answer "what does the policy say?". Formula resources answer "how much do I get?" — the template forces the author to define boundaries, caps, and worked examples so the LLM can calculate edge cases (cross-period, cap interactions) accurately.

Brand detection: The CLI reads package.json and handles both naming patterns — mcp-<brand> and <brand>-mcp-server — to derive the brand prefix for tool/prompt names (e.g. tool_acme__get_orders).

Shorthand Mode

If the first argument isn't mcp or server, the CLI treats it as the project name and defaults to MCP generation:

# These are equivalent:
pnpm run gen acme
pnpm run gen mcp acme

# For a host server, you must specify the subcommand:
pnpm run gen server acme

Interactive Mode

In an interactive terminal, any argument you don't pass as a flag is prompted sequentially — press Enter to accept the default. This lets you provide just the name and accept defaults for the rest, or mix CLI flags with prompts:

# Provide name, prompt for everything else:
pnpm run gen mcp acme

# Provide name + port, prompt for the rest:
pnpm run gen server acme --port 8080

# Prompt for everything (including name):
pnpm run gen mcp
pnpm run gen server

Example — pnpm run gen server acme (name provided, rest prompted):

╔═══════════════════════════════════════════════════════════╗
║  Host Server Generator — interactive mode                 ║
║  Press Enter to accept the [default] shown in parentheses ║
╚═══════════════════════════════════════════════════════════╝

target (default: .): ↵
dep-mode (default: latest): ↵
dep-version (default: 0.1.0): ↵
scope: ↵
display-name: ↵
port (default: 3001): ↵
mcp-url (default: http://localhost:3101): ↵
api-url (default: http://localhost:3201): ↵
force (overwrite if exists) (default: false): ↵

Note: name was not prompted — it was provided positionally. And port would be skipped if you passed --port 8080.

Behavior details:

  • Fields passed as CLI flags (or positionally for name) are skipped — only unprompted fields are asked.
  • name has no default and is always required; if omitted positionally, it's the first prompt. Invalid names are re-prompted with the validation error.
  • dep-mode and force validate against their allowed values.
  • port must be a number between 1–65535.
  • Ctrl+C / Ctrl+D aborts gracefully.
  • In a non-TTY environment (CI, piped stdin), the CLI uses flags + built-in defaults without prompting. If name is missing in non-TTY, it errors.

Help & Version

pnpm run gen --help       # Show full help
pnpm run gen --version    # Print version

Options Reference

These flags apply to both mcp and server commands:

| Flag | Default (MCP / Server) | Description | | --------------------- | ---------------------- | ------------------------------------------------------------------------------------ | | <name> | (required) | Brand/service name. Directory = mcp-<name> or server-<name>. | | --target <path> | . | Output directory where the package folder is created (default = current dir). | | --dep-mode <mode> | latest | How @karlbur/* packages are referenced. See Dependency Modes. | | --dep-version <ver> | 0.1.0 | Version string when --dep-mode=version. | | --scope <@org> | (none) | npm scope for package name (e.g. @acme). If omitted, package is unscoped. | | --display-name <n> | (PascalCase of name) | Human-readable name used in package.json, server config, .env.example. | | --port <number> | 3101 / 3001 | Default port in generated .env.example. | | --force | false | Overwrite existing files. Does not delete extra files you added. |

--target Details

| Command | Default target | Example output path | | -------- | -------------- | ------------------- | | mcp | . | ./mcp-acme/ | | server | . | ./server-acme/ |

Override with any relative path:

pnpm run gen mcp acme --target packages/
# → packages/mcp-acme/

Argument Syntax

The parser supports three forms:

--flag value        # space-separated
--flag=value        # equals sign
--flag              # boolean (sets value to 'true')

Name Validation Rules

The <name> argument must satisfy all of the following:

| Rule | Valid examples | Invalid examples | | ------------------------------------- | -------------- | ------------------------------------------- | | Lowercase letters + numbers + hyphens | acme, vip2 | Acme, VIP | | Must start with a letter | acme2 | 2acme, 1brand | | No leading or trailing hyphens | my-brand | -acme, acme- | | Max 40 characters | acme | (41+ character string) | | Not a reserved name | — | oxb, shared, mcp-factory, konnector |

Regex: /^[a-z][a-z0-9-]{0,39}$/

Reserved names: oxb, shared, mcp-factory, konnector


Dependency Modes

Controls how @karlbur/shared, @karlbur/mcp-factory, and @karlbur/konnector appear in the generated package.json:

| --dep-mode | Dependency value | When to use | | ------------ | ------------------------ | ---------------------------------------------------- | | workspace | workspace:* | Inside this monorepo as a pnpm workspace member | | link | link:../packages/<pkg> | Monorepo checkout, but not a pnpm workspace member | | version | ^<dep-version> | Published packages from a registry (GitHub Packages) | | latest | latest | Always pull newest published version (default) |

Effect on tsconfig.json

| Mode | tsconfig.json behavior | | ------------------- | ----------------------------------------------------------------- | | workspace, link | Extends ../../../tsconfig.base.json (monorepo template) | | version, latest | Standalone compilerOptions — no extends (standalone template) |


Generated Project Structure

Generated MCP Server

<target>/mcp-<name>/
├── package.json            # @karlbur/shared + mcp-factory deps
├── tsconfig.json           # monorepo or standalone (based on --dep-mode)
├── .env.example            # MCP_PORT, AUTH_API_URL
└── src/
    ├── index.ts            # Re-exports: tools[], resources[], types
    ├── main.ts             # bootServer({ id, name, tools, resources }, port)
    ├── type.ts             # Brand response types (placeholder)
    ├── tools/
    │   ├── index.ts        # Aggregates all tool arrays
    │   └── get-example.ts  # Example tool with variant-block transforms
    ├── resources/
    │   ├── index.ts        # ResourceDefinition[] with readMd helper
    │   └── example.md      # Placeholder resource document
    └── prompts/
        └── index.ts        # prompt_ guide tools (placeholder)

The generated tool template follows the variant blocks pattern — handlers use transform helpers (toCards(), toTable(), etc.) to produce pre-shaped VariantContent[] for the frontend.

Generated Host Server

<target>/server-<name>/
├── package.json            # @karlbur/shared + konnector deps
├── tsconfig.json           # monorepo or standalone
├── .env.example            # PORT, LLM_*, MCP_SERVERS, AUTH_API_URL, etc.
└── src/
    ├── main.ts             # createKonnector({...}) + Express app + listen
    └── routes/
        └── auth.routes.ts  # Brand-specific auth proxy template (/login, /logout, /refresh)

Placeholder Variables

All {{KEY}} tokens in .tpl files are replaced at generation time:

| Key | Example (gen mcp acme) | Description | | -------------------- | ----------------------------- | ----------------------------------------------------------------------- | | NAME | acme | Lowercase name as provided | | NAME_PASCAL | Acme | PascalCase transform (handles hyphens: my-brandMyBrand) | | DISPLAY_NAME | Acme | Human-readable (defaults to PascalCase; override with --display-name) | | SCOPE_PREFIX | @acme/ or (empty) | npm scope + /, or empty string | | DEP_SHARED | workspace:* or ^0.1.0 | Dependency spec for @karlbur/shared | | DEP_FACTORY | workspace:* or ^0.1.0 | Dependency spec for @karlbur/mcp-factory | | DEP_KONNECTOR | workspace:* or ^0.1.0 | Dependency spec for @karlbur/konnector (server template only) | | PORT | 3101 / 3001 | Port number | | API_URL | http://localhost:3201 | Upstream API URL | | MCP_URL | http://localhost:3101 | MCP server URL (server template only) | | TSCONFIG_BASE_PATH | ../../../tsconfig.base.json | Relative path to base tsconfig (monorepo modes only) |


Post-Generation Steps

After generating an MCP server

# Standalone (latest/version mode — default):
cd mcp-acme
npm install
npm run dev

# Monorepo (workspace mode):
pnpm install                         # link the new workspace package
pnpm --filter mcp-acme run dev       # start dev server on port 3101

After generating a host server

# Copy and edit env file first:
cd server-acme
cp .env.example .env
# Edit .env: set LLM_API_KEY, MCP_SERVERS, AUTH_API_URL, etc.

# Standalone (latest/version mode — default):
npm install
npm run dev

# Monorepo (workspace mode):
pnpm install
pnpm --filter server-acme run dev    # start on port 3001

Recipes

Generate a standalone project (default — latest published deps)

npx @karlbur/kick mcp acme
npx @karlbur/kick server acme
cd mcp-acme && npm install

Generate inside the monorepo (workspace mode)

pnpm run gen mcp acme --dep-mode workspace
pnpm run gen server acme --dep-mode workspace
pnpm install

Generate with specific published versions

npx @karlbur/kick mcp acme --dep-mode version --dep-version 0.2.0 --scope @acme
npx @karlbur/kick server acme --dep-mode version --dep-version 0.2.0 --scope @acme

Custom target directory

pnpm run gen mcp billing --target packages/
# → packages/mcp-billing/

Custom ports and URLs

pnpm run gen mcp acme --port 3200 --api-url https://api.acme.com
pnpm run gen server acme --port 8080 --mcp-url http://localhost:3200

Custom display name

pnpm run gen mcp acme --display-name "ACME Corporation"

Overwrite existing files

pnpm run gen mcp acme --force

--force overwrites individual template files but does not delete extra files you may have added after the initial scaffold.


Architecture

Source Layout

tools/scaffold/
├── cli.ts              # Unified CLI entry — subcommands + shorthand
├── gen-mcp.ts          # MCP server generator (delegated from cli.ts)
├── gen-server.ts       # Host server generator (delegated from cli.ts)
├── gen-mcp-t.ts        # Single item generator (tool/prompt/resource)
├── args.ts             # Minimal --flag parser (no external deps)
├── prompt.ts           # Interactive readline prompts (TTY-only, no deps)
├── fs-utils.ts         # File ops: mkdirp, writeFile, copyFile, printSummary
├── placeholders.ts     # {{KEY}} substitution, name transforms, validation
├── package.json        # Package metadata + bin entries
└── templates/
    ├── mcp/            # MCP server .tpl files
    └── server/         # Host server .tpl files

Design Principles

  1. Zero external dependencies — Uses only Node.js built-ins (node:fs, node:path, node:url). No commander, yargs, or inquirer.
  2. Template-driven — All generated code lives in .tpl files with {{PLACEHOLDER}} tokens. The substitution engine is a single regex.
  3. Safe by default — Won't overwrite existing files unless --force is passed.
  4. Informative output — Prints a summary of created/skipped files and context-aware next-step instructions (monorepo vs standalone).

CLI Dispatch Flow

cli.ts
  ├── argv[0] === 'mcp'     →  runGen('mcp', rest)    →  import gen-mcp.ts
  ├── argv[0] === 'server'  →  runGen('server', rest) →  import gen-server.ts
  ├── argv[0] === 'mcp-t'   →  override argv + import gen-mcp-t.ts
  ├── argv[0] === <name>    →  runGen('mcp', argv)    →  import gen-mcp.ts
  └── --help / --version    →  print and exit

runGen() overrides process.argv and dynamically imports the target script, which reads process.argv.slice(2) itself. The mcp-t subcommand similarly overrides process.argv and dynamically imports gen-mcp-t.ts.