Skip to main content
Glama
junna-legal
by junna-legal
README.md
# Production-Ready MCP Server Boilerplate

> **Ship reliable MCP servers in minutes, not days.**
> A production-ready foundation for building [Model Context Protocol](https://modelcontextprotocol.io/) servers with built-in security, authentication, and observability.

> [!NOTE]
> This is a starter template β€” not a finished product. You are responsible for reviewing and securing any code before production use.

[![TypeScript](https://img.shields.io/badge/TypeScript-Strict-blue.svg)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![MCP Compliant](https://img.shields.io/badge/MCP-Compliant-purple.svg)](https://modelcontextprotocol.io/)

**Don't build from scratch.** This kit solves the "boring" parts of MCP server developmentβ€”transport management, error handling, and security boundariesβ€”so you can focus on your tool's logic.

Works with **Claude Code**, **Cursor**, **Windsurf**, and any MCP-compatible client.

---

## πŸš€ Why this boilerplate?

Most MCP tutorials show you a "toy" server. This repo gives you a **production-grade** foundation.

### πŸ›‘οΈ Secure by Design
- **SSRF Protection:** Blocks requests to private/internal networks (IPv4 + IPv6), including cloud metadata endpoints (`169.254.169.254`). DNS resolution is checked to prevent rebinding.
- **JWT Security:** Algorithm validation rejects `alg:none`, HS384, and RS256 downgrade attacks. Expiry and tampering are verified with constant-time comparison.
- **HMAC-SHA256 Webhook Signatures:** Outbound webhooks are signed with `X-Webhook-Signature` when a secret is configured.
- **DNS Rebinding Protection:** HTTP transport validates `Host` header against an allowlist.
- **Sandboxed File Access:** Prevents AI from reading/writing outside allowed directories, with symlink escape detection.
- **Strict Input Validation:** All tool inputs are validated with **Zod** schemas.
- **Injection Protection:** SQLite queries use strict parameter binding.
- **Security tested:** 30+ security-focused test cases covering OWASP top threats (SSRF, injection, path traversal, auth bypass).

### πŸ”Œ Built for Real Projects
- **Authentication:** Built-in strategies for **API Key** and **JWT** (configurable per env).
- **Rate Limiting:** Token bucket algorithm to prevent abuse.
- **Observability:** Structured JSON logging (via `pino`) ready for CloudWatch/Datadog.

### ⚑ Developer Experience (DX)
- **Type-Safe:** `strict: true` TypeScript configuration, ESM, fully typed.
- **Testing:** 228 tests (unit, integration, and E2E) with **Vitest**, including 30+ security-focused cases.
- **Dockerized:** Multi-stage Dockerfile for immediate deployment.

---

## πŸ“¦ What's Included

| Feature | This Boilerplate | Basic Tutorials |
| :--- | :--- | :--- |
| **Transport** | **HTTP (SSE) + Stdio** | Stdio only |
| **Validation** | **Zod Schemas** | Manual / None |
| **Logging** | **Structured JSON** | `console.log` |
| **Error Handling** | **Graceful + MCP Codes** | Process crash |
| **CI/CD** | **GitHub Actions** | None |

### Reference Implementations
Includes 6 fully-typed tools to copy-paste patterns from:
1.  **`database-query`**: Secure SQLite operations.
2.  **`api-connector`**: Fetch data from external REST APIs.
3.  **`file-manager`**: Safe file system operations (5 sub-tools).
4.  **`cache-store`**: TTL-based key-value cache with namespaces (5 sub-tools).
5.  **`semantic-search`**: Local RAG with embeddings (3 tools + 2 resources + 1 prompt).
6.  **`webhook-notifier`**: Async webhook delivery with task tracking (4 tools + 2 resources + 1 prompt).

---

## 🏁 Quick Start

### Prerequisites
- Node.js 22+
  > **WSL2 users:** Use Node.js installed inside WSL, not Windows. See [Troubleshooting](docs/TROUBLESHOOTING.md#13-wsl2-npm-install-fails-with-eperm).
- npm 9+

### 1. Setup
```bash
git clone <your-repo-url> my-mcp-server
cd my-mcp-server
npm install
```

### 2. Configure Environment
```bash
cp .env.example .env
# Edit .env if needed β€” defaults work out of the box
```

### 3. Seed Sample Database
```bash
npm run db:seed  # Populates local SQLite for testing
```

> **Note:** If the server is already running, restart it after seeding to pick up the new database.

### 4. Build
```bash
npm run build  # Compiles TypeScript to dist/
```

### 5. Run Development Server
```bash
npm run dev
# Starts server in hot-reload mode
```

### 6. Verify with Inspector
```bash
npm run inspector
# Opens interactive debugger in your browser (uses dist/index.js)
```

---

## πŸ”§ Connecting to Clients

### Claude Code
Copy the example config to your project root:

```bash
cp .mcp.json.example .mcp.json
# Edit paths in .mcp.json to match your setup
```

Or add manually to your `.mcp.json`:

```json
{
  "mcpServers": {
    "mcp-starter-kit": {
      "command": "node",
      "args": ["dist/index.js"],
      "env": {
        "LOG_LEVEL": "info",
        "DB_PATH": "./data/sample.db",
        "SANDBOX_ROOT": "./data/sandbox"
      }
    }
  }
}
```

### Claude Desktop
Add to your `claude_desktop_config.json`:

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

### Cursor, Windsurf, & Others
See [docs/SETUP.md](docs/SETUP.md) for detailed connection guides.

---

## πŸ“‚ Project Architecture

Designed for scalability:

```
mcp-starter-kit/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts              # Entry point
β”‚   β”œβ”€β”€ server.ts             # Central MCP registry
β”‚   β”œβ”€β”€ config/env.ts         # Environment variable validation (Zod)
β”‚   β”œβ”€β”€ tools/
β”‚   β”‚   β”œβ”€β”€ database-query/   # SQLite CRUD tool
β”‚   β”‚   β”œβ”€β”€ api-connector/    # REST API tool
β”‚   β”‚   β”œβ”€β”€ file-manager/     # Sandboxed file operations tool
β”‚   β”‚   β”œβ”€β”€ cache-store/      # TTL-based key-value cache
β”‚   β”‚   β”œβ”€β”€ semantic-search/  # Local RAG with embeddings
β”‚   β”‚   └── webhook-notifier/ # Async webhook delivery
β”‚   β”œβ”€β”€ lib/                  # Shared utilities (Logger, Guardrails)
β”‚   β”œβ”€β”€ middleware/            # Auth & rate limiting
β”‚   └── transport/            # stdio and HTTP transports
β”œβ”€β”€ tests/                    # Integration tests & helpers
β”œβ”€β”€ scripts/                  # CLI tools (db:seed, create-tool)
β”œβ”€β”€ docs/                     # Detailed documentation
β”œβ”€β”€ docker/                   # Dockerfile & docker-compose
└── data/                     # Sample DB & sandbox directory
```

---

## πŸ“œ Documentation

| Document | Description |
|----------|-------------|
| [SETUP.md](docs/SETUP.md) | Detailed setup, environment variables, client configuration |
| [CUSTOMIZATION.md](docs/CUSTOMIZATION.md) | Step-by-step guide to creating new tools |
| [DEPLOYMENT.md](docs/DEPLOYMENT.md) | Deploy via npm, Docker, or cloud services |
| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | Design decisions, security model, and data flow |
| [TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) | Common errors and solutions |
| [TESTING.md](docs/TESTING.md) | Test suite organization, writing tests, security checklist |
| [SECURITY.md](SECURITY.md) | Security policy, vulnerability reporting, feature inventory |

---

## πŸ› οΈ Scripts

| Command | Description |
|---------|-------------|
| `npm run dev` | Start with hot-reload (tsx watch) |
| `npm run build` | Build to `dist/` (tsup) |
| `npm start` | Run built server (stdio) |
| `npm run start:http` | Run built server (HTTP) |
| `npm test` | Run all tests |
| `npm run lint` | Lint with ESLint |
| `npm run typecheck` | Type-check with tsc |
| `npm run inspector` | Open MCP Inspector |
| `npm run db:seed` | Seed sample SQLite database |
| `npm run create-tool` | Scaffold a new tool |
| `npm run test:coverage` | Run tests with coverage report |

---

## License

MIT Β© 2026 Edge Craft Studio

Not affiliated with, endorsed by, or certified by Anthropic or the Agentic AI Foundation.

TDQS

A3.5/5.0

Scored across 15 tools

Disambiguation5/5

Each tool targets a distinct resource and action, with clear boundaries between file, database, cache, semantic, webhook, and task operations. The only minor overlap is task_status handling both get and update, but the description clearly separates these behaviors, so no two tools appear to do the same thing.

Naming Consistency2/5

Naming conventions are mixed: some tools use hyphens (database-query, api-connector), others use underscores (file_read, task_status), and one is a single word (cache). The word order is also inconsistent, with most tools using noun_verb (file_read) but api-connector using a noun-noun pattern, and no uniform separator across the set.

Tool Count4/5

With 15 tools, the server sits at the upper boundary of a reasonable scope for a starter kit. Each tool covers a distinct capability, but the sheer variety (files, database, cache, semantic search, webhooks, tasks) makes it feel slightly broad, yet still justifiable for its purpose.

Completeness3/5

The tool surface covers core operations for each domain, but there are notable gaps: no file_delete or file_rename, no webhook_unregister, and no task_cancel or task_delete. These are common lifecycle operations that agents would likely need, making the set somewhat incomplete.

Maintenance

ActivityInactive
ResponsivenessNo issues