Skip to main content
Glama
berryj85

MCP Server Template

by berryj85

MCP Server Template

Bun TypeScript License: 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

Related MCP server: MCP Server Starter

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.

A
license - permissive license
-
quality - not tested
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/berryj85/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server