mcp-gen
Convierte tus funciones de TypeScript escritas en un servidor MCP; los esquemas de herramientas, recursos y prompts se infieren de tus tipos y JSDoc. Sin biblioteca de esquemas, sin decoradores, sin código repetitivo.
Documentación
mcp-gen
Convierte tus funciones TypeScript tipadas en un servidor MCP. Sin biblioteca de esquemas, sin decoradores, sin código repetitivo: el esquema se infiere de tus tipos.

mcp-gen lee funciones TypeScript exportadas y genera definiciones de herramientas, recursos y avisos del Protocolo de Contexto de Modelos a partir de ellas, usando el verificador de tipos de TypeScript (a través de ts-morph) para convertir cada tipo de parámetro en un esquema JSON y cada comentario JSDoc en una descripción. Puede emitir los esquemas como JSON, servir un servidor MCP en vivo o abrir un área de juegos en vivo donde llamas a tus herramientas en un navegador mientras editas.
Si tus funciones están tipadas, ya son herramientas MCP.
Inicio rápido
Escribe funciones simples y tipadas con JSDoc normal:
// tools.ts
/**
* Greets a person by name and age.
* @param name - The person's name
* @param age - The person's age in years
*/
export function greet(name: string, age: number): string {
return `Hello ${name}, age ${age}`;
}
/**
* Echoes a message back after a tick.
* @param msg - The message to echo back
*/
export async function slowEcho(msg: string): Promise<string> {
return `echo: ${msg}`;
}
Genera los esquemas de las herramientas:
mcp-gen tools.ts
{
"tools": [
{
"name": "greet",
"description": "Greets a person by name and age.",
"inputSchema": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "The person's name" },
"age": { "type": "number", "description": "The person's age in years" }
},
"required": ["name", "age"]
}
}
// ... slowEcho
]
}
La forma más rápida de probarlas de verdad: el área de juegos en vivo. Observa tu archivo, genera un formulario de entrada para cada herramienta a partir del esquema inferido y lo ejecuta directamente en tu navegador mientras editas:
mcp-gen dev tools.ts # then open the printed http://127.0.0.1:4000/ URL
O ejecútalo como un servidor MCP real:
mcp-gen serve tools.ts --port 3000
serve vincula 127.0.0.1 (loopback) por defecto — ejecuta tu código local cuando se llaman sus herramientas, por lo que no es accesible desde otras máquinas a menos que lo solicites. Para exponerlo en la red, indícalo explícitamente con --host (p. ej. mcp-gen serve tools.ts --host 0.0.0.0); hacerlo imprime una advertencia, ya que el punto final pasa a ser accesible desde otras máquinas.
Antes de exponerlo, activa la autenticación con token portador. Configura una o más claves con --api-key <key> (repetible) o la variable de entorno MCP_GEN_API_KEYS separada por comas — si hay alguna clave configurada, la autenticación está activada y toda solicitud a /mcp debe incluir Authorization: Bearer <key> (una clave ausente, mal formada o incorrecta se rechaza con 401 antes de que se ejecute cualquier herramienta). Sin claves configuradas, la autenticación está desactivada y el comportamiento es el mismo. Cuando la autenticación está activada, la advertencia de "sin autenticación" en máquinas externas se reemplaza por una confirmación de una línea de que se requiere un token. Consulta Implementación en producción.
Eso es todo. Los nombres de los parámetros, tipos, obligatoriedad y descripciones provienen del código que ya escribiste.
Cómo funciona
- Los tipos se convierten en esquemas. Los parámetros de cada función exportada se convierten en un esquema JSON
inputSchemamediante el verificador de tipos de TypeScript. Los parámetros opcionales (age?: number) se omiten derequired; se capturan los tipos de retorno (y se desarrollaPromise<T>). - JSDoc se convierte en documentación. El resumen de la función se convierte en el
descriptionde la herramienta; cada@paramse convierte en ladescriptionde esa propiedad. - Falla en voz alta, nunca en silencio. Una función que no se puede convertir a un esquema válido — por ejemplo un genérico sin enlazar en posición de entrada (
identity<T>(value: T)) — se excluye y se informa, nunca se emite como algo roto. Las funciones limpias se siguen generando; el código de salida te indica si alguna falló (ver más abajo).
Qué maneja
Está diseñado para funcionar en bases de código reales, no solo en juguetes de un solo archivo:
- genéricos (restringidos y sin enlazar), y un error claro en los que no se pueden representar
- tipos importados de otros módulos y reexportados bajo alias
- múltiples estilos de exportación (nombrados, por defecto, con alias)
- descubrimiento de
tsconfig.jsony resolución de alias de ruta - detección de tipos no serializables (en lugar de emitir un esquema inválido)
- funciones
async(tipos de retorno esperados); una herramienta que falla devuelveisErroren lugar de derribar el servidor
Recursos y avisos
Los servidores MCP pueden exponer tres tipos de cosas: herramientas (acciones), recursos (datos) y avisos (plantillas reutilizables). mcp-gen infiere los tres a partir de las mismas exportaciones tipadas; una sola etiqueta JSDoc elige cuál. Una función sin etiqueta es una herramienta, exactamente igual que antes — nada cambia para el código existente.
Recursos — @resource <uri>
Etiqueta una función con @resource y un URI. Si el URI tiene {placeholders} que coinciden con los nombres de los parámetros, se convierte en una plantilla de recurso (los parámetros validan la URL); sin marcadores de posición es un recurso estático. El valor de retorno es el contenido: un string se sirve como text/plain, cualquier otra cosa como application/json. Añade @mime <type> para anularlo.
/**
* Read a user record by id.
* @resource users://{id} — templated: {id} matches the `id` param
* @param id - The user id
*/
export function getUser(id: string): { id: string; name: string } {
return { id, name: `User ${id}` };
}
/**
* The current app configuration.
* @resource config://app — static: no placeholders
*/
export function appConfig() {
return { theme: "dark", version: "1.1.0" };
}
/**
* @resource info://build
* @mime text/plain — override the content type
*/
export function buildInfo(): string {
return "mcp-gen build 1.1.0";
}
Avisos — @prompt
Etiqueta una función con @prompt. Sus parámetros se convierten en los argumentos del aviso (nombres y descripciones de @param). Devuelve una cadena para un único mensaje de usuario, o un array de mensajes de { role, content } para pasarlos tal cual.
/**
* A code-review prompt.
* @prompt
* @param language - The programming language
* @param code - The code to review
*/
export function reviewPrompt(language: string, code: string): string {
return `Please review this ${language} code:\n\n${code}`;
}
Ejecuta mcp-gen serve y un cliente MCP conectado puede listar y leer tus recursos y obtener tus avisos, además de llamar a las herramientas. Los recursos y avisos pasan por exactamente la misma ruta que las herramientas — la misma inferencia de tipos, la misma validación, la misma ejecución — y se aplica la misma regla de fallar en voz alta: por ejemplo, una plantilla @resource cuyo {var} no coincide con un parámetro se excluye y se informa, nunca se registra a medias.
CLI
mcp-gen <file.ts> [--debug] [--tsconfig <path>] Generate tool schemas as JSON (stdout)
mcp-gen serve <file.ts> [--port N] [--host <addr>] [--api-key <key>]... [--tsconfig <path>] Start a live MCP server (default port 3000; binds 127.0.0.1; PORT/HOST env honored)
mcp-gen dev <file.ts> [--port N] [--tsconfig <path>] Live playground UI, watches + reloads (default port 4000)
mcp-gen check <file.ts> [--update] [--snapshot <path>] [--tsconfig <path>] Guard the tool surface against breaking changes (CI)
La generación escribe JSON legible por máquina en stdout (siempre incluye tools; incluye errors/warnings cuando están presentes); los mensajes legibles por humanos van a stderr. Códigos de salida:
| Código | Significado |
|---|---|
0 | cada función exportada se convirtió limpiamente |
1 | una o más funciones fallaron — las limpias aún se emiten, los fallos se listan en errors |
2 | fallo a nivel de archivo (no encontrado / no analizable / nada servible) |
Implementación en producción
Para ejecutar serve como un servidor MCP accesible por red, vincula una interfaz pública y exige un token portador. Pasa las claves a través del entorno (no --api-key) para que el secreto nunca quede en el historial del shell o en un listado de procesos:
# one or more comma-separated keys; every caller must send `Authorization: Bearer <key>`
MCP_GEN_API_KEYS="$(openssl rand -hex 32)" mcp-gen serve tools.ts --host 0.0.0.0
- Claves vía entorno en producción, no en la CLI.
--api-keyes conveniente para pruebas locales, pero una bandera es visible para cualquiera que pueda listar procesos (ps);MCP_GEN_API_KEYSmantiene el secreto fuera deargv. Ambas fuentes se unen, se dividen por comas y se recortan, y cualquier clave no vacía activa la autenticación. PORT/HOSTse respetan. Cuando omites--port/--host,serverecurre a las variables de entornoPORTyHOSTantes de sus valores predeterminados (3000/127.0.0.1) — así encaja directamente en una plataforma que inyectaPORT. Una bandera--port/--hostexplícita siempre anula la variable de entorno.- La autenticación está bloqueada por defecto. Con claves configuradas, una solicitud a
/mcpcon un token ausente, mal formado o no coincidente se rechaza con401 {"error":"unauthorized"}antes del transporte MCP — por lo que no se ejecuta ningún código de herramienta, recurso o aviso. Las claves se comparan en tiempo constante. - Sin claves = expuesto y sin autenticación. Vincula un
--host(oHOST) que no sea de loopback sin tener ninguna clave configurada yserveseguirá imprimiendo la advertencia de exposición. Configura una clave para proteger el punto final (y silenciar la advertencia).
En una plataforma que inyecta PORT (y opcionalmente HOST), solo suministras las claves:
MCP_GEN_API_KEYS="key-a,key-b" mcp-gen serve tools.ts --host 0.0.0.0 # PORT taken from the environment
Protegiendo el contrato — check
check es tsc para tu superficie de herramientas: guarda una instantánea de las herramientas generadas en un archivo comprometido y, en ejecuciones posteriores, falla la compilación ante cambios rupturistas — para que una herramienta orientada a agentes no pueda cambiar silenciosamente su forma bajo los ojos de sus llamadores.
mcp-gen check tools.ts --update # write the baseline (the `jest -u` of tool contracts) — commit it
mcp-gen check tools.ts # in CI: fail if the surface broke
Los cambios rupturistas (salida 1) se juzgan desde la perspectiva de un llamador existente: una herramienta eliminada o renombrada, una propiedad eliminada, un parámetro nuevo obligatorio, un parámetro opcional que se vuelve obligatorio, un cambio de tipo, un valor de enum eliminado o cualquier otra restricción de un subesquema anidado. Los cambios puramente aditivos o de relajación — una nueva herramienta, un nuevo parámetro opcional, un requisito relajado, un nuevo valor de enum — son seguros y nunca fallan. Los cambios de descripción y tipo de retorno se informan como avisos.
| Código | Significado |
|---|---|
0 | sin cambios rupturistas (o un --update exitoso) |
1 | al menos un cambio rupturista — indicado en stderr, lista completa de cambios como JSON en stdout |
2 | fallo a nivel de archivo, uso incorrecto o instantánea faltante (nunca se crea silenciosamente — imprime cómo crear una línea base) |
La instantánea se normaliza determinísticamente (herramientas y claves ordenadas, formato estable), por lo que permanece estable en bytes y se revisa limpiamente en un PR. Por defecto es <file>.mcp-snapshot.json; anúlalo con --snapshot.
Área de juegos en vivo — dev
dev es un área de juegos con conocimiento de tipos para el servidor que define un archivo. Observa el archivo, regenera la superficie de herramientas en cada guardado y sirve una pequeña interfaz web de localhost:
mcp-gen dev tools.ts # then open the printed URL, e.g. http://127.0.0.1:4000/
Abre la URL impresa en un navegador. Para cada herramienta, renderiza un formulario de entrada a partir del esquema inferido (cadena → texto, número → número, booleano → casilla de verificación, enumeración → menú desplegable, arrays/objetos → cuadro JSON bruto), ejecuta la herramienta bajo demanda y muestra el resultado, el inputSchema generado y la solicitud/respuesta JSON-RPC cruda — la vista de inspector. Las funciones excluidas por fallar en voz alta se listan en gris con sus razones. Guarda el archivo y la página se recarga sola, conservando lo que habías escrito.
Lo crucial es que el área de juegos ejecuta cada herramienta a través de exactamente la misma ruta que mcp-gen serve — el mismo cargador de módulos y la misma asignación nombre→posición — para que lo que ves en el navegador sea lo que hace el servidor atendido. Vincula 127.0.0.1 únicamente (ejecuta tu código local bajo petición, por lo que nunca se expone fuera de la máquina), usa el puerto 4000 por defecto y sigue la misma disciplina de códigos de salida que serve.
Comete el archivo
*.mcp-snapshot.json— es la línea base contra la que cadacheckposterior compara, no el resultado de la compilación. No lo agregues a.gitignore; inclúyelo junto con tu código para que el diff de un PR muestre exactamente cómo cambió la superficie de herramientas.
Instalación
npm install -g @zodromon/mcp-gen
El paquete tiene alcance (@zodromon/mcp-gen), pero el comando que ejecutas es simplemente mcp-gen:
mcp-gen tools.ts
O ejecútalo sin instalar, mediante npx:
npx @zodromon/mcp-gen tools.ts
Desde el código fuente (para desarrollarlo o contribuir):
git clone https://github.com/zodromon/mcp-gen && cd mcp-gen
npm install
npm run build # → dist/
node dist/generate-mcp-schemas.js tools.ts
Durante el desarrollo puedes ejecutarlo directamente sin compilar:
npm run generate -- tools.ts # via tsx
Requiere Node.js. Dependencias: @modelcontextprotocol/sdk, ts-morph, typescript, jiti.
Alcance, honestamente
Bueno para: exponer rápidamente funciones tipadas existentes como herramientas MCP — herramientas internas, prototipos, cualquier cosa donde prefieras no escribir esquemas de herramientas a mano.
No intenta ser el framework MCP más grande. Hace una sola cosa. Si quieres decoradores, un sistema de complementos o una plataforma gestionada, otras buenas herramientas se ajustan mejor:
- FastMCP — maduro y popular; declaras parámetros mediante una biblioteca de esquemas (Zod/ArkType/Valibot).
- simply-mcp-ts — APIs decorador / funcional / programáticas.
- El SDK oficial de MCP — control máximo, más código repetitivo.
mcp-gen's única diferencia real es el gusto: no se añade nada a tus funciones — sin biblioteca de esquemas, sin anotaciones más allá del JSDoc que de todos modos escribirías. Si eso te atrae, úsalo. Si no, los demás son geniales.
Licencia
MIT. Libre de usar, bifurcar o ignorar.