Skip to main content
Glama
abe-source

MCP TypeScript Boilerplate

by abe-source
README.md
<p align="center">
  <img src="assets/hero.svg" alt="mcp-typescript-boilerplate" width="100%" />
</p>

<p align="center">
  <a href="https://github.com/abe-source/mcp-typescript-boilerplate/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-4ade80.svg" alt="MIT License"></a>
  <img src="https://img.shields.io/badge/node-%3E%3D18-4ade80.svg" alt="Node >= 18">
  <img src="https://img.shields.io/badge/TypeScript-7-4ade80.svg" alt="TypeScript 7">
  <img src="https://img.shields.io/badge/MCP-server-4ade80.svg" alt="MCP Server">
</p>

# MCP TypeScript Boilerplate

A starting point for building MCP servers with the official `@modelcontextprotocol/sdk`, no wrapper framework. Extracted from a working, published server (`mcp-abuseipdb`).

## Layers

```
src/
  config.ts           env loading + validation — API key, base URL, timeout
  client.ts            generic fetch wrapper — no domain knowledge, rarely needs changes
  apiClient.ts          adds this API's auth header + error unwrapping, on top of client.ts
  endpoints/            one file per API endpoint you call — HTTP shape only
    example.ts
  tools/
    types.ts           the Tool interface every tool file implements
    example.ts          one tool: schema + handler, calls into endpoints/
    index.ts             tool registry — tools[] array
  server.ts             wires the tool registry into an McpServer instance
  index.ts               entrypoint: loadConfig() → createServer() → connect stdio transport
```

## Adapting this to a new service

1. `src/config.ts` — rename `API_KEY` to `<SERVICE>_API_KEY`, set the real `BASE_URL`
2. `src/apiClient.ts` — match the target API's auth scheme (header name, `Bearer` vs custom) and error response shape
3. `src/endpoints/` — one function per endpoint, delete `example.ts`
4. `src/tools/` — one tool per file (schema + result formatting), delete `example.ts`, register real tools in `tools/index.ts`
5. `package.json` — rename, update `bin`, description, repo URLs

## Build

```
npm install
cp .env.example .env   # fill in API_KEY
npm run build
npm start
```

## Design notes

- `client.ts` has zero domain knowledge — it should not need to change between projects
- `apiClient.ts` is the only layer that knows about auth and this API's error format
- `endpoints/` returns typed data, `tools/` formats that data as MCP `content` — don't blend the two
- stdio transport, so this works with Claude Desktop, Claude Code, and any other MCP-compatible client without extra setup

TDQS

A3.8/5.0

Scored across 1 tool

Disambiguation5/5

There is only one tool, so no ambiguity exists. An agent cannot confuse it with another tool.

Naming Consistency5/5

With a single tool, naming consistency is not a concern; there is no inconsistency to evaluate.

Tool Count4/5

As a boilerplate server, one tool is appropriate for its demonstration purpose. It is minimal but not unreasonable.

Completeness3/5

For a boilerplate, the single tool serves as an example. However, it lacks any create, update, or delete operations, which limits its completeness.

Maintenance

ActivityStale
ResponsivenessNo issues