nan-mcp-server
NaN MCP Server
Servidor MCP (Model Context Protocol) que expone las herramientas de media de la API de NaN (api.nan.builders) para cualquier cliente compatible con MCP.
Al ser un estándar abierto, funciona con opencode, Claude Code, Codex, Pi, Cursor, Windsurf, Zed, etc.
Herramientas
Herramienta | Descripción | Modelo |
| Generar imagen desde texto |
|
| Editar imagen (imagen→imagen) |
|
| Sintetizar audio desde texto |
|
| Listar voces kokoro por idioma | — |
| Transcribir audio a texto |
|
| Embeddings vectoriales (4096 dims) |
|
| Reordenar documentos por relevancia (RAG) |
|
| Listar modelos disponibles con tu key | — |
Requisitos
Node.js >= 18
Una API key de NaN (
sk-...)
Instalación
El paquete se distribuye por npm. La forma más simple de usarlo en cualquier cliente MCP es sin instalarlo: npx lo ejecuta al vuelo.
export NAN_API_KEY="sk-tu-key-aqui"
npx -y nan-mcp-server@1.1.0Con otro gestor de paquetes, si ya lo usas:
pnpm dlx nan-mcp-server@1.1.0 # pnpm
yarn dlx nan-mcp-server@1.1.0 # yarn
bunx nan-mcp-server@1.1.0 # bunO instálalo globalmente:
npm install -g nan-mcp-server@1.1.0 # o: pnpm add -g / bun add -g
nan-mcp-serverSobre la versión fijada: los ejemplos fijan una versión exacta en lugar de
@latest, a propósito. Con@latest, cada arranque descarga la última versión publicada, así que cualquier versión futura —incluida una publicada por una cuenta comprometida— se ejecutaría en tu máquina automáticamente. Fijar la versión te deja decidir cuándo actualizar; consulta las releases y sube el número cuando quieras. Si prefieres actualizaciones automáticas, sustituye la versión por@latesten cualquiera de los ejemplos.
Configuración
El servidor se ejecuta vía stdio (proceso local). Solo necesita una variable de entorno: NAN_API_KEY.
Las imágenes y audios generados se guardan en ~/nan-mcp-output/ (configurable con NAN_OUTPUT_DIR).
Configuración por cliente
Añade a tu opencode.jsonc (o créalo en ~/.config/opencode/):
{
"mcp": {
"nan-media": {
"type": "local",
"command": ["npx", "-y", "nan-mcp-server@1.1.0"],
"environment": {
"NAN_API_KEY": "{env:NAN_API_KEY}"
}
}
}
}Instalar vía CLI:
claude mcp add nan-media --scope user -e NAN_API_KEY='${NAN_API_KEY}' -- \
npx -y nan-mcp-server@1.1.0O en .mcp.json:
{
"mcpServers": {
"nan-media": {
"type": "stdio",
"command": "npx",
"args": ["-y", "nan-mcp-server@1.1.0"],
"env": {
"NAN_API_KEY": "${NAN_API_KEY}"
}
}
}
}En ~/.codex/config.toml:
[mcp_servers.nan-media]
command = "npx"
args = ["-y", "nan-mcp-server@1.1.0"]
env_vars = ["NAN_API_KEY"]
env_varsno es opcional: codex no propaga su propio entorno a los servidores MCP, así que sin esa línea el proceso arranca sinNAN_API_KEYy muere durante el handshake (connection closed: initialize response).env_varsnombra las variables que debe heredar;envsolo admite valores literales, que no conviene escribir en un archivo versionado.
Pi usa pi-mcp-adapter y lee los archivos MCP estándar. Instala el adaptador:
pi install npm:pi-mcp-adapterCrea ~/.config/mcp/mcp.json (config compartido MCP estándar):
{
"mcpServers": {
"nan-media": {
"command": "npx",
"args": ["-y", "nan-mcp-server@1.1.0"],
"env": {
"NAN_API_KEY": "$env:NAN_API_KEY"
}
}
}
}La key se interpola con
$env:NAN_API_KEY, así que ningún secreto queda en el archivo.
Para usar los modelos de NaN en Pi, define el proveedor en ~/.pi/agent/models.json:
{
"providers": {
"nan": {
"baseUrl": "https://api.nan.builders/v1",
"api": "openai-completions",
"apiKey": "$NAN_API_KEY",
"models": [
{ "id": "deepseek-v4-flash", "name": "DeepSeek V4 Flash", "reasoning": true, "input": ["text", "image"], "contextWindow": 1048576 },
{ "id": "qwen3.6", "name": "Qwen 3.6", "reasoning": true, "input": ["text", "image"], "contextWindow": 262144 }
]
}
}
}Luego usa --provider nan --model <id> (p.ej. pi --provider nan --model deepseek-v4-flash).
En la configuración de MCP del cliente, añade un servidor stdio:
Comando: npx -y nan-mcp-server@1.1.0
Variables: NAN_API_KEY=tu-clave-de-nan-builders (no la incluyas en el config versionado)Uso
Una vez conectado, pide al agente:
"Genera una imagen de un faro al atardecer con nan-media"
"Sintetiza en español: Hola mundo, voz ef_dora"
"Transcribe el audio /ruta/audio.mp3"
"Reordena estos documentos según la query X"
Límites de la API
Recurso | Límite |
Generación/edición de imágenes | 100 req/mes por usuario, 1 req/s (burst 3) |
Tamaño máximo archivo (STT / edit_image) | 25 MB por archivo |
Audios para transcripción | máx. ~2 min por archivo (timeout 524 si supera) |
Imágenes de referencia (edit_image) | hasta 4 |
Variables de entorno
Variable | Obligatoria | Descripción |
| Sí | API key de NaN |
| No | Base URL de la API (default |
| No | Directorio de salida (default |
| No | Timeout por petición en ms (default |
Desarrollo
Estructura
nan-mcp-server/
├── server.js # Servidor MCP + herramientas
├── test/server.test.js # Tests (node:test, sin dependencias extra)
├── .github/workflows/ # ci.yml (tests) + publish.yml (npm)
├── package.json
└── README.mdTesting
Los tests usan el test runner nativo de Node (node:test), sin dependencias adicionales. No hacen llamadas a la API (usan un valor de prueba para NAN_API_KEY), así que se ejecutan sin red ni credenciales.
npm testPara probar el servidor manualmente contra la API real (requiere key):
NAN_API_KEY=sk-tu-key-aqui node server.jsY luego una llamada de ejemplo vía stdio:
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}\n{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}\n' \
| node server.jsPublicación / CI
El código no contiene secretos:
NAN_API_KEYse lee solo del entorno.El
.gitignoreexcluyenode_modules/, logs y.env..github/workflows/ci.ymlejecuta los tests en cada push y PR amainsobre Node 18, 20, 22 y 24, más un jobstrict-depscon pnpm: sunode_modulessin hoisting hace fallar cualquier import de un paquete no declarado enpackage.json(npm lo dejaría pasar silenciosamente)..github/workflows/publish.ymlpublica en npm al crear un release en GitHub, vía trusted publishing (OIDC), sin token en secrets.
Notas
Las imágenes y audios se guardan en
~/nan-mcp-output/(configurable conNAN_OUTPUT_DIR). Los nombres se sanitizan (sin path traversal) y nunca se sobrescriben archivos existentes: si el nombre ya está ocupado se añade-2,-3, etc.Los archivos de entrada (STT / edit_image) se cargan en memoria; para archivos muy grandes conviene dividirlos.
El servidor no contiene ningún secreto en el código: solo lee
NAN_API_KEYdel entorno.
Licencia
MIT — ver LICENSE.