Skip to main content
Glama
EuKennedy

mcpkit

by EuKennedy

mcpkit

ci release license node

El kit de herramientas de TypeScript para crear servidores MCP sin código repetitivo.

Define una herramienta con un esquema de Zod y un manejador. Obtén un servidor del Model Context Protocol funcional: generación de esquemas, validación de entradas, sobres de error, configuración de transporte, todo hecho.

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();

Eso es un servidor MCP real y funcional. Ejecútalo con mcpkit dev y apunta cualquier cliente compatible con MCP hacia él.


por qué existe esto

Escribir un servidor MCP con el SDK oficial está bien, pero terminas haciendo la misma fontanería cada vez:

  • declarar la lista de herramientas en un lugar

  • declarar un JSON Schema separado para cada herramienta

  • escribir un switch sobre los nombres de las herramientas en el manejador de llamadas

  • forzar los retornos del manejador dentro del sobre de contenido del protocolo

  • configurar un transporte

  • capturar errores y convertirlos a la forma isError correcta

mcpkit colapsa todo eso en defineTool + defineServer. El esquema se genera a partir de tu tipo Zod, la validación se ejecuta antes de tu manejador, los errores se convierten en respuestas de protocolo adecuadas y un retorno de cadena se convierte en un bloque de contenido de texto. Te mantienes en la capa que realmente importa —lo que hace la herramienta— y te saltas la capa que no.

Related MCP server: MCP Base Server

con vs sin

La misma herramienta, escrita contra el SDK básico y contra 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();

La columna de la derecha tiene el mismo comportamiento a nivel de red, además de validación de entrada, argumentos de manejador tipados y un sobre isError en lanzamientos no capturados.

instalación

npm install mcpkit zod

O crea un proyecto nuevo (recomendado para un primer servidor):

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

Obtendrás un proyecto pequeño con un servidor stdio funcional, tres herramientas de ejemplo y un tsconfig.json configurado para modo estricto. Reemplaza las herramientas de ejemplo con las tuyas y publica.

la 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 se envía con cuatro plantillas hoy:

plantilla

qué obtienes

stdio-basic

servidor MCP local sobre stdio. la mayoría de los clientes quieren esto.

http-streaming

servidor accesible por red sobre el transporte HTTP transmitible.

with-fetch

servidor stdio con herramientas de obtención HTTP (tiempos de espera configurados).

with-sqlite

servidor stdio con un ejemplo CRUD respaldado por SQLite (better-sqlite3, WAL).

la 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? }
})

La entrada del manejador está totalmente tipada mediante z.infer. Devolver una cadena la envuelve como un bloque de contenido de texto único —ese es el caso común. Lanzar un error dentro de un manejador se convierte automáticamente en una respuesta isError: true; si deseas dar forma al mensaje de error, pasa un manejador onToolError a defineServer.

defineServer

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

Devuelve un DefinedServer con:

  • .start({ transport: 'stdio' }) — conecta un transporte y sirve.

  • .connect(transport) — conecta una instancia de transporte que construiste tú mismo (HTTP, personalizado, cualquier cosa que actúe como un Transport).

  • .stop() — cierra el transporte activo y el servidor subyacente.

  • .raw — el Server del SDK subyacente si necesitas hacer algo exótico.

recursos y prompts

La misma forma declarativa:

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}` } }],
  }),
});

observabilidad

onEvent obtiene una devolución de llamada estructurada para cada llamada de herramienta, lectura de recurso y obtención de prompt — hora de inicio, hora de finalización, latencia, error, un requestId por llamada para correlacionar. Puedes conectarlo a cualquier cosa: pino, console, OpenTelemetry, tu agregador casero. También hay uno integrado para el caso simple:

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: [...]
});

El registro siempre va a stderr — stdout está reservado para el tráfico del protocolo en transportes stdio.

pruebas

mcpkit/testing expone un cliente en proceso que habla con tu servidor a través de un transporte en memoria — sin subprocesos, sin tuberías stdio, sin cierres de proceso inestables. El mismo cliente que usaría un consumidor real, solo que enrutado a través de la RAM.

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();
  });
});

decisiones de diseño que vale la pena conocer

Zod, no JSON Schema crudo. Escribes el tipo una vez. La validación, el JSON Schema generado para el protocolo y la inferencia de TypeScript para el manejador surgen de la misma fuente. Intentar mantener tres definiciones sincronizadas es el código repetitivo que este proyecto existe para eliminar.

Los errores son valores, no excepciones. Un manejador que lanza un error se convierte en un sobre de contenido isError: true. El cliente ve una respuesta sensata en lugar de un fallo a nivel de transporte. Si prefieres formatear el error tú mismo, sobrescribe onToolError.

Núcleo agnóstico al transporte. El mismo defineServer funciona sobre stdio, el transporte HTTP transmitible, el transporte de prueba en memoria o cualquier otra cosa que implemente la interfaz Transport del SDK. La plantilla http-streaming muestra la configuración.

Modo estricto por defecto. Las plantillas se envían con strict: true y noUncheckedIndexedAccess. La biblioteca misma se compila bajo la misma configuración. Si encuentras un agujero en los tipos, eso es un error.

Los errores del oyente son ignorados. Si tu manejador onEvent lanza un error, tus llamadas a herramientas siguen funcionando. Los errores de observabilidad no deberían ser críticos.

preguntas frecuentes

¿Esto me bloquea en mcpkit para siempre? No. Cada ayudante tiene una salida de emergencia — server.raw te da el Server del SDK subyacente, y puedes hacer setRequestHandler en él directamente si necesitas algo que el kit aún no modela. El kit es una capa superior, no un reemplazo.

¿Por qué Zod 3 y no 4? Zod 4 es genial, pero el ecosistema (notablemente zod-to-json-schema) todavía se está poniendo al día. Nos moveremos cuando sea estable en producción. Si ya estás en Zod 4, las interfaces de esquema son lo suficientemente compatibles — abre un problema si te encuentras con un muro.

¿Soporta recursos y prompts, no solo herramientas? Sí. defineResource y definePrompt son de primera clase. Se usan menos comúnmente que las herramientas, por lo que la mayoría de los ejemplos comienzan con herramientas, pero la configuración es idéntica.

¿HTTP transmitible, SSE, ambos? HTTP transmitible. El sabor anterior HTTP+SSE todavía está en el SDK pero se está eliminando gradualmente; si tienes una razón para necesitarlo, defineServer es agnóstico al transporte y puedes pasar cualquier instancia de Transport a través de .connect().

¿Listo para producción? La biblioteca es pequeña y la superficie es intencionalmente estrecha. El SDK oficial hace el trabajo pesado debajo. Fija una versión, escribe pruebas para tus herramientas (el cliente en proceso facilita esto) y estarás listo.

lo que esto no es

  • no es un servicio alojado. tú construyes, tú despliegas.

  • no es un marco de trabajo de agentes. construye el lado del servidor de MCP, no el cliente.

  • no tiene opiniones sobre tu dominio. las herramientas son funciones; lo que hacen es tu problema.

hoja de ruta

  • más plantillas (protegidas por oauth, tiempo de ejecución edge, drizzle/postgres).

  • un comando mcpkit publish que analiza + empaqueta + etiqueta una versión.

  • ayudantes de prueba más ricos (fuzzing de la entrada de una herramienta, diferencia de esquema contra una línea base).

  • adaptador opcional de OpenTelemetry para onEvent.

Si falta algo, abre un problema con un boceto de la API que desearías.

licencia

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