mcpkit
mcpkit
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
isErrorcorrecta
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 zodO crea un proyecto nuevo (recomendado para un primer servidor):
npx mcpkit create my-server
cd my-server
npm run devObtendrá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 servercreate se envía con cuatro plantillas hoy:
plantilla | qué obtienes |
| servidor MCP local sobre stdio. la mayoría de los clientes quieren esto. |
| servidor accesible por red sobre el transporte HTTP transmitible. |
| servidor stdio con herramientas de obtención HTTP (tiempos de espera configurados). |
| 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 unTransport)..stop()— cierra el transporte activo y el servidor subyacente..raw— elServerdel 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 publishque 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.
This server cannot be installed
Maintenance
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
AlicenseCqualityDmaintenanceA 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.218MIT- AlicenseNot gradedqualityDmaintenanceA TypeScript-based template for rapidly developing MCP servers with modular tool architecture, built-in validation using Zod schemas, and comprehensive error handling.9MIT
- FlicenseNot gradedqualityDmaintenanceA minimal MCP server framework that enables zero-config tool discovery and streamable HTTP transport using the LeanMCP SDK. It allows developers to build type-safe services with automatic schema validation and integrated React UI components.
- AlicenseBqualityDmaintenanceA 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.116ISC
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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