MCP Server Template

berryj85/mcp-server
0 starsMITCommunity

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

A production-ready template for building Model Context Protocol servers using TypeScript and Bun runtime, including schema validation, structured logging, and retry utilities.

README.md

MCP Server Template

![Bun](https://bun.sh/) ![TypeScript](https://www.typescriptlang.org/) ![License: MIT](https://opensource.org/licenses/MIT)

Production-ready MCP server template for building Model Context Protocol servers with TypeScript and Bun runtime.

What is this?

This is a template project for creating MCP servers. It includes:

  • TypeScript with strict type checking
  • Bun runtime for fast execution
  • Zod schema validation
  • Structured logging (stderr only)
  • Retry utilities with exponential backoff
  • Unit and integration test setup
  • Production-ready error handling

Installation

bun install

Quick Start

# Start the MCP server
bun run start

# Development with hot reload
bun run dev

MCP Configuration

Add to your MCP client configuration:

{
  "mcpServers": {
    "mcp-server-template": {
      "command": "bun",
      "args": ["run", "/path/to/mcp-server-template/src/server.ts"]
    }
  }
}

Or use the built version:

{
  "mcpServers": {
    "mcp-server-template": {
      "command": "node",
      "args": ["/path/to/mcp-server-template/dist/server.js"]
    }
  }
}

Adding Tools

1. Define Schema

In src/types/index.ts:

import { z } from "zod";

export const MyToolInputSchema = z.object({
  param1: z.string().min(1).describe("Parameter description"),
  param2: z.number().optional().describe("Optional parameter"),
});

export type MyToolInput = z.infer<typeof MyToolInputSchema>;

2. Add Tool Definition

In src/tools/index.ts:

export const toolDefinitions = [
  {
    name: "my_tool",
    description: "Description of what the tool does",
    inputSchema: {
      type: "object" as const,
      properties: {
        param1: { type: "string", description: "Parameter description" },
        param2: { type: "number", description: "Optional parameter" },
      },
      required: ["param1"],
    },
  },
];

3. Implement Handler

export async function handleMyTool(input: unknown): Promise<CallToolResult> {
  try {
    const validated = MyToolInputSchema.parse(input);
    log.info('Executing tool', { tool: 'my_tool', params: validated });
    
    // Your logic here
    const result = { data: "..." };
    
    log.info('Tool completed', { tool: 'my_tool', success: true });
    return createSuccessResult(result);
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    return createErrorResult(message, "my_tool");
  }
}

4. Add to Router

export async function handleToolCall(name: string, args: unknown): Promise<CallToolResult> {
  switch (name) {
    case "my_tool":
      return handleMyTool(args);
    default:
      return createErrorResult(`Unknown tool: ${name}`, name);
  }
}

5. Write Tests

Create tests/unit/my_tool.test.ts:

import { describe, test, expect } from "bun:test";
import { handleMyTool } from "../../src/tools/index.js";

describe("My Tool", () => {
  test("should work correctly", async () => {
    const result = await handleMyTool({ param1: "test" });
    expect(result.isError).toBe(false);
  });
});

6. Document Tool

Create docs/tools/my_tool.md:

# my_tool

Description of what the tool does.

## Parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| param1 | string | Yes | Description |

## Examples

**Input:**
\`\`\`json
{ "param1": "value" }
\`\`\`

**Output:**
\`\`\`json
{ "data": "result" }
\`\`\`

Available Scripts

| Script | Description | |--------|-------------| | bun run dev | Start development server with hot reload | | bun run build | Build for production | | bun run start | Run production build | | bun test | Run unit tests | | bun run test:coverage | Run tests with coverage | | bun run test:runtime | Run runtime testcases | | bun run lint | Run Biome linter | | bun run lint:fix | Auto-fix lint issues | | bun run format | Format code with Biome | | bun run typecheck | Type check without emit |

Configuration

Environment Variables

  • DEBUG=true - Enable debug logging

Troubleshooting

Server won't start

  • Ensure Bun is installed: bun --version
  • Check TypeScript errors: bun run typecheck

Tool execution fails

  • Check input schema matches the tool definition
  • Enable debug mode: DEBUG=true bun run start

Development

See DEVELOPMENT.md for development setup.

License

MIT License - see LICENSE for details.

Related MCP servers

Browse all →