Capítulo MCP de la guía Neblla — el servidor MCP para que una IA cree y gestione apps. El contrato base está en core.txt; el criterio de cuándo usar Neblla, en empezar.txt.

El servidor MCP

Endpoint: https://neblla.com/mcp. Es la puerta por la que cualquier IA puede crear apps Neblla, subir ficheros, gestionar productos y usuarios, y publicar en la galería en nombre del desarrollador.

Autenticación

OAuth con Bearer token. El recurso protegido anuncia su metadata en https://neblla.com/.well-known/oauth-protected-resource/mcp. El access token tiene su propio TTL y revocación. Pide un solo permiso (scope), mcp: usar todas estas tools sobre las apps del desarrollador que lo aprueba (crear, cambiar y borrar apps, sus ficheros y sus productos). La pantalla de permisos lo enseña bajo cada frase, con enlace a esta página.

Si el desarrollador aún no tiene cuenta, se crea al conectarse: el cliente MCP abre el navegador, el dev entra con Google, GitHub o su email y acepta, y la cuenta y la primera app salen en la misma conversación. Si el agente no puede abrir un navegador (en la nube, en CI), Neblla publica https://neblla.com/auth.md (el protocolo abierto auth.md): el agente pide el alta con el email del dev, Neblla le manda un código de un solo uso, el dev se lo dicta al agente y el agente recibe su token para el MCP.

Tres tools funcionan sin autenticación: neblla_get_llms, neblla_get_app_url y neblla_validate_requirements. El resto requiere el token del desarrollador.

Tools

Guía y descubrimiento (sin auth):

Apps:

Ficheros:

Un fichero que la lista tiene pero cuyo contenido se perdió (se guardó justo antes de un deploy de Neblla) responde file_bytes_lost en neblla_get_file y neblla_edit_file: súbelo otra vez. La portada de la galería no corre ese riesgo: se guarda aparte.

Versiones seguras:

Productos:

Galería:

Usuarios finales (backoffice):

Las herramientas que leen usuarios y sus datos (neblla_list_users, neblla_search_users_by_email, neblla_get_user, neblla_export_users, neblla_list_communications, neblla_list_community_entries, neblla_get_community_entry) aceptan env: pro (los usuarios, por defecto) o pre (los del pre de la app, que son los de pro si pre usa sus datos). En el panel es el selector «Datos de: publicada · borrador» de las páginas con datos (el panel llama a pre «borrador» y a pro «la publicada»).

Salas y moderadores:

Comunidad:

Reseñas de la galería:

Comunicaciones (backoffice):

Integraciones:

Cobros:

Cuenta:

Facturación:

Solo en la web, a propósito: contraseña, rotar el token, guardar las claves de la IA (Claude, OpenAI, DeepSeek), y quitar emails o cambiar el principal.

La lista corta y la referencia de cada tool

tools/list muestra cada tool en corto: una frase del efecto, sus argumentos sin texto y el puntero «More: neblla_get_llms tools/<nombre>». El texto completo de cada tool (su descripción entera y la explicación de cada argumento, con la forma de los objetos) es la sección tools/<nombre> de neblla_get_llms, por ejemplo neblla_get_llms({ section: "tools/sales" }); tools/index las lista todas. neblla_update_app se lista por módulos: neblla_update_app (lo general), _rooms, _community, _payments, _auth, _storage, _games, _business, _inbox y _integrations. Es la misma llamada: neblla_update_app acepta todos los campos, así que las guías que escriben neblla_update_app({ business }) siguen valiendo.

El dinero se aprueba en el panel

El MCP no mueve dinero. Estas acciones crean una petición y devuelven approveUrl, un enlace al panel (#approve=<token>) que abre la acción ya rellenada: neblla_sales refund, neblla_billing auto_recharge (al activarla; apagarla es inmediato), neblla_domains register, neblla_credits adjust y neblla_booking cancel (con reembolso; con refund: false corre al momento) y cancelSession. El dev, con su sesión del panel, ve qué se le pide (por ejemplo «Reembolsar 20,00 EUR a Ana»), pulsa «Aprobar» y solo entonces se ejecuta. El enlace sirve una vez, caduca a las 24 horas y solo lo ve el dev dueño de la app. Si la acción sería rechazada (una venta ya reembolsada, un dominio ocupado), el rechazo llega al pedirla.

Tools que miran y tools que cambian

Cada tool lleva sus anotaciones MCP (title, readOnlyHint, destructiveHint, openWorldHint): el cliente deja correr sin preguntar las que solo miran y pide confirmación en las que cambian o borran. Una tool con action que mezclaba las dos cosas está registrada como dos: la de siempre (neblla_domains) tiene las acciones que cambian y neblla_domains_read las que solo miran, con los mismos argumentos. Si una acción no sale en una de las dos, está en la otra. Las de esta lista son las que se dividen:

Cuando una llamada falla

Toda tool responde { status: "fail", error, message, messageEs }. Un error conocido (app_not_found, unauthorized, slug_taken…) dice qué hacer a continuación. server_error es un fallo que Neblla no esperaba: añade tool, retryable (true cuando un servicio del que depende Neblla no contestó a tiempo: repite la misma llamada en unos segundos) y errorId, el id de la línea en el log de Neblla (mándalo a hello@neblla.com si se repite). La causa no va en la respuesta. Tras una escritura que falló, mira el estado actual con la tool de lectura antes de repetirla: el primer intento pudo llegar a hacerse.

Los módulos de una app

Una app de Neblla es un set de módulos neblla.*, un interruptor por módulo en features:

Lo que está apagado no viaja en el SDK que descarga la app, el servidor lo rechaza con feature_disabled (y module dice cuál) y neblla_get_llms con appId lo deja fuera de la guía. neblla_update_app({ appId, features: { shop: true } }) cambia solo los módulos que pasas: encender uno trae lo que necesita y apagar uno se lleva lo que lo necesita. Un nombre viejo (multiplayer, friends, purchases, communications, login) responde unknown_module. neblla_get_app devuelve los módulos de la app en modules.

Con qué nace una app: con decisions, los módulos decididos; con template, los de su página (rooms, los cuatro del multijugador; lobby-only, message, state y room; solo-save y home, ninguno más); sin nada, solo auth y db. La respuesta de neblla_create_app los lista en modules: enciende lo que la app usa, y nada más, con neblla_update_app({ features }). Un juego con salas y herramientas, por ejemplo: { room: true, rooms: true, message: true, state: true, tools: true }.

Flujo recomendado de creación

1. neblla_validate_requirements — recorrer el mapa de decisiones (abajo) hasta have_enough_context: true. 2. neblla_get_llms — cargar core + las secciones de los módulos encendidos (tras crear la app, con su appId). 3. neblla_create_app({ name, decisions }) — crea la app, scaffoldea su página con el código de ejemplo de sus módulos y escribe la config completa. Devuelve el appId. 4. neblla_upload_file (y neblla_get_file + neblla_edit_file para cambiar trozos, neblla_move_file para mover) — editar los ficheros scaffoldeados siguiendo la estructura canónica de core.txt. Todo cae en el borrador de la app. 5. neblla_promote({ action: 'publish' }) — publicarlo entero al acabar; con pro, el entorno de una app nueva, los usuarios lo tienen en el acto. 6. neblla_get_app_url — obtener la URL canónica y entregarla al usuario.

Publicar en la galería (neblla_publish_app) es un paso aparte y opcional.

El flujo de decisiones

neblla_validate_requirements recorre el MISMO mapa de decisiones que el wizard del dashboard: las dos superficies son la misma entrevista. El contrato para el modelo que crea la app:

1. Pasa en decisions todo lo que la petición del usuario ya responde o implica. 2. La respuesta lista cada decisión pendiente con how_to_infer (cómo deducirla tú mismo) y ask_user (si merece molestar al humano). Responde tú mismo todo lo que puedas. Solo las decisiones devueltas en ask_user_questions que de verdad no puedas inferir se preguntan al usuario — todas juntas, en un único mensaje. 3. Repite con el set completo hasta have_enough_context: true. Las decisiones con default y ask_user: never se autocompletan; las "preguntables" (p. ej. aiPayer, que decide quién paga) exigen respuesta explícita — tuya o del usuario — y nunca se rellenan en silencio. 4. Pasa el decisions devuelto tal cual a neblla_create_app. El campo plan de la respuesta te enseña antes de crear qué patrón, piezas y config van a salir.

Las decisiones: kind (game|app), players (single | lobby-only | multi — single = un dispositivo; lobby-only = todos en un único espacio común sin salas; multi = salas separadas), board y master (solo cuando players=multi: una pantalla común que solo muestra, alguien que dirige la sesión; cada uno trae su pieza de ejemplo), modules (la lista de módulos neblla.* además de auth y db, que van siempre, y de los del multijugador, que fija players: social, shop, inbox, ai, api, anticheat, groups, community, business, tools, world, o []; cada opción trae lo que hace, lo que necesita y lo que cuesta, y se decide con el dev contándole el coste y lo que le obliga; una combinación que no se sostiene, como anticheat en una app de un dispositivo, vuelve en problems, y lo que el dev debe saber de lo elegido en notes), connections (all|p2p|server), roomsPolicy (ephemeral|public|private|mixed), matchmakingMode (nocode|custom), aiPayer (off|browser|server; solo con ai en modules), sells (items|subs|packs; con shop: elige el ejemplo de compra), bookingPay (credits|booking|free; con business: cómo se pagan las reservas con las que nace la app), palette ({primary, secondary, alert} en hex — elígela TÚ según el carácter de la app) y typography (modern|editorial|techy|serif|playful — también tuya).

El scaffold resultante: la página (la del juego según players, o home para una app de un dispositivo, con lo que la app es —reservas, tienda, comunidad, grupos— en el centro) + el código de ejemplo de cada módulo de la app (login y perfil, salas, jugadores, chat, tienda, reservas, comunidad, grupos, caja de IA, amigos, inbox, dados con tools, testigos con anticheat, claves con api), tematizado con la paleta y tipografía vía variables CSS en main.css. Lo que no está en la app no sale. Los ficheros server/ salen del patrón; con tools, room.js trae el dado. Una app con salas nace con un solo ejemplo de sala: el servidor pone el estado, los clientes lo pintan y hablan por message. Con árbitro (ajedrez, cartas), pantalla y mandos (al estilo Jackbox) o todos a la vez (una pizarra) son recetas en salas.txt, con su código. Tu trabajo después es EDITAR esos ficheros, no reescribirlos desde cero. Para cambiar la paleta o la tipografía más tarde, neblla_retheme_app (o el botón "Cambiar tema" del editor) re-hornea solo esas variables y el enlace de fuentes: no hace falta tocar main.css a mano ni se pierde lo que hayas editado.