npm package: @mcp-init/create
Description: Interactive CLI that scaffolds a production-ready MCP server. Define your tools, generate real vurb code.
Latest version: 1.0.0

# @mcp-init/create

<div align="center">

**The fastest way to build and ship an MCP server.**

[![npm](https://img.shields.io/npm/v/@mcp-init/create?color=ff4d00&label=npm)](https://npmjs.com/package/@mcp-init/create)
[![Powered by vurb](https://img.shields.io/badge/powered%20by-vurb-6c47ff)](https://npmjs.com/package/@vurb/core)
[![License](https://img.shields.io/npm/l/@mcp-init/create)](LICENSE)

</div>

---

## What is an MCP server and why do you need one?

An MCP server is a process that gives AI agents — Claude, Cursor, VS Code, and any other MCP-compatible client — access to **your systems, your data, and your APIs**.

Without an MCP server, the AI can only work with what you paste into the chat. With an MCP server, the AI can call your tools directly, in real time, and use the results to answer questions, generate reports, or take actions — all without you copying and pasting anything.

**Concrete examples of what a running MCP server enables:**

| You ask the AI | The AI calls your tool | The AI responds with |
|---|---|---|
| "Give me a summary of Q1 performance" | `analytics.summary(period: "Q1 2024")` | A real summary from your database |
| "Create a new user account for Ana" | `users.create(name: "Ana", role: "member")` | Confirmation with the new user ID |
| "What orders are pending today?" | `orders.list(status: "pending", date: "today")` | A real list from your order system |
| "Generate a billing report for March" | `billing.report(from: "2024-03-01", to: "2024-03-31")` | A real report from your billing service |

The AI does not have access to your data. **Your MCP server does.** You write the implementation — the AI decides when and how to call it.

---

## What this CLI does

`@mcp-init/create` is an interactive wizard that builds the full scaffolding of an MCP server for you. You describe your server and its tools step by step. The CLI generates a complete, typed TypeScript project using the [vurb](https://npmjs.com/package/@vurb/core) framework — with the full structure, the tool definitions, and the connection code already wired.

**You only need to write the implementation logic.** Everything else is generated.

```bash
npx @mcp-init/create
```

---

## What you get

When the wizard finishes, you have a **fully wired MCP server** ready to implement:

- A project folder with a clean structure
- One TypeScript file per tool — with your parameters already declared and a `// TODO` where your logic goes
- The server entry point already generated and connected to all your tools
- All dependencies installed

---


## Step by step

### Step 1 — Run the wizard

Open your terminal in the folder where you want to create your server and run:

```bash
npx @mcp-init/create
```

You will see a welcome screen and the wizard will start immediately.

---

### Step 2 — Name your server

```
◆  Server name
│  analytics-server
```

This becomes the project folder name and the npm package name.

**Rules:** lowercase letters, numbers, and hyphens only.
**Examples:** `analytics-server`, `user-management`, `billing-tools`, `support-bot`

---

### Step 3 — Describe your server

```
◆  What does this server do?  (the LLM reads this)
│  Provides analytics and reporting tools for business intelligence dashboards
```

This description is read by the AI agent to understand what your server does and when to use it. **Write it like you are explaining to a smart colleague in one sentence.** Be precise.

---

### Step 4 — Define your first tool

```
◆  Tool name
│  analytics.summary
```

A tool is a function the AI agent can call. You can have as many as you need — each one will get its own file.

**Naming convention:** `resource.action` — always two words separated by a dot.

| Good | Not good |
|---|---|
| `users.list` | `listUsers` |
| `orders.create` | `CreateOrder` |
| `analytics.summary` | `summary` |
| `billing.refund` | `billing-refund` |

---

### Step 5 — Describe the tool

```
◆  Describe analytics.summary  (the LLM reads this)
│  Generate a business summary for a given time period and category
```

This is what the AI agent reads to decide **when and why** to call this tool. Be direct and specific.

**Good descriptions:**
- `Returns a paginated list of all users in the workspace`
- `Creates a new order and returns the confirmation number`
- `Generates a business summary report for the given time period`

**Bad descriptions:**
- `Does the thing`
- `Analytics stuff`
- `Tool for users`

---

### Step 6 — Add parameters

```
◆  Does this tool take parameters?
│  Yes

ℹ  Parameters define what the LLM must pass when calling this tool.
   Each parameter has a name, type, description, and a required flag.
   The LLM reads the description to understand what value to provide.

◆  Parameter name
│  period

◆  Type of period
│  ● string   Any text value — IDs, names, queries, dates, free-form input
│  ○ number   Integer or float — limits, offsets, amounts, percentages
│  ○ boolean  True / false flag — toggles, include/exclude switches
│  ○ enum     One of a fixed set — status, role, category, priority

◆  Describe period  (the LLM reads this)
│  Time period to analyze, e.g. "Q1 2024" or "last 30 days"

◆  Is period required?
│  Yes

  ✓ period  string  required

◆  Add another parameter?
│  Yes
```

Repeat for each parameter. When you are done, answer **No** to "Add another parameter?" and the wizard moves on.

**Parameter types explained:**

| Type | Use when | Example values |
|---|---|---|
| `string` | The value is free-form text | `"Q1 2024"`, `"user@example.com"`, `"New York"` |
| `number` | The value is a number | `10`, `3.14`, `100` |
| `boolean` | The value is yes or no | `true`, `false` |
| `enum` | The value must be one of a known list | `"active"`, `"pending"`, `"cancelled"` |

**Always use `enum`** when you know all valid options in advance — it prevents the LLM from inventing invalid values.

---

### Step 7 — Add more tools

```
◆  Add another tool?
│  Yes
```

Answer **Yes** to keep adding tools. Answer **No** when your server is complete. Each tool repeats steps 4–6.

---

### Step 8 — Select middleware

```
◆  Select middleware  (space to toggle, enter to confirm)

│  ◉  @mcp-utils/cache     Cache repeated LLM calls — stop hitting your DB on every request
│  ◉  @mcp-utils/retry     Retry on failure — survive transient API and network errors
│  ◯  @mcp-utils/timeout   Hard timeout — prevent hanging tool calls from stalling your agent
```

Middleware wraps your tool handlers to add production features automatically. **You do not write any wrapping code** — the CLI generates it for you.

| Middleware | What it does | Use when |
|---|---|---|
| `@mcp-utils/cache` | Caches results for a set time (60s by default) | Your tools call external APIs or databases |
| `@mcp-utils/retry` | Retries up to 3 times with exponential backoff | Your tools call unreliable external services |
| `@mcp-utils/timeout` | Fails after 10 seconds instead of hanging | Any tool that calls slow APIs |

This step is optional. You can skip it and add middleware later.

---

### Step 9 — Install dependencies

```
◆  Install dependencies now?
│  Yes
```

Answer **Yes** to let the CLI run `npm install` automatically. Answer **No** if you want to do it yourself later.

---

### Step 10 — Done

```
└  ✓ analytics-server is ready!

   1. Open src/tools/ and implement your tool handlers
   2. Run npm run build to compile
   3. Run node dist/index.js to start your MCP server
```

Your server is ready. Open the project in your editor, find `src/tools/`, and implement the `// TODO` section in each tool file with your actual logic.

---

## After the wizard — what to do next

When the wizard finishes, each tool file is generated with your definitions already in place and a `// TODO` comment marking where your logic goes.

### What the generated file looks like

```ts
// src/tools/analytics.summary.ts  (generated — before you implement it)

import { f, success } from '@vurb/core';
import { withCache }   from '@mcp-utils/cache';
import { withTimeout } from '@mcp-utils/timeout';

export const analyticsSummaryTool = f.tool('analytics.summary')
    .describe('Generate a business summary for a given time period and category.')
    .withString('period', 'Time period to analyze, e.g. "Q1 2024" or "last 30 days"')
    .withEnum('category', ['revenue', 'users', 'performance', 'costs'], 'Business category', { required: false })
    .handle(
        withTimeout(
            withCache(
                async (input) => {
                    // TODO: implement analytics.summary
                    return success({ ...input });
                },
                { ttl: 60_000 },
            ),
            10_000,
        ),
    );
```

### What the final implemented server looks like

You replace the `// TODO` with your real logic. Everything else stays exactly as generated:

```ts
// src/tools/analytics.summary.ts  (after you implement it — production-ready)

import { f, success } from '@vurb/core';
import { withCache }   from '@mcp-utils/cache';
import { withTimeout } from '@mcp-utils/timeout';
import { analyticsService } from '../services/analytics.js';

export const analyticsSummaryTool = f.tool('analytics.summary')
    .describe('Generate a business summary for a given time period and category.')
    .withString('period', 'Time period to analyze, e.g. "Q1 2024" or "last 30 days"')
    .withEnum('category', ['revenue', 'users', 'performance', 'costs'], 'Business category', { required: false })
    .handle(
        withTimeout(
            withCache(
                async (input) => {
                    const summary = await analyticsService.summarize({
                        period:   input.period,
                        category: input.category ?? 'revenue',
                    });

                    return success({
                        period:   input.period,
                        category: input.category ?? 'revenue',
                        total:    summary.total,
                        change:   summary.percentChange,
                        insight:  summary.topInsight,
                    });
                },
                { ttl: 60_000 },
            ),
            10_000,
        ),
    );
```

The entry point `src/index.ts` is already generated and wired — you do not touch it unless you want to rename the server or add a new tool manually:

```ts
// src/index.ts  (fully generated — ready to run)

import { vurb } from '@vurb/core';
import { analyticsSummaryTool } from './tools/analytics.summary.js';
import { analyticsReportTool }  from './tools/analytics.report.js';

vurb()
    .name('analytics-server')
    .describe('Analytics and reporting tools for business intelligence dashboards.')
    .use(analyticsSummaryTool)
    .use(analyticsReportTool)
    .start();
```

When you run `node dist/index.js`, this is the process the AI client connects to over stdio.

---



## Connecting your server to an AI client

MCP servers communicate over **stdio** — which means your server runs as a local process and the AI client (Claude Desktop, Cursor, VS Code, etc.) launches it automatically when needed.

### Step 1 — Build your server

```bash
cd analytics-server
npm run build
```

This compiles your TypeScript to `dist/index.js`.

### Step 2 — Find your config file

Each client has a JSON config file where you register MCP servers.

| Client | Config file location |
|---|---|
| **Claude Desktop** (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| **Claude Desktop** (Windows) | `%APPDATA%\Claude\claude_desktop_config.json` |
| **Cursor** | Settings → MCP → Edit config |
| **VS Code** | `.vscode/mcp.json` in your workspace |

### Step 3 — Register your server

Open the config file and add your server under `mcpServers`:

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

Replace `/absolute/path/to/analytics-server` with the full path to your project folder.

**On Windows**, use double backslashes or forward slashes:
```json
"args": ["C:/Users/you/projects/analytics-server/dist/index.js"]
```

### Step 4 — Restart your client

Restart Claude Desktop or Cursor. Your server will appear in the tools list and the AI agent can start calling your tools immediately.

---

## Multiple servers

You can register as many MCP servers as you want in the same config file:

```json
{
    "mcpServers": {
        "analytics-server": {
            "command": "node",
            "args": ["/path/to/analytics-server/dist/index.js"]
        },
        "user-management": {
            "command": "node",
            "args": ["/path/to/user-management/dist/index.js"]
        }
    }
}
```

Each server runs as its own process. The AI agent sees all tools from all registered servers and calls the right one based on the descriptions you wrote.

---


## CLI options

You can skip some prompts by passing flags:

```bash
npx @mcp-init/create --name my-server      # skip the name prompt
npx @mcp-init/create --skip-install        # skip npm install
npx @mcp-init/create --help                # show all options
```

---

## The ecosystem

Every server created with this CLI is built on [vurb](https://npmjs.com/package/@vurb/core) and works with the full `@mcp-utils` production toolkit.

| Package | What it does |
|---|---|
| **[vurb](https://npmjs.com/package/@vurb/core)** | **The MCP framework. Foundation of every server generated by this CLI** |
| [@mcp-utils/cache](https://npmjs.com/package/@mcp-utils/cache) | Cache repeated tool calls |
| [@mcp-utils/retry](https://npmjs.com/package/@mcp-utils/retry) | Retry on transient failures |
| [@mcp-utils/pagination](https://npmjs.com/package/@mcp-utils/pagination) | Cursor-based pagination for large datasets |
| [@mcp-utils/timeout](https://npmjs.com/package/@mcp-utils/timeout) | Hard timeouts with AbortSignal chaining |
| [@mcp-utils/testing](https://npmjs.com/package/@mcp-utils/testing) | Test tool handlers without a running server |

---

## Deploying to the cloud (Vinkius Edge)

Running `node dist/index.js` locally is great for development and for connecting clients on the same machine.  
To make your MCP server **accessible from anywhere** — including remote AI agents, teammates, and cloud pipelines — deploy it to the Vinkius Edge network with a single command.

> The server runs inside a V8 isolate on Vinkius Edge. All tools defined in your project are bundled, compressed, and deployed automatically. No Docker, no servers to manage.

### Step 1 — Create a server on the dashboard

Go to **[cloud.vinkius.com](https://cloud.vinkius.com)** → **New Server** → copy the **Server ID** and the **Deploy Token** shown in the dashboard.

### Step 2 — Link your project to the cloud

Run these two commands once inside your project directory:

```bash
# Link to your cloud server
vurb remote --server-id <your-server-id>

# Save your deploy token (stored in .vurbrc, which is gitignored automatically)
vurb token <your-deploy-token>
```

Your `.vurbrc` file will look like this — **never commit it**:

```json
{
  "serverId": "abc-123-def",
  "token": "vk_live_xxxxxxxxxxxxxxxx"
}
```

### Step 3 — Deploy

```bash
vurb deploy
```

That's it. The CLI will:

1. **Bundle** your entire server with esbuild (all dependencies included)
2. **Introspect** your tools and generate a cryptographic manifest
3. **Compress** the bundle with gzip
4. **Upload** to the Vinkius Edge CDN

Output on success:

```
  Vinkius Edge  ·  analytics-server is ready in just 3.2s
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  MCP Server Stateful
  https://edge.vinkius.com/s/abc-123-def

  TOOLS  3 tools ready

    ● analytics.summary   Generate a business summary for a given period
    ● users.list          Return a paginated list of all workspace users
    ● billing.refund      Issue a refund for a specific order

  42KB → 12KB gzip (71% smaller)
  ✓ manifest signed
```

### Step 4 — Connect via URL

Use the HTTPS URL from the output above to connect any MCP-compatible client:

**Claude Desktop** (`claude_desktop_config.json`):

```json
{
    "mcpServers": {
        "analytics-server": {
            "url": "https://edge.vinkius.com/s/abc-123-def"
        }
    }
}
```

**Cursor / VS Code** (`.cursor/mcp.json` or `.vscode/mcp.json`):

```json
{
    "servers": {
        "analytics-server": {
            "url": "https://edge.vinkius.com/s/abc-123-def"
        }
    }
}
```

> The URL is permanent and survives redeployments. Every `vurb deploy` updates the code behind the same URL — no client reconfiguration needed.

### Environment variables on the Edge

Your `.env` file is **not sent** to the cloud (it's gitignored by default).  
Set environment variables through the Vinkius Cloud dashboard under **Server → Environment Variables**.

These are injected into the V8 isolate at runtime — the same `process.env.MY_API_TOKEN` calls in your generated code will work exactly as they do locally.

### Continuous deployment

Add `vurb deploy` to your CI pipeline (GitHub Actions, GitLab CI, etc.):

```yaml
# .github/workflows/deploy.yml
- name: Deploy MCP server
  run: vurb deploy
  env:
    VURB_DEPLOY_TOKEN: ${{ secrets.VURB_DEPLOY_TOKEN }}
```

---

## Requirements

- Node.js 18 or later
- npm 7 or later

---

## License

Apache-2.0