Skip to main content
Glama
dao-genesis

MCP Server Starter

by dao-genesis
README.md
# MCP Server Starter (TypeScript)

A **production-ready starter kit** for building [Model Context Protocol](https://modelcontextprotocol.io) (MCP) servers in TypeScript. Clone it, add your tools, ship. Everything you'd otherwise spend a day wiring up is already here:

- ✅ **Typed, validated config** from environment variables (zod) — fails fast on bad input
- ✅ **Clean modular structure** for tools, resources and prompts — add a file, register it, done
- ✅ **Three reference tools** (`echo`, `calculator`, `fetch_url`) showing input validation, error handling, and safe network I/O with a timeout + host allowlist
- ✅ **Resource and prompt examples** wired end to end
- ✅ **stderr-only structured logger** (never corrupts the stdio JSON-RPC stream — a common footgun)
- ✅ **Full test suite** (Vitest) including an **in-memory client↔server round-trip** test
- ✅ **Docker** multi-stage build and **GitHub Actions CI** across Node 18/20/22
- ✅ **Graceful shutdown** on SIGINT/SIGTERM
- ✅ MIT licensed — use it in commercial projects freely

## Quick start

```bash
npm install
npm run build
npm start          # runs the MCP server over stdio
```

Develop with hot reload:

```bash
npm run dev
```

Run the test suite and type checks:

```bash
npm test
npm run typecheck
```

Inspect it interactively with the official MCP Inspector:

```bash
npm run inspect
```

## Use it with Claude Desktop / any MCP client

After `npm run build`, add this to your client's MCP config (e.g. Claude Desktop's `claude_desktop_config.json`):

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

## Project layout

```
src/
  index.ts          # entrypoint: loads config, wires stdio transport, handles shutdown
  server.ts         # builds the McpServer and registers everything
  config.ts         # zod-validated environment config
  logger.ts         # structured stderr logger
  tools/            # one file per tool + a registrar (index.ts)
  resources/        # read-only content exposed to the client
  prompts/          # reusable prompt templates
test/               # vitest unit + end-to-end tests
Dockerfile          # multi-stage production image
.github/workflows/  # CI
```

## Add your own tool

1. Create `src/tools/myTool.ts` exporting a `ToolModule` (copy `echo.ts`).
2. Add it to the `tools` array in `src/tools/index.ts`.
3. Add a test in `test/tools.test.ts`.

That's the whole loop. The `ToolModule` type keeps the input schema, metadata and handler together and type-checked.

## Configuration

All settings are optional and read from the environment (see `.env.example`):

| Variable | Default | Description |
| --- | --- | --- |
| `MCP_SERVER_NAME` | `mcp-server-starter` | Name reported to clients |
| `MCP_SERVER_VERSION` | `1.0.0` | Version reported to clients |
| `LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` |
| `HTTP_TIMEOUT_MS` | `10000` | Timeout for the `fetch_url` tool |
| `ALLOWED_FETCH_HOSTS` | *(empty = all)* | Comma-separated host allowlist for `fetch_url` |

## Docker

```bash
docker build -t mcp-server-starter .
docker run --rm -i mcp-server-starter
```

## License

MIT — see [LICENSE](./LICENSE).