MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

MCP server by v-checha

Created 12/9/2025
Updated 4 days ago
Repository documentation and setup instructions

MCPKit

npm version License: MIT

Developer-friendly toolkit for building Model Context Protocol (MCP) servers with minimal boilerplate.

MCPKit provides a decorator-based, type-safe API for creating MCP servers that work with Claude, ChatGPT, Cursor, and other AI assistants.

Features

  • Decorator-based API - Clean, declarative syntax with @MCPServer, @Tool, @Resource, @Prompt, and @Param
  • Type-safe - Full TypeScript support with automatic type inference
  • Multiple transports - Support for stdio, HTTP/SSE, and Streamable HTTP
  • CLI tooling - Project scaffolding and development tools
  • Testing utilities - Mock clients and helpers for testing your servers
  • Zod integration - Runtime validation with automatic JSON Schema generation
  • MCP SDK compatible - Built on top of the official @modelcontextprotocol/sdk

Packages

| Package | Description | |-------------------------------------------|--------------------------------------| | @mcpkit-dev/core | Core decorators and server framework | | @mcpkit-dev/cli | CLI tool for project scaffolding | | @mcpkit-dev/testing | Testing utilities and mock clients |

Quick Start

Using the CLI (Recommended)

# Install the CLI globally
npm install -g @mcpkit-dev/cli

# Create a new project
mcpkit init my-server

# Navigate and start development
cd my-server
npm run dev

Manual Installation

npm install @mcpkit-dev/core zod
import {MCPServer, Tool, Param} from '@mcpkit-dev/core';

@MCPServer({
    name: 'my-server',
    version: '1.0.0',
})
class MyServer {
    @Tool({description: 'Greet someone by name'})
    async greet(
        @Param({description: 'Name to greet'}) name: string
    ): Promise<string> {
        return `Hello, ${name}!`;
    }
}

// Start the server
const server = new MyServer();
await server.listen();

Decorators

@MCPServer

Class decorator that marks a class as an MCP server.

@MCPServer({
    name: 'weather-server',
    version: '1.0.0',
    description: 'Get weather information',
})
class WeatherServer {}

@Tool

Method decorator that exposes a method as an MCP tool.

// Using @Param decorators
@Tool({ description: 'Get current weather' })
async getWeather(
  @Param({ name: 'city', description: 'City name' }) city: string,
  @Param({ name: 'unit', optional: true }) unit?: 'celsius' | 'fahrenheit',
): Promise<WeatherData> {
  // implementation
}

// Using explicit Zod schema
@Tool({
  description: 'Get forecast',
  schema: z.object({
    city: z.string(),
    days: z.number().min(1).max(7),
  }),
})
async getForecast(args: { city: string; days: number }) {
  // implementation
}

@Param

Parameter decorator for tool and prompt arguments.

@Param({
    name: 'city',           // Optional - defaults to parameter name
    description: 'City',    // Optional - shown to AI
    schema: z.string(),     // Optional - explicit Zod schema
    optional: true,         // Optional - is parameter optional?
})

@Resource

Method decorator that exposes data as an MCP resource.

// URI template with parameters
@Resource('weather://cities/{city}/current')
async getCityWeather(city: string) {
    return {
        contents: [{
            uri: `weather://cities/${city}/current`,
            mimeType: 'application/json',
            text: JSON.stringify({ temperature: 22 }),
        }],
    };
}

// Static resource with options
@Resource({
    uri: 'docs://readme',
    name: 'README',
    mimeType: 'text/markdown',
})
async getReadme() {
    return { contents: [{ uri: 'docs://readme', text: '# README' }] };
}

@Prompt

Method decorator for reusable prompt templates.

@Prompt({ description: 'Generate a weather report' })
async weatherReport(
    @Param({ name: 'city' }) city: string,
) {
    return {
        messages: [{
            role: 'user',
            content: { type: 'text', text: `Write a weather report for ${city}` },
        }],
    };
}

@Monitor

Method decorator for per-method monitoring and logging.

@Tool({ description: 'Process important data' })
@Monitor({
    logArgs: true,      // Log input arguments
    logResult: true,    // Log return value
    logDuration: true,  // Log execution time (default: true)
    logErrors: true,    // Log errors (default: true)
    logger: customLogger, // Optional custom logger
})
async processData(@Param({ name: 'data' }) data: string) {
    return `Processed: ${data}`;
}

Note: @Monitor only works when hooks are configured on @MCPServer.

Lifecycle Hooks

Add logging, monitoring, and observability to your server with hooks:

import { MCPServer, Tool, Param, type ServerHooks } from '@mcpkit-dev/core';

@MCPServer({
    name: 'monitored-server',
    version: '1.0.0',
    hooks: {
        // Whether to await hook execution (default: true)
        awaitHooks: true,

        // Server lifecycle
        // Note: Use console.error (stderr) for logging - stdout is reserved for MCP protocol
        onServerStart: () => console.error('Server started'),
        onServerStop: () => console.error('Server stopped'),

        // Tool hooks
        onToolCall: ({ toolName, args }) => {
            console.error(`Tool ${toolName} called with`, args);
        },
        onToolSuccess: ({ toolName, duration, result }) => {
            console.error(`Tool ${toolName} completed in ${duration}ms`);
        },
        onToolError: ({ toolName, error, duration }) => {
            console.error(`Tool ${toolName} failed after ${duration}ms:`, error.message);
        },

        // Resource hooks
        onResourceRead: ({ uri }) => console.error(`Reading resource: ${uri}`),
        onResourceSuccess: ({ uri, duration }) => console.error(`Resource read in ${duration}ms`),
        onResourceError: ({ uri, error }) => console.error(`Resource error: ${uri}`, error),

        // Prompt hooks
        onPromptGet: ({ promptName }) => console.error(`Getting prompt: ${promptName}`),
        onPromptSuccess: ({ promptName, duration }) => console.error(`Prompt ready in ${duration}ms`),
        onPromptError: ({ promptName, error }) => console.error(`Prompt error:`, error),
    },
})
class MonitoredServer {
    @Tool({ description: 'Example tool' })
    async example(@Param({ name: 'input' }) input: string) {
        return `Result: ${input}`;
    }
}

Transport Options

MCPKit supports multiple transport protocols:

stdio (Default)

Standard input/output transport for CLI tools and Claude Desktop integration.

const server = new MyServer();
await server.listen(); // Uses stdio by default

Streamable HTTP (Recommended for Web)

Modern HTTP transport with session support and SSE streaming.

const server = new MyServer();
await server.listen({
    transport: 'streamable-http',
    port: 3000,
    host: 'localhost',
    path: '/mcp',
});
// Server available at http://localhost:3000/mcp

SSE (Legacy HTTP)

Server-Sent Events transport for backward compatibility.

const server = new MyServer();
await server.listen({
    transport: 'sse',
    port: 3000,
    host: 'localhost',
    ssePath: '/sse',
    messagePath: '/message',
});

CLI Tool

The @mcpkit-dev/cli package provides project scaffolding and development tools.

npm install -g @mcpkit-dev/cli

Commands

# Create a new project
mcpkit init [name]
  --template <template>  Template to use (basic, advanced)
  --no-git              Skip git initialization
  --no-install          Skip installing dependencies

# Start development server
mcpkit dev
  --port <port>         Port for HTTP transport (default: 3000)
  --transport <type>    Transport type (stdio, http, streamable-http)
  --watch               Watch for file changes (default: true)

# Build for production
mcpkit build
  --output <dir>        Output directory (default: dist)

Testing

The @mcpkit-dev/testing package provides utilities for testing MCP servers.

npm install -D @mcpkit-dev/testing

Mock Client

import {MockMcpClient} from '@mcpkit-dev/testing';
import {bootstrapServer, MetadataStorage} from '@mcpkit-dev/core';

describe('MyServer', () => {
    it('should greet users', async () => {
        // Create mock client
        const {client, serverTransport} = MockMcpClient.create();

        // Bootstrap server with test transport
        const instance = new MyServer();
        const options = MetadataStorage.getServerOptions(MyServer);
        const server = await bootstrapServer(instance, options!);
        await server.server.connect(serverTransport);
        await client.connect();

        // Test the tool
        const result = await client.callTool('greet', {name: 'World'});
        expect(result.content[0].text).toBe('Hello, World!');

        // Cleanup
        await client.close();
        await server.close();
    });
});

In-Memory Transport

import {InMemoryTransport} from '@mcpkit-dev/testing';

const {clientTransport, serverTransport} = InMemoryTransport.createPair();
// Use transports for direct client-server communication

Using with Claude Desktop

Add your server to Claude Desktop's configuration (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": [
        "/path/to/your/server/dist/index.js"
      ]
    }
  }
}

TypeScript Configuration

MCPKit requires the following TypeScript settings:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext"
  }
}

Examples

See the examples directory for complete working examples:

API Reference

Listen Options

interface ListenOptions {
    transport?: 'stdio' | 'http' | 'sse' | 'streamable-http';
    port?: number;           // HTTP port (default: 3000)
    host?: string;           // HTTP host (default: 'localhost')
    path?: string;           // Streamable HTTP endpoint path
    ssePath?: string;        // SSE stream path
    messagePath?: string;    // SSE message path
    stateless?: boolean;     // Disable session management
    enableJsonResponse?: boolean; // Use JSON instead of SSE
    onSessionInitialized?: (sessionId: string) => void;
    onSessionClosed?: (sessionId: string) => void;
}

Server Instance

interface BootstrappedServer {
    server: McpServer;        // Underlying MCP server
    transport: Transport;     // Active transport
    connect(): Promise<void>; // Start the server
    close(): Promise<void>;   // Stop the server
}

Requirements

  • Node.js 18+
  • TypeScript 5.0+

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting a PR.

License

MIT

Quick Setup
Installation guide for this server

Install Package (if required)

npx @modelcontextprotocol/server-mcpkit

Cursor configuration (mcp.json)

{ "mcpServers": { "v-checha-mcpkit": { "command": "npx", "args": [ "v-checha-mcpkit" ] } } }