npm package: @magneticwatermelon/mcp-toolkit
Description: Build and ship **[Model Context Protocol](https://github.com/modelcontextprotocol)** (MCP) servers with zero-config ⚡️.
Latest version: 2.0.1

# MCP Toolkit

Build and ship **[Model Context Protocol](https://github.com/modelcontextprotocol)** (MCP) servers with zero-config ⚡️.

`mcp-toolkit` is a TypeScript + Bun toolkit that gives you everything you need to:

* scaffold an MCP server project in seconds
* declare type-safe Tools, Resources and Prompts with [Zod](https://github.com/colinhacks/zod)
* expose your server over stdio or streaming HTTP (with optional CORS & auth)
* bundle, validate and publish your project – all from one cohesive CLI

---

## Table of contents

- [MCP Toolkit](#mcp-toolkit)
  - [Table of contents](#table-of-contents)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
  - [Quick start](#quick-start)
    - [1. Scaffold a new project](#1-scaffold-a-new-project)
    - [2. Install \& build](#2-install--build)
    - [3. Run the server](#3-run-the-server)
  - [CLI reference](#cli-reference)
  - [Project structure](#project-structure)
  - [Authoring Tools](#authoring-tools)
  - [Prompts \& Resources](#prompts--resources)
  - [Server API](#server-api)
  - [Transports \& Auth](#transports--auth)
    - [http-stream (default)](#http-stream-default)
    - [stdio](#stdio)
  - [Environment variables](#environment-variables)
  - [Testing](#testing)
  - [Contributing](#contributing)
  - [License](#license)

---

## Prerequisites

`mcp-toolkit` is developed and tested with **Bun ≥ 1.2**. Make sure you have it installed:

```bash
bun --version # ≥ 1.2.x
```

( Node ≥ 18 is only required for types but the runtime is **Bun**.)

---

## Installation

Install the CLI globally (recommended):

```bash
bun add -g mcp-toolkit   # installs "mcp-toolkit" binary
```

or use `bunx` for one-off invocations:

```bash
bunx mcp-toolkit <command> [...options]
```

---

## Quick start

### 1. Scaffold a new project

```bash
mcp-toolkit create my-mcp-server --port 3000 --cors
cd my-mcp-server
```

Flags explained:

* `--http`    Generate HTTP streaming transport (defaults to http-stream)
* `--port`    Port to listen on (default **8080**)
* `--cors`    Allow any origin (for browsers / local dev)

### 2. Install & build

```bash
bun install       # installs deps
bun run build     # compiles TS ➜ dist & bundles tools/prompts
```

### 3. Run the server

```bash
bun run src/index.ts     # dev (ts-node style)
# — or —
bun run start            # prod (dist/index.js)
```

You now have a fully-functional MCP server exposing an example `example_tool` 🎉

---

## CLI reference

`mcp-toolkit` ships with the following sub-commands:

| Command                      | Description |
| ---------------------------- | ----------- |
| `create <name>`              | Scaffold a new MCP server project |
| `add-tool <name>`            | Generate a Typed **Tool** in `src/tools/` |
| `add-resource <name>`        | Generate a **Resource** handler |
| `add-prompt <name>`          | Generate a **Prompt** definition |
| `build`                      | Bundle & validate the project before publishing |
| `--help`, `--version`        | Display help / version |

Each generator asks the minimum number of questions and creates fully-typed stubs.

---

## Project structure

A freshly created project looks like this:

```text
my-mcp-server/
├─ src/
│  ├─ tools/           # Your Tool classes live here
│  ├─ prompts/         # Prompt files
│  ├─ resources/       # Resource handlers (files, db, etc.)
│  └─ index.ts         # Entry point – configures & starts MCPServer
├─ dist/               # Populated by `bun run build`
├─ package.json        # Generated with ready-to-use scripts
└─ tsconfig.json       # Strict compiler settings
```

Feel free to modify the layout; loaders perform a recursive search.

---

## Authoring Tools

```ts
// src/tools/GreetTool.ts
import { MCPTool } from "mcp-toolkit";
import { z } from "zod";

const GreetSchema = z.object({
  name: z.string().describe("Name to greet"),
  age: z.number().optional().describe("Age of the person"),
  formal: z.boolean().default(false).describe("Use formal greeting"),
});

export default class GreetTool extends MCPTool<any, typeof GreetSchema> {
  name = "greet";
  description = "Return a friendly greeting";
  protected schema = GreetSchema;

  async execute(input: z.infer<typeof GreetSchema>) {
    const { name, age, formal } = input;
    const greeting = formal ? "Good day" : "Hello";
    const ageText = age ? ` (age ${age})` : "";
    return `${greeting} ${name}${ageText}! 👋`;
  }
}
```

### Type Support

MCP Toolkit supports all common Zod types with automatic JSON Schema generation:

* **Basic types**: `string`, `number`, `boolean`, `date`
* **Advanced types**: `array`, `object`, `enum`, `literal`, `union`
* **Modifiers**: `optional()`, `nullable()`, `default(value)`
* **Constraints**: string length, number ranges, regex patterns
* **Nested objects**: Full support for complex nested schemas

**Key features**:
* **Zod powered**: All fields require `.describe()` so generated JSON-Schema is LLM-friendly
* **Type coercion**: Automatic conversion of string inputs to numbers, booleans, and dates  
* **Strong typing**: Full TypeScript inference from schema to execution
* **Validation**: Runtime validation with helpful error messages

Registering happens automatically – just export default your class.

---

## Prompts & Resources

* **Prompt**: A reusable chat template that returns an array of `messages` (system, user, etc.).
* **Resource**: Long-lived data streams such as log files or database rows that can be subscribed to.

Generators (`add-prompt`, `add-resource`) provide a skeleton; fill in the logic and you are good to go.

---

## Server API

```ts
import { MCPServer } from "mcp-toolkit";

const server = new MCPServer({
  name: "my-mcp-server",          // defaults to package.json name
  version: "1.0.0",               // defaults to package.json version
  basePath: process.cwd(),         // root used by loaders
  transport: {
    type: "http-stream",          // "stdio" | "http-stream"
    options: {
      port: 3000,
      cors: { allowOrigin: "*" }
    }
  }
});

await server.start();
```

See the inline docs (`src/core/server.ts`) for every option and capability flag.

---

## Transports & Auth

### http-stream (default)

Exposes a streaming endpoint compatible with the MCP HTTP spec:

```
POST /mcp
Content-Type: application/json
Authorization: Bearer <token>
```

Auth strategies are pluggable. Pass an `auth` block when initialising the transport or configure the built-in bearer token middleware via environment variables.

### stdio

Best for embedding the MCP server as a child process managed by the LLM runtime.

---

## Environment variables & Secrets Management

`mcp-toolkit` provides ergonomic secrets management for your MCP servers:

### Quick Start

```bash
# In your MCP project directory
mcp-toolkit env init           # Initialize secrets configuration
mcp-toolkit env add API_KEY    # Add a new secret interactively
mcp-toolkit env generate       # Generate .env files
```

### Commands

| Command | Description |
| ------- | ----------- |
| `mcp-toolkit env init` | Initialize secrets configuration |
| `mcp-toolkit env add <name>` | Add a new secret with type validation |
| `mcp-toolkit env remove <name>` | Remove a secret |
| `mcp-toolkit env list` | List all configured secrets |
| `mcp-toolkit env generate` | Generate .env files from configuration |

### Secret Types

- **`string`**: Generic string values
- **`number`**: Numeric values with validation
- **`boolean`**: Boolean values (true/false, 1/0, yes/no)
- **`url`**: URLs with format validation
- **`api_key`**: API keys with security checks

### Framework Environment Variables

| Name             | Purpose |
| ---------------- | ------- |
| `MCP_LOG_FILE`   | Path to a file where **safe** logs are written |
| `MCP_SKIP_VALIDATION` | Skip JSON-Schema validation during build |

### Using Secrets in Your Code

```typescript
// Basic usage
const apiKey = process.env.API_KEY;

// With type-safe getter (coming soon)
const getEnv = createEnvGetter(secrets);
const port = getEnv('PORT', 8080); // number type with default
```

---

## Testing

Because the runtime is **Bun**, you can use the built-in `bun test` command or any test runner that supports ESM. The utilities under `src/tests/` illustrate mocking transports and asserting Tool outputs.

---

## Contributing

1. Fork & clone the repository.
2. `bun install` then `bun run watch` to rebuild on change.
3. Submit a pull request – discussions are welcomed in issues.

Please follow the conventional commit format; the CI will lint & test your patch.

---

## License

MIT © 2024 — [Your Name](https://github.com/your-handle)