Carmen LabsCarmen Labs

Schema Reference

Every field in mview.json, with valid and invalid examples.

Schema Reference

Every mview.json manifest must validate against:

https://schemas.carmenlabs.com/mview/v1/schema.json

Field table

FieldTypeRequiredDescription
$schemastring (const)yesMust be exactly https://schemas.carmenlabs.com/mview/v1/schema.json.
idstringyesUnique identifier. Pattern: ^[a-z0-9][a-z0-9._-]*$.
namestringyesHuman-readable display name.
descriptionstringnoHuman-readable summary of what the view shows.
versionstringyesSemantic version of the MView itself: MAJOR.MINOR.PATCH.
promptstringyesPrompt used to generate this mutation.
runtimeobjectyesRendering runtime required by the MView.
runtime.environmentstringyesExecution environment. V1 allows "web", "desktop", "terminal", or "other".
runtime.rendererstringyesRequired renderer/adapter. This is an open implementation-defined identifier, for example "html", "html+js", "react", "solid", or "pdf".
runtime.versionstringnoCompatible semver range for the renderer, for example "^19.0.0".
authorstringnoAuthor name or identifier.
licensestringnoSPDX license identifier.
iconstringnoRelative path to an icon asset.
acceptsstring[]noCapabilities this MView needs from the runtime. See Capabilities.
sourceobjectnoThe source file or directory this MView is derived from.
source.kind"file" | "directory"noSource type. Defaults to "file" when omitted.
source.pathstringyes, if source presentRelative path to the source file or directory.
source.adaptersstring[]noSource Adapter identifiers, in preference order, used to transform the original file.
source.filesobject[]yes, if source.kind is "directory"Non-empty selection of files within the source directory. Files are not discovered implicitly.
source.files[].pathstringyesFile path relative to source.path. Must be unique within the selection.
source.files[].acceptsstring[]yesCapabilities the runtime must try when normalizing this file, in order.
source.files[].adaptersstring[]noSource Adapter identifiers, in preference order, used for this original file.
source.files[].contentHashstringnoSHA-256 hash of the file bytes.
source.contentHashstringnoHash of the source file or, for a directory, aggregate hash of the selection and its contents.
entryobjectyesExecutable entry points.
entry.parserstringyesRelative path to the parser module.
entry.componentstringyesRelative path to the view component.
resourcesobjectnoLocation of static assets.
resources.pathstringnoRelative path to the resources directory. Default ./resources.
settingsobjectnoDefault settings exposed to parser and component.
metadataobjectnoFree-form implementation metadata. Must not drive runtime behavior.

additionalProperties: false applies at every level — manifests with unknown fields are invalid.

id

Lowercase letters, digits, dots, underscores, and hyphens only.

Valid: sales-dashboard, invoice.tax-view, logs_timeline Invalid: Sales Dashboard, dashboard final, ventas/2026

prompt

The manifest must preserve the original prompt used to generate the mutation. This lets the user see how the view was created and provides an editable starting point if the source changes and the mutation is no longer compatible.

"prompt": "Create an executive view for monthly sales, top clients, and totals."

The prompt is re-executable provenance, not runtime configuration: it must not replace settings for values that directly affect rendering.

runtime

V1 defines multiple execution environments ("web", "desktop", "terminal", "other") with an explicit renderer. runtime.renderer is not a closed list of renderers supported by the specification: it is the identifier for the rendering path the manifest requires.

For environment: "web", we recommend this priority order:

  1. "html" — Pure HTML (+ inline CSS/JS or <style>/<script> tags). Simplest option, zero dependencies, works in any browser.
  2. "html+js" — HTML with separate JavaScript files for interactivity.
  3. "react" — For complex UIs that justify a framework.
  4. "solid" — Alternative to React with fine-grained reactivity.

Example with HTML (recommended for simple views):

"runtime": {
  "environment": "web",
  "renderer": "html"
}

This is the lightest option. The parser can be a simple .js file, and the component is a plain .html file. No build step, no transpilation, no framework overhead.

Example with React (for complex interactive views):

"runtime": {
  "environment": "web",
  "renderer": "react",
  "version": "^19.0.0"
}

Example with Solid:

"runtime": {
  "environment": "web",
  "renderer": "solid",
  "version": "^1.9.0"
}

runtime.version is optional and is interpreted as a compatible semver range for the renderer, not as an exact version. The specification does not require any runtime to implement a specific renderer; each implementation must document which runtime.renderer values it accepts and how to execute or produce that kind of view. Implementations must reject manifests whose environment, renderer, or version range they don't support, rather than guessing.

accepts

Declares what kind of normalized input the parser expects — a capability, not a file extension. Full list and normalizer shapes: Capabilities.

accepts describes the normalized output expected by the parser; it does not by itself select the code that reads the source. Use source.adapters or source.files[].adapters for that.

source

Optional pointer to the file or file selection this MView was derived from.

File source

source.kind is optional and defaults to "file". Therefore, the following two manifests have the same meaning:

"source": {
  "path": "../sales.csv",
  "adapters": ["csv-table"],
  "contentHash": "sha256:8d969eef6ecad3c29a3a629280e686cff8ca58e3f3f2d4d0c7d7f9f2e2f0f4ab"
}
"source": {
  "kind": "file",
  "path": "../sales.csv",
  "adapters": ["csv-table"],
  "contentHash": "sha256:8d969eef6ecad3c29a3a629280e686cff8ca58e3f3f2d4d0c7d7f9f2e2f0f4ab"
}

path is always relative to the MView directory. contentHash lets a runtime detect drift between the file and the last time the MView was created or validated, and prompt for regeneration. files MUST NOT appear in a file source.

Directory source

A directory source must declare kind: "directory" and explicitly enumerate the files that form the input:

"accepts": ["filesystem"],
"source": {
  "kind": "directory",
  "path": "../reports",
  "files": [
    {
      "path": "january.csv",
      "accepts": ["table"],
      "adapters": ["csv-table"],
      "contentHash": "sha256:111..."
    },
    {
      "path": "notes/summary.md",
      "accepts": ["markdown", "document"],
      "adapters": ["markdown-document"],
      "contentHash": "sha256:222..."
    }
  ],
  "contentHash": "sha256:333..."
}

files must contain at least one item. Its paths are relative to source.path, use / as the separator, and must be unique. They cannot be absolute, empty, contain . or .. segments, or resolve outside the directory through symbolic links. The runtime reads only the enumerated files: there is no recursive traversal or implicit inclusion of new files.

Each files[].accepts must contain at least one capability, without duplicates, and declares in preference order the capabilities the runtime will try when normalizing that file. The MView's accepts must include "filesystem", because the parser receives the full normalized collection rather than each file as a separate execution.

Canonical directory hash

Each files[].contentHash, when present, is sha256: followed by the SHA-256 of the original file bytes before normalization. source.contentHash, when present on a directory source, is calculated as follows:

  1. For each file, construct an object containing its normalized path and actual contentHash.
  2. Sort the objects lexicographically by the UTF-8 bytes of path. Comparison is case-sensitive.
  3. Serialize the array with JSON Canonicalization Scheme (RFC 8785).
  4. Calculate SHA-256 over the UTF-8 bytes of that serialization and prepend sha256:.

The logical representation before hashing is:

[
  { "path": "january.csv", "contentHash": "sha256:111..." },
  { "path": "notes/summary.md", "contentHash": "sha256:222..." }
]

The aggregate hash changes when the content, path, or membership of the selection changes, but not when only the order of source.files in the manifest changes.

entry

"entry": {
  "parser": "./parser.js",
  "component": "./view.html"
}

Both paths are relative to the MView's own directory, never absolute. For HTML-based views, the parser is typically a simple .js file and the component is a .html file whose script reads the props from the window.mview global injected by the runtime. For framework-based views (React, Solid), you would use .tsx or .jsx files that receive the props as their argument.

The parser and component contracts are specified separately: Parser Contract, Component Contract.

settings

Initial, editable configuration surfaced to the parser and/or component.

"settings": {
  "currency": "USD",
  "showTopClients": true,
  "maxRows": 10
}

Unlike metadata, settings is allowed to affect rendering.

metadata

Free-form provenance information — who/what generated the MView, when, with which model.

"metadata": {
  "createdBy": "llm",
  "model": "gpt-5.5",
  "createdAt": "2026-07-11T05:00:00Z"
}

metadata must never gate or change runtime behavior. If a value needs to affect rendering, it belongs in settings.

Full example (HTML)

{
  "$schema": "https://schemas.carmenlabs.com/mview/v1/schema.json",
  "id": "sales-summary",
  "name": "Sales Summary",
  "description": "Simple sales summary from sales.csv.",
  "version": "1.0.0",
  "prompt": "Show total sales and top 3 clients in a simple view.",
  "runtime": {
    "environment": "web",
    "renderer": "html"
  },
  "author": "Victor Avila",
  "license": "MIT",
  "accepts": ["table"],
  "source": {
    "path": "../sales.csv",
    "adapters": ["csv-table"],
    "contentHash": "sha256:8d969eef6ecad3c29a3a629280e686cff8ca58e3f3f2d4d0c7d7f9f2e2f0f4ab"
  },
  "entry": {
    "parser": "./parser.js",
    "component": "./view.html"
  },
  "settings": {
    "currency": "USD",
    "topClientsLimit": 3
  },
  "metadata": {
    "createdBy": "llm",
    "model": "gpt-5.5",
    "createdAt": "2026-07-16T21:26:00Z"
  }
}

Full example (React)

For more complex interactive dashboards:

{
  "$schema": "https://schemas.carmenlabs.com/mview/v1/schema.json",
  "id": "sales-dashboard",
  "name": "Sales Dashboard",
  "description": "Interactive dashboard with charts and filters.",
  "version": "1.0.0",
  "prompt": "Create an interactive dashboard from sales.csv with charts, filters, and drill-down.",
  "runtime": {
    "environment": "web",
    "renderer": "react",
    "version": "^19.0.0"
  },
  "author": "Victor Avila",
  "license": "MIT",
  "icon": "./resources/icon.svg",
  "accepts": ["table"],
  "source": {
    "path": "../sales.csv",
    "contentHash": "sha256:8d969eef6ecad3c29a3a629280e686cff8ca58e3f3f2d4d0c7d7f9f2e2f0f4ab"
  },
  "entry": {
    "parser": "./parser.ts",
    "component": "./Dashboard.tsx"
  },
  "resources": {
    "path": "./resources"
  },
  "settings": {
    "currency": "USD",
    "topClientsLimit": 10
  },
  "metadata": {
    "createdBy": "llm",
    "model": "gpt-5.5",
    "createdAt": "2026-07-16T21:26:00Z"
  }
}

Raw schema

The canonical machine-readable schema is served at schemas.carmenlabs.com/mview/v1/schema.json. Validate manifests against that URL directly — do not hardcode a copy where it can drift.

Referencia del esquema

Cada campo de mview.json, con ejemplos válidos e inválidos.

Referencia del esquema

Todo manifiesto mview.json debe validar contra:

https://schemas.carmenlabs.com/mview/v1/schema.json

Tabla de campos

CampoTipoRequeridoDescripción
$schemastring (const)Debe ser exactamente https://schemas.carmenlabs.com/mview/v1/schema.json.
idstringIdentificador único. Patrón: ^[a-z0-9][a-z0-9._-]*$.
namestringNombre visible para humanos.
descriptionstringnoResumen legible de lo que muestra la vista.
versionstringVersión semántica de la MView: MAJOR.MINOR.PATCH.
promptstringPrompt usado para generar esta mutación.
runtimeobjectRuntime de renderizado requerido por la MView.
runtime.environmentstringEntorno de ejecución. V1 permite "web", "desktop", "terminal" u "other".
runtime.rendererstringRenderer/adaptador requerido. Es un identificador abierto definido por la implementación, por ejemplo "html", "html+js", "react", "solid" o "pdf".
runtime.versionstringnoRango semver compatible del renderer, por ejemplo "^19.0.0".
authorstringnoNombre o identificador del autor.
licensestringnoIdentificador de licencia SPDX.
iconstringnoRuta relativa a un asset de icono.
acceptsstring[]noCapacidades que esta MView necesita del runtime. Ver Capacidades.
sourceobjectnoEl archivo o directorio fuente del que deriva esta MView.
source.kind"file" | "directory"noTipo de fuente. Si se omite, el valor es "file".
source.pathstringsí, si source está presenteRuta relativa al archivo o directorio fuente.
source.adaptersstring[]noIdentificadores de Source Adapters, en orden de preferencia, para transformar el archivo original.
source.filesobject[]sí, si source.kind es "directory"Selección no vacía de archivos dentro del directorio fuente. No se descubren archivos implícitamente.
source.files[].pathstringRuta del archivo relativa a source.path. Debe ser única dentro de la selección.
source.files[].acceptsstring[]Capacidades con las que el runtime debe intentar normalizar este archivo, en orden.
source.files[].adaptersstring[]noIdentificadores de Source Adapters, en orden de preferencia, para este archivo original.
source.files[].contentHashstringnoHash SHA-256 de los bytes del archivo.
source.contentHashstringnoHash del archivo fuente o, para un directorio, hash agregado de la selección y sus contenidos.
entryobjectPuntos de entrada ejecutables.
entry.parserstringRuta relativa al módulo parser.
entry.componentstringRuta relativa al componente de vista.
resourcesobjectnoUbicación de assets estáticos.
resources.pathstringnoRuta relativa al directorio de recursos. Por defecto ./resources.
settingsobjectnoConfiguración por defecto expuesta al parser y al componente.
metadataobjectnoMetadatos libres de implementación. No deben dirigir el comportamiento del runtime.

additionalProperties: false aplica en todos los niveles: los manifiestos con campos desconocidos son inválidos.

id

Solo letras minúsculas, dígitos, puntos, guiones bajos y guiones.

Válido: sales-dashboard, invoice.tax-view, logs_timeline Inválido: Sales Dashboard, dashboard final, ventas/2026

prompt

El manifiesto debe conservar el prompt original usado para generar la mutación. Esto permite mostrarle al usuario cómo se creó la vista y ofrece un punto de partida editable si la fuente cambia y la mutación deja de ser compatible.

"prompt": "Crea una vista ejecutiva para revisar ventas mensuales, clientes principales y totales."

El prompt es procedencia reejecutable, no configuración de runtime: no debe reemplazar a settings para valores que afecten directamente el renderizado.

runtime

V1 define múltiples entornos de ejecución ("web", "desktop", "terminal", "other") con renderer explícito. runtime.renderer no es una lista cerrada de renderers soportados por la especificación: es el identificador del camino de renderizado que el manifiesto requiere.

Renderers recomendados para web

Para environment: "web", recomendamos este orden de prioridad:

  1. "html" — HTML puro (+ CSS/JS inline o tags <style>/<script>). Opción más simple, cero dependencias, funciona en cualquier navegador.
  2. "html+js" — HTML con archivos JavaScript separados para interactividad.
  3. "react" — Para UIs complejas que justifiquen un framework.
  4. "solid" — Alternativa a React con reactividad granular.

Ejemplo con HTML (recomendado para vistas simples):

"runtime": {
  "environment": "web",
  "renderer": "html"
}

Esta es la opción más liviana. El parser puede ser un simple archivo .js, y el componente es un archivo .html plano. Sin build step, sin transpilación, sin overhead de framework.

Ejemplo con React (para vistas interactivas complejas):

"runtime": {
  "environment": "web",
  "renderer": "react",
  "version": "^19.0.0"
}

Ejemplo con Solid:

"runtime": {
  "environment": "web",
  "renderer": "solid",
  "version": "^1.9.0"
}

runtime.version es opcional y se interpreta como un rango semver compatible del renderer, no como una versión exacta. La especificación no obliga a ningún runtime a implementar un renderer concreto; cada implementación debe documentar qué valores de runtime.renderer acepta y cómo ejecutar o producir ese tipo de vista. Las implementaciones deben rechazar manifiestos cuyo environment, renderer o rango de versión no soportan, en lugar de inferir.

accepts

Declara qué tipo de entrada normalizada espera el parser: una capacidad, no una extensión de archivo. Lista completa y formas normalizadas: Capacidades.

accepts describe la salida normalizada esperada; no selecciona por sí solo el código que lee la fuente. Para eso se usan source.adapters o source.files[].adapters.

source

Puntero opcional al archivo o a la selección de archivos de la que derivó esta MView.

Fuente de archivo

source.kind es opcional y su valor por defecto es "file". Por lo tanto, ambos manifiestos siguientes tienen el mismo significado:

"source": {
  "path": "../sales.csv",
  "adapters": ["csv-table"],
  "contentHash": "sha256:8d969eef6ecad3c29a3a629280e686cff8ca58e3f3f2d4d0c7d7f9f2e2f0f4ab"
}
"source": {
  "kind": "file",
  "path": "../sales.csv",
  "adapters": ["csv-table"],
  "contentHash": "sha256:8d969eef6ecad3c29a3a629280e686cff8ca58e3f3f2d4d0c7d7f9f2e2f0f4ab"
}

path siempre es relativo al directorio de la MView. contentHash permite que un runtime detecte drift entre el archivo y la última vez que la MView fue creada o validada, y pida regeneración. files NO DEBE aparecer en una fuente de archivo.

Fuente de directorio

Una fuente de directorio debe declarar kind: "directory" y enumerar explícitamente los archivos que forman la entrada:

"accepts": ["filesystem"],
"source": {
  "kind": "directory",
  "path": "../reportes",
  "files": [
    {
      "path": "enero.csv",
      "accepts": ["table"],
      "adapters": ["csv-table"],
      "contentHash": "sha256:111..."
    },
    {
      "path": "notas/resumen.md",
      "accepts": ["markdown", "document"],
      "adapters": ["markdown-document"],
      "contentHash": "sha256:222..."
    }
  ],
  "contentHash": "sha256:333..."
}

files debe contener al menos un elemento. Sus rutas son relativas a source.path, usan / como separador y deben ser únicas. No pueden ser absolutas, estar vacías, contener segmentos . o .., ni resolver fuera del directorio mediante enlaces simbólicos. El runtime lee únicamente los archivos enumerados: no hay recorrido recursivo ni inclusión implícita de archivos nuevos.

Cada files[].accepts debe contener al menos una capacidad, sin duplicados, y declara en orden de preferencia las capacidades con las que el runtime intentará normalizar ese archivo. El accepts de la MView debe incluir "filesystem", porque el parser recibe la colección normalizada completa y no cada archivo como una ejecución independiente.

Hash canónico de un directorio

Cada files[].contentHash, cuando está presente, es sha256: seguido del SHA-256 de los bytes originales del archivo, antes de normalizarlo. source.contentHash, cuando está presente en una fuente de directorio, se calcula así:

  1. Para cada archivo, construir un objeto con path normalizado y su contentHash real.
  2. Ordenar los objetos lexicográficamente por los bytes UTF-8 de path. La comparación es sensible a mayúsculas y minúsculas.
  3. Serializar el array mediante JSON Canonicalization Scheme (RFC 8785).
  4. Calcular SHA-256 sobre los bytes UTF-8 de esa serialización y anteponer sha256:.

La representación lógica anterior al hash es:

[
  { "path": "enero.csv", "contentHash": "sha256:111..." },
  { "path": "notas/resumen.md", "contentHash": "sha256:222..." }
]

El hash agregado cambia si cambia el contenido, la ruta o la membresía de la selección, pero no si solo se reordena source.files en el manifiesto.

entry

"entry": {
  "parser": "./parser.js",
  "component": "./view.html"
}

Ambas rutas son relativas al propio directorio de la MView, nunca absolutas. Para vistas basadas en HTML, el parser es típicamente un archivo .js simple y el componente es un archivo .html cuyo script lee las props desde el global window.mview que inyecta el runtime. Para vistas basadas en frameworks (React, Solid), usarías archivos .tsx o .jsx que reciben las props como argumento.

Los contratos del parser y componente se especifican por separado: Contrato del parser, Contrato del componente.

settings

Configuración inicial editable expuesta al parser y/o componente.

"settings": {
  "currency": "USD",
  "showTopClients": true,
  "maxRows": 10
}

A diferencia de metadata, settings puede afectar el renderizado.

metadata

Información libre de procedencia: quién o qué generó la MView, cuándo y con qué modelo.

"metadata": {
  "createdBy": "llm",
  "model": "gpt-5.5",
  "createdAt": "2026-07-11T05:00:00Z"
}

metadata nunca debe condicionar ni cambiar el comportamiento del runtime. Si un valor necesita afectar el renderizado, pertenece en settings.

Ejemplo completo (HTML)

{
  "$schema": "https://schemas.carmenlabs.com/mview/v1/schema.json",
  "id": "sales-summary",
  "name": "Resumen de Ventas",
  "description": "Resumen simple de ventas desde sales.csv.",
  "version": "1.0.0",
  "prompt": "Muestra el total de ventas y los 3 clientes principales en una vista simple.",
  "runtime": {
    "environment": "web",
    "renderer": "html"
  },
  "author": "Victor Avila",
  "license": "MIT",
  "accepts": ["table"],
  "source": {
    "path": "../sales.csv",
    "adapters": ["csv-table"],
    "contentHash": "sha256:8d969eef6ecad3c29a3a629280e686cff8ca58e3f3f2d4d0c7d7f9f2e2f0f4ab"
  },
  "entry": {
    "parser": "./parser.js",
    "component": "./view.html"
  },
  "settings": {
    "currency": "USD",
    "topClientsLimit": 3
  },
  "metadata": {
    "createdBy": "llm",
    "model": "gpt-5.5",
    "createdAt": "2026-07-16T21:26:00Z"
  }
}

Ejemplo completo (React)

Para dashboards interactivos más complejos:

{
  "$schema": "https://schemas.carmenlabs.com/mview/v1/schema.json",
  "id": "sales-dashboard",
  "name": "Dashboard de Ventas",
  "description": "Dashboard interactivo con gráficos y filtros.",
  "version": "1.0.0",
  "prompt": "Crea un dashboard interactivo desde sales.csv con gráficos, filtros y drill-down.",
  "runtime": {
    "environment": "web",
    "renderer": "react",
    "version": "^19.0.0"
  },
  "author": "Victor Avila",
  "license": "MIT",
  "icon": "./resources/icon.svg",
  "accepts": ["table"],
  "source": {
    "path": "../sales.csv",
    "contentHash": "sha256:8d969eef6ecad3c29a3a629280e686cff8ca58e3f3f2d4d0c7d7f9f2e2f0f4ab"
  },
  "entry": {
    "parser": "./parser.ts",
    "component": "./Dashboard.tsx"
  },
  "resources": {
    "path": "./resources"
  },
  "settings": {
    "currency": "USD",
    "topClientsLimit": 10
  },
  "metadata": {
    "createdBy": "llm",
    "model": "gpt-5.5",
    "createdAt": "2026-07-16T21:26:00Z"
  }
}

Esquema raw

El esquema canónico legible por máquina se sirve en schemas.carmenlabs.com/mview/v1/schema.json. Valida manifiestos directamente contra esa URL: no hardcodees una copia que pueda desactualizarse.