Skip to main content
Glama
EuKennedy

mcpkit

by EuKennedy

mcpkit

ci release license node

Das TypeScript-Toolkit zum Erstellen von MCP-Servern ohne Boilerplate.

Definieren Sie ein Tool mit einem Zod-Schema und einem Handler. Sie erhalten einen funktionierenden Model Context Protocol-Server zurück — Schema-Generierung, Eingabevalidierung, Fehler-Envelopes, Transport-Verkabelung, alles erledigt.

import { defineServer, defineTool } from 'mcpkit';
import { z } from 'zod';

const server = defineServer({
  name: 'demo',
  version: '0.1.0',
  tools: [
    defineTool({
      name: 'add',
      description: 'Add two numbers.',
      input: z.object({ a: z.number(), b: z.number() }),
      handler: ({ a, b }) => `${a + b}`,
    }),
  ],
});

await server.start();

Das ist ein echter, funktionierender MCP-Server. Führen Sie ihn mit mcpkit dev aus und verbinden Sie einen beliebigen MCP-fähigen Client damit.


warum es das gibt

Das Schreiben eines MCP-Servers mit dem offiziellen SDK ist in Ordnung, aber man erledigt jedes Mal dieselbe Routinearbeit:

  • Deklarieren der Tool-Liste an einer Stelle

  • Deklarieren eines separaten JSON-Schemas für jedes Tool

  • Schreiben eines Switch-Statements über Tool-Namen im Call-Handler

  • Umwandeln von Handler-Rückgaben in das Content-Envelope des Protokolls

  • Verkabelung eines Transports

  • Abfangen von Fehlern und Konvertieren in die richtige isError-Form

mcpkit fasst all das in defineTool + defineServer zusammen. Das Schema wird aus Ihrem Zod-Typ generiert, die Validierung läuft vor Ihrem Handler, Fehler werden zu korrekten Protokollantworten und eine String-Rückgabe wird zu einem Text-Content-Block. Sie bleiben in der Schicht, die tatsächlich wichtig ist — was das Tool tut — und überspringen die Schicht, die es nicht ist.

Related MCP server: MCP Base Server

mit vs ohne

Dasselbe Tool, geschrieben mit dem nackten SDK und mit mcpkit:

const server = new Server(
  { name: 'demo', version: '0.1.0' },
  { capabilities: { tools: {} } },
);

server.setRequestHandler(
  ListToolsRequestSchema,
  async () => ({
    tools: [
      {
        name: 'add',
        description: 'Add two numbers.',
        inputSchema: {
          type: 'object',
          properties: {
            a: { type: 'number' },
            b: { type: 'number' },
          },
          required: ['a', 'b'],
        },
      },
    ],
  }),
);

server.setRequestHandler(
  CallToolRequestSchema,
  async (req) => {
    if (req.params.name === 'add') {
      const { a, b } = req.params.arguments as {
        a: number; b: number;
      };
      return {
        content: [{ type: 'text', text: `${a + b}` }],
      };
    }
    throw new Error('unknown tool');
  },
);

await server.connect(new StdioServerTransport());
const server = defineServer({
  name: 'demo',
  version: '0.1.0',
  tools: [
    defineTool({
      name: 'add',
      description: 'Add two numbers.',
      input: z.object({
        a: z.number(),
        b: z.number(),
      }),
      handler: ({ a, b }) => `${a + b}`,
    }),
  ],
});

await server.start();

Die rechte Spalte hat dasselbe Verhalten auf Protokollebene, plus Eingabevalidierung, plus typisierte Handler-Argumente, plus ein isError-Envelope bei nicht abgefangenen Fehlern.

installation

npm install mcpkit zod

Oder erstellen Sie ein neues Projekt (empfohlen für den ersten Server):

npx mcpkit create my-server
cd my-server
npm run dev

Sie erhalten ein kleines Projekt mit einem funktionierenden stdio-Server, drei Beispiel-Tools und einer tsconfig.json, die für den Strict-Modus konfiguriert ist. Ersetzen Sie die Beispiel-Tools durch Ihre eigenen und veröffentlichen Sie es.

die cli

mcpkit create [target]   scaffold a new server from a template
mcpkit dev               run with hot reload (uses tsx under the hood)
mcpkit build             compile to dist/
mcpkit inspect           launch the official inspector against your server

create wird derzeit mit vier Vorlagen ausgeliefert:

Vorlage

was Sie erhalten

stdio-basic

lokaler MCP-Server über stdio. Die meisten Clients benötigen dies.

http-streaming

netzwerkfähiger Server über den streamfähigen HTTP-Transport.

with-fetch

stdio-Server mit HTTP-Fetch-Tools (Timeouts vorkonfiguriert).

with-sqlite

stdio-Server mit einem SQLite-basierten CRUD-Beispiel (better-sqlite3, WAL).

die api

defineTool

defineTool({
  name: string,            // [a-zA-Z0-9_-]+
  description: string,     // shown to the client / LLM
  input: z.ZodType,        // Zod schema; converted to JSON Schema for you
  handler: (input) => string | ToolContent | ToolContent[] | { content, isError? }
})

Die Handler-Eingabe ist vollständig über z.infer typisiert. Die Rückgabe eines Strings verpackt diesen als einzelnen Text-Content-Block — das ist der Standardfall. Das Werfen eines Fehlers innerhalb eines Handlers wird automatisch in eine isError: true-Antwort umgewandelt; wenn Sie die Fehlermeldung anpassen möchten, übergeben Sie einen onToolError-Handler an defineServer.

defineServer

defineServer({
  name: string,
  version: string,
  description?: string,
  tools?: ToolDefinition[],
  resources?: ResourceDefinition[],
  prompts?: PromptDefinition[],
  onToolError?: (err, toolName) => ToolResult,
  onEvent?: (event: ServerEvent) => void,
})

Gibt einen DefinedServer zurück mit:

  • .start({ transport: 'stdio' }) — einen Transport verbinden und starten.

  • .connect(transport) — eine von Ihnen selbst erstellte Transport-Instanz verbinden (HTTP, benutzerdefiniert, alles, was wie ein Transport funktioniert).

  • .stop() — den aktiven Transport und den zugrunde liegenden Server schließen.

  • .raw — das zugrunde liegende SDK Server-Objekt, falls Sie etwas Exotisches tun müssen.

ressourcen und prompts

Gleiche deklarative Form:

defineResource({
  uri: 'file:///etc/hosts',
  name: 'hosts',
  mimeType: 'text/plain',
  read: async () => ({ text: await fs.readFile('/etc/hosts', 'utf8') }),
});

definePrompt({
  name: 'summarize',
  description: 'Summarize a chunk of text.',
  arguments: z.object({ text: z.string() }),
  build: ({ text }) => ({
    messages: [{ role: 'user', content: { type: 'text', text: `Summarize:\n${text}` } }],
  }),
});

beobachtbarkeit

onEvent erhält einen strukturierten Callback für jeden Tool-Aufruf, jedes Ressourcen-Lesen und jeden Prompt-Abruf — Startzeit, Endzeit, Latenz, Fehler, eine requestId pro Aufruf zur Korrelation. Sie können es an alles anschließen: pino, console, OpenTelemetry, Ihren eigenen Aggregator. Es gibt auch eine integrierte Lösung für den einfachen Fall:

import { defineServer, consoleLogger, jsonLogger } from 'mcpkit';

const server = defineServer({
  name: 'demo',
  version: '0.1.0',
  onEvent: consoleLogger(),    // → pretty stderr lines
  // or: onEvent: jsonLogger() // → one JSON object per line, on stderr
  tools: [...]
});

Logging geht immer an stderr — stdout ist für den Protokollverkehr bei stdio-Transporten reserviert.

testen

mcpkit/testing stellt einen In-Process-Client bereit, der über einen In-Memory-Transport mit Ihrem Server spricht — kein Subprozess, kein stdio-Piping, kein fehleranfälliges Prozess-Herunterfahren. Derselbe Client, den ein echter Konsument verwenden würde, nur über den Arbeitsspeicher geroutet.

import { describe, it, expect } from 'vitest';
import { createTestClient, expectToolError, snapshotTools } from 'mcpkit/testing';
import { server } from '../src/index.js';

describe('add', () => {
  it('adds', async () => {
    const client = await createTestClient(server);
    const result = await client.callTool('add', { a: 2, b: 3 });
    expect(result.text).toBe('5');
    expect(result.isError).toBe(false);
    await client.close();
  });

  it('rejects bad input', async () => {
    const client = await createTestClient(server);
    const text = await expectToolError(client, 'add', { a: 'nope', b: 1 });
    expect(text).toMatch(/invalid/i);
    await client.close();
  });

  it("doesn't drift its public surface", () => {
    expect(snapshotTools(server)).toMatchSnapshot();
  });
});

wissenswerte designentscheidungen

Zod, nicht rohes JSON-Schema. Sie schreiben den Typ einmal. Validierung, generiertes JSON-Schema für das Protokoll und TypeScript-Inferenz für den Handler ergeben sich alle aus derselben Quelle. Der Versuch, drei Definitionen synchron zu halten, ist der Boilerplate-Code, den dieses Projekt eliminieren will.

Fehler sind Werte, keine Exceptions. Ein Handler, der einen Fehler wirft, wird zu einem isError: true-Content-Envelope. Der Client sieht eine sinnvolle Antwort anstelle eines Fehlers auf Transportebene. Wenn Sie den Fehler lieber selbst formatieren möchten, überschreiben Sie onToolError.

Transport-agnostischer Kern. Derselbe defineServer funktioniert über stdio, den streamfähigen HTTP-Transport, den In-Memory-Test-Transport oder alles andere, das das Transport-Interface des SDK implementiert. Die http-streaming-Vorlage zeigt die Verkabelung.

Standardmäßig Strict-Modus. Vorlagen werden mit strict: true und noUncheckedIndexedAccess ausgeliefert. Die Bibliothek selbst kompiliert unter denselben Einstellungen. Wenn Sie eine Lücke in den Typen finden, ist das ein Bug.

Listener-Fehler werden verschluckt. Wenn Ihr onEvent-Handler einen Fehler wirft, funktionieren Ihre Tool-Aufrufe weiterhin. Observability-Bugs sollten nicht kritisch für die Funktion sein.

faq

Bin ich für immer an mcpkit gebunden? Nein. Jeder Helfer hat einen Ausweg — server.raw gibt Ihnen den zugrunde liegenden SDK Server, und Sie können setRequestHandler direkt darauf aufrufen, wenn Sie etwas benötigen, das das Kit noch nicht modelliert. Das Kit ist eine Schicht darüber, kein Ersatz.

Warum Zod 3 und nicht 4? Zod 4 ist großartig, aber das Ökosystem (insbesondere zod-to-json-schema) holt noch auf. Wir werden umsteigen, wenn es in der Produktion stabil ist. Wenn Sie bereits Zod 4 verwenden, sind die Schema-Interfaces kompatibel genug — erstellen Sie ein Issue, wenn Sie auf Probleme stoßen.

Unterstützt es Ressourcen und Prompts, nicht nur Tools? Ja. defineResource und definePrompt sind erstklassige Bürger. Sie werden seltener verwendet als Tools, daher führen die meisten Beispiele mit Tools — aber die Verkabelung ist identisch.

Streamable HTTP, SSE, beides? Streamable HTTP. Die ältere HTTP+SSE-Variante ist noch im SDK enthalten, wird aber schrittweise eingestellt — wenn Sie einen Grund haben, sie zu benötigen, ist defineServer transport-agnostisch und Sie können jede Transport-Instanz über .connect() übergeben.

Produktionsreif? Die Bibliothek ist klein und die Oberfläche ist bewusst schmal gehalten. Das offizielle SDK leistet die Schwerstarbeit im Hintergrund. Pinnen Sie eine Version, schreiben Sie Tests für Ihre Tools (der In-Process-Client macht dies einfach), und Sie sind startklar.

was dies nicht ist

  • kein gehosteter Dienst. Sie bauen, Sie deployen.

  • kein Agent-Framework. Es baut die Server-Seite von MCP, nicht den Client.

  • nicht voreingenommen gegenüber Ihrer Domäne. Tools sind Funktionen; was sie tun, ist Ihr Problem.

roadmap

  • mehr Vorlagen (oauth-geschützt, Edge-Runtime, Drizzle/Postgres).

  • ein mcpkit publish-Befehl, der lintet + paketiert + ein Release taggt.

  • reichhaltigere Test-Helfer (Fuzzing einer Tool-Eingabe, Schema-Diff gegen eine Baseline).

  • optionaler OpenTelemetry-Adapter für onEvent.

Wenn etwas fehlt, eröffnen Sie ein Issue mit einer Skizze der API, die Sie sich wünschen.

lizenz

MIT.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (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.

Related MCP Servers

  • A
    license
    C
    quality
    D
    maintenance
    A lightweight and extendable MCP server toolkit that allows developers to build and integrate custom tools with AI assistants through automatic tool discovery from local directories or npm packages.
    2
    18
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A TypeScript-based template for rapidly developing MCP servers with modular tool architecture, built-in validation using Zod schemas, and comprehensive error handling.
    9
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    A TypeScript-based boilerplate for building Model Context Protocol (MCP) servers using the official SDK and Zod. It provides a structured foundation with a decoupled architecture to simplify the creation and registration of custom MCP tools.
    1
    16
    ISC

View all related MCP servers

Related MCP Connectors

  • Markdown-first MCP server for Notion API with 8 composite tools and 39 actions.

  • MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.

  • MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.

View all MCP Connectors

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/EuKennedy/mcpkit'

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