Auto-Ontology auditado: 9.026 estrellas, 46 watchers y un conector SQLite que devuelve Ada dos veces sin reportar error

Auto-Ontology suma 9.026 estrellas, 46 watchers y ningún release en GitHub, pero su conector SQLite devuelve Ada dos veces sin dar error.

La primera frase del README de Auto-Ontology, de NVIDIA, es una promesa que acaba incriminando al propio proyecto:

Los agentes pueden recuperar documentos y consultar bases de datos, pero la fiabilidad limita la analítica agéntica: una métrica de ingresos respondida más rápido no vale nada si el número está mal.

Estoy de acuerdo con esa frase. Es el diagnóstico correcto de por qué los demos de text-to-SQL no sobreviven al contacto con un equipo de finanzas. El problema es que la herramienta construye después una capa semántica cuyo único propósito es que el número esté bien, y publica tres conectores de base de datos que —lo comprobé en esta máquina— devuelven números silenciosamente erróneos cada vez que un join produce dos columnas con el mismo nombre.

Esta es la salida real del conector SQLite del propio repositorio, ejecutado contra un join de dos tablas con cuatro columnas seleccionadas:

columns: ['id', 'id', 'name', 'name']
values : [[1, 1, 'Ada', 'Ada']]
expected: [[1, 100, 'Ada', 'first order']]

El id del cliente (1) sobrescribió el id del pedido (100), y el nombre Ada sobrescribió first order. error vale None. No hay advertencia, ni reintento, ni excepción. Si un agente ejecuta esa consulta y responde «dos filas, cliente Ada», ningún componente del pipeline sabe que está mintiendo.

Ese es el hallazgo principal de esta auditoría. El resto del artículo trata de la maquinaria alrededor: qué publicó NVIDIA realmente, qué no dice el número de estrellas, qué admiten los propios mantenedores sobre el límite de fiabilidad y qué debería verificar un equipo antes de conectar esto a algo que produzca cifras que una persona vaya a usar para decidir.

Qué es Auto-Ontology en la práctica

Quitando el marketing, la arquitectura es convencional y sensata. La ingesta lee las fuentes relacionales, perfila columnas, muestrea valores y pide a un modelo un primer borrador de ontología: términos (conceptos de negocio mapeados a columnas), atributos SQL (expresiones revisadas como margen o total acumulado) y relaciones (cómo se unen las tablas, incluidas tablas puente). Todo eso se guarda en Postgres con embeddings en pgvector. Si alguna vez has montado un pipeline RAG con grafo —la forma que tiene LLM Graph Builder— la mitad de ingesta te resultará familiar; la diferencia es que Auto-Ontology mantiene el grafo en Postgres y trata la certificación humana como una etapa obligatoria y no opcional.

En el momento de la pregunta, un agente clasifica la intención, extrae entidades, recupera términos y atributos candidatos por búsqueda de embeddings, escribe SQL a partir de ellos, valida los valores de filtro contra los datos vivos, repara el SQL cuando una comprobación falla y devuelve la respuesta junto a su SQL y los pasos que siguió.

ComponenteTecnologíaFunciónPuerto
Frontend / pasarelaNext.js 16, Better Auth, PrismaUI web, autenticación, API pública3000
BackendFastAPI, LangChainAgente NL-a-SQL, catálogo3001
Worker de ingestaFastAPIIngesta, embeddings, compilación3002
Servidor MCPFastMCPHerramientas de solo lectura3003
Postgres + pgvectorPostgreSQL 17Catálogo, ontología, vectores5432

Soporta diez motores de origen: PostgreSQL, MySQL, Databricks, Snowflake, ClickHouse, Trino, Kyuubi, HeavyDB, DuckDB y SQLite. La inferencia pasa por NVIDIA NIM por defecto (nvidia/nemotron-3.5-lightning-30b-a3b tanto para el rol de razonamiento como para el de no razonamiento), y cada rol se configura con un triplete <PREFIX>_ENDPOINT / _API_KEY / _MODEL que cae a un DEFAULT_MODELS compartido. Es decir: usar un NIM autoalojado o cualquier endpoint compatible con OpenAI son tres variables de entorno.

La parte que me parece genuinamente bien diseñada es la que recibe menos atención: la superficie MCP. El equipo tomó un OpenAPI de 119 operaciones y publicó 9 herramientas curadas en lugar de exponer la API entera. Su propio razonamiento, en un comentario del código:

La especificación describe 87 operaciones. Exponerlas todas sería activamente dañino: la selección de herramientas del agente se degrada mucho antes de esa cifra, y la mayor parte de la superficie —proveedores SSO, gestión de tokens, prompts personalizados, control de compilación— no tiene por qué ser invocable por un agente.

Medí la consecuencia construyendo el servidor desde la distribución mcp/ del repositorio y pidiéndole su lista de herramientas: 9 herramientas, 6.286 bytes de nombre + descripción + esquema JSON, unos 1.571 tokens. La especificación completa pesa 437.217 bytes. Exponerla sin filtrar habría costado unas 70 veces más contexto para un agente peor. Además, las descripciones están escritas para quien va a llamar la herramienta, no para quien lee documentación de API, algo más raro de lo que debería ser.

Ahora bien, ese comentario contiene una cifra desactualizada, y importa más de lo que parece. Lo veremos en la sección de derivas.

Los números que el README no imprime

Datos de la API de GitHub, leídos el 2026-11-07:

MétricaValor
Estrellas9.026
Watchers (subscribers_count)46 (0,51% de las estrellas)
Forks725 (8,03%)
Creado2026-04-27
Commits1.367
Contribuidores13
Issues abiertas34 (más 28 pull requests abiertos)
Releases en GitHub0
Tags de git1
Ramas remotas101

Dos de estas cifras merecen un párrafo cada una.

46 watchers. Los watchers son quienes pidieron ser notificados; las estrellas son marcadores. En esta serie de auditorías ese cociente ha oscilado entre 0,22% y 0,94%. Con 0,51%, Auto-Ontology queda en el medio: mejor que varios proyectos con diez veces su perfil de commits-y-abandono, peor que un proyecto con base de usuarios real. El dato más raro es el de forks: el 8,03% de quienes pusieron estrella lo bifurcaron, una proporción alta para un proyecto que no acepta pull requests externos. La gente no solo lo guarda en marcadores: lo bifurca, probablemente porque bifurcar es la única vía que le queda abierta.

1.367 commits en ocho meses, y el 54,5% de dos personas. La API devuelve 13 logins, con DinaLaptii en 503 commits y yuvalshkolar en 242. git shortlog sobrecuenta, porque tres mantenedores firman con dos nombres de autor distintos (dlaptii/DinaLaptii, Liav Nave/liav nave, Lio Fleishman/liofnv); la API ya unificó esas identidades, y 503 + 242 = 745 de 1.367 es el 54,5% en las dos cuentas principales. Factor bus: dos.

El volumen mensual de commits cuenta la historia que la curva de estrellas esconde:

MesCommits
2026-04144
2026-05125
2026-06295
2026-07257
2026-08217
2026-09165
2026-10146
2026-11 (6 días)18

Máximo en junio, descenso sostenido desde entonces: octubre es el 50,5% del pico de junio. Es un proyecto que se construyó rápido dentro de NVIDIA, se abrió a finales de abril y ahora está en modo mantenimiento-con-novedades mientras las estrellas siguen subiendo.

Cero releases, un tag, y dónde viven realmente los artefactos

El único tag se llama pre-main-merge-backup. No es una versión. No hay tag v1.2.0 ni release en GitHub, en un repositorio cuyo pyproject.toml, mcp/pyproject.toml y Chart.yaml de Helm dicen todos 1.2.0.

Antes de publicar «no hay releases» como hallazgo, comprobé si el proceso vivía simplemente en otro sitio. DEPLOYMENT.md dice que sí, y tiene razón: los artefactos están en NGC, no en GitHub.

Cada release etiqueta sus imágenes con la versión del chart, y el chart fija sus propias imágenes a esa etiqueta.

Consulté directamente el índice de Helm de NGC (helm.ngc.nvidia.com/nvidia/index.yaml, 131.716 bytes) y encontré exactamente dos versiones del chart:

Versión del chartPublicada
1.1.02026-10-13T17:03Z
1.2.02026-11-06T18:15Z

Así que la disciplina de release existe, el desfase es de un día (subida de versión en git el 11-05, chart el 11-06), y mi sospecha inicial era falsa de una forma instructiva: un proyecto empresarial puede tener cero releases en GitHub y aun así distribuir. Vale la pena decirlo sin rodeos, porque el reflejo «0 releases = abandonado» habría sido una acusación injusta aquí.

La versión honesta del hallazgo es más estrecha y sigue siendo útil: no puedes fijar Auto-Ontology desde GitHub. No hay tag que hacer checkout, ni notas de release que leer, ni changelog que comparar. El comando de instalación de MCP que documentan es uvx --from "git+https://github.com/NVIDIA/auto-ontology.git#subdirectory=mcp", sin referencia ni versión: siempre lo que haya en main en ese momento. auto-ontology-server y auto-ontology-mcp no están en PyPI (probé los cuatro nombres plausibles; los cuatro dan 404). La reproducibilidad pasa por los digests de imagen de NGC y la versión del chart, y por ningún otro sitio.

Un residuo menor de la misma historia: el proyecto antes se llamaba de otra forma. El primer README del repositorio se titula GSF — generative semantic fabric, el package.json del frontend aún se llama gsf, y el commit del «security patch release» 0.1.1 del 2026-05-11 tocó exactamente tres archivos —frontend/package.json, pyproject.toml y uv.lock— y nada de código. Una cadena de versión no es un release.

Ejecuté el conector y devolvió la fila equivocada

El fallo está registrado como issue #408, abierta el 2026-11-04 por hyeonsang010716, y es lo más importante del tracker. No me quedé con la palabra del reportero. Extraje auto_ontology/connectors/sqlite.py, base.py y sus dos dependencias a un paquete mínimo, instalé el rango de dependencias fijado (pandas>=2.3.3,<3, resuelto a 2.3.3) y ejecuté su propia reproducción.

El mecanismo es una línea, y es el mismo error en tres sitios:

# auto_ontology/connectors/sqlite.py, _execute()
rows = cur.fetchall()
return pd.DataFrame(
    [dict(row) for row in rows], columns=[col[0] for col in cur.description]
)

conn.row_factory es sqlite3.Row. dict(row) indexa por nombre de columna, así que c.id y o.id se convierten ambos en la clave id, y gana la segunda. El argumento columns= pide entonces cuatro etiquetas a pandas contra un diccionario que tiene dos claves, y pandas repite el valor superviviente en ambas columnas. Postgres tiene la misma forma vía psycopg.rows.dict_row; MySQL, vía cursor(dictionary=True).

La salida medida por motor que reporta la issue, y que mi ejecución en SQLite reprodujo exactamente:

ConectorColumnas devueltasFila devueltaEsperado
Esperadoid, id, name, name1, 100, Ada, first order—
Postgres 17.7id, name100, first orderdesaparecen los datos del cliente
MySQL 9.4id, id, name, name100, 100, first order, first orderel pedido se duplica sobre el cliente
SQLiteid, id, name, name1, 1, Ada, Adael cliente se duplica sobre el pedido
DuckDBid, id_1, name, name_11, 100, Ada, first ordercorrecto

Poner alias lo evita. Nada obliga a un agente a poner alias. Y el fallo llega al camino de text-to-SQL: en Postgres, _run_sql devuelve [{"id":100,"name":"first order"}] con error=None, así que el bucle de reparación —el mecanismo sobre el que se construye toda la arquitectura— no tiene nada que reparar.

El detalle que convierte esto en algo más que un bug: el proyecto ya tiene una defensa contra columnas duplicadas, y esa defensa no puede ver el bug. _deduplicate_result_columns se añadió en el PR #397 precisamente para esta clase de problema, pero opera sobre el DataFrame después de que el conector lo haya construido. Para entonces la colisión ya ocurrió. Su test unitario pasa porque construye el frame a mano con dialect="postgres", un frame que el conector de Postgres es estructuralmente incapaz de producir.

Existe un arreglo: el PR #422 de un contribuidor externo, abierto desde el 2026-11-05, que cambia los tres conectores a filas de tuplas y toma los nombres de cursor.description, como ya hacen los conectores de Trino y Snowflake.

La pregunta del quickstart no termina contra el endpoint por defecto

La issue #440, abierta el 2026-11-06, es la segunda que debería preocupar a quien planee un piloto. El reportero ejecutó el quickstart del README —Docker Compose, API alojada de NVIDIA, nvidia/nemotron-3.5-lightning-30b-a3b— y la pregunta de ejemplo sobre los pendrives con forma de sushi nunca recibe una respuesta completa.

El mecanismo es un desajuste de versiones en el camino de salida estructurada. langchain-nvidia-ai-endpoints==1.4.3 (la versión que fija la imagen del backend) envía un esquema JSON de dos maneras: response_format al estilo OpenAI, y un sobre nvext: {guided_json: ...}. Contra el endpoint vivo:

Forma de la peticiónResultado
response_format: {type: json_schema}200, pero contenido vacío — el parser devuelve None
nvext: {guided_json: schema}400 — unknown field 'guided_json'
guided_json: schema en el nivel superior200 con JSON correcto

Como _FallbackRunnable relanza la última excepción, el error que se ve es el 400; el fallo silencioso de contenido vacío queda enmascarado. Cada llamada de no razonamiento falla tres veces, cae al modelo de razonamiento, y cada paso del pipeline pasa de segundos a unos dos minutos. El reportero midió una respuesta completa de 10 a 15 minutos en lugar de uno, terminando en unconstructable_sql_response y una respuesta tibia.

Esta no pude reproducirla: requiere una clave nvapi-, que no tengo en este entorno. Es un solo reporte, sin comentarios, de hace cuatro días, y puede quedar resuelto la semana que viene con un cambio de versión. Pero es la clase de fallo que le cuesta a un equipo dos días de evaluación antes de que a alguien se le ocurra leer el tracker; así que si estás evaluando, lee primero auto_ontology/utils/llm_invoke.py y comprueba si guided_json se enlaza en el nivel superior.

El quickstart publica los dos puertos que el README dice que hay que mantener privados

Esto lo verifiqué de forma estática, desde el repositorio, y es estructural, no un bug puntual.

README, línea 271:

Mantén los puertos 3001 y 3002 en una red privada. FastAPI confía en la identidad de usuario que el frontend reenvía en la cabecera x-auto-ontology-user-id, y los endpoints del servicio de ingesta (ingest, delete, reset, compile) no tienen autenticación propia.

El código lo confirma, y sin rodeos. auto_ontology/server/identity.py, línea 24:

FastAPI no debe ser accesible públicamente porque la cabecera no se autentica aquí de forma independiente.

Y resolve_internal_user() hace exactamente lo que el docstring admite: lee la cabecera, la recorta y devuelve el string que haya. Sin firma, sin secreto compartido, sin mTLS.

Ahora docker-compose.yml, el archivo que ejecuta el quickstart, líneas 47 y 76:

  auto-ontology:
    ports:
      - "3001:3001"
  ingestion-service:
    ports:
      - "3002:3002"

Un mapeo HOST:CONTAINER sin IP se enlaza a 0.0.0.0. Es decir: el arranque local documentado publica, en todas las interfaces, el backend que confía en una cabecera y el worker de ingesta sin autenticación, precisamente los dos servicios que el mismo documento dice mantener privados. Es un stack de desarrollo local y el README advierte que cambies las contraseñas por defecto, así que esto no es una afirmación de vulnerabilidad remota: es un desajuste entre el consejo y el valor por defecto. Pero «solo es localhost» deja de ser cierto en el momento en que alguien ejecuta este compose en una máquina de build compartida o en una VM de nube con el grupo de firewall abierto por defecto, que es como suelen aparecer los entornos de evaluación.

Las derivas que pude medir

Cuatro inconsistencias, todas verificables en el árbol actual:

El reranker tiene dos valores por defecto distintos en el mismo README. La línea 63 dice nvidia/llama-nemotron-rerank-vl-1b-v2. La línea 415 dice nvidia/nemotron-3.5-rerank-8b. .env.example línea 55 coincide con la 415, y añade un comentario de que el catálogo sirve el reranking desde ai.api.nvidia.com y no desde integrate.api.nvidia.com — una distinción que te romperá la configuración si la tomas de la línea 63.

El recuento de herramientas curadas está documentado como 87 operaciones; la especificación tiene 119. Es un +36,8%. El argumento del docstring («exponerlas todas sería activamente dañino») solo se refuerza con la deriva, porque las operaciones nuevas son en su mayoría justo el tipo de cosa que dice no exponer, pero la cifra que se lleva el lector es falsa.

La tabla de componentes lista «Relational Database» como tecnología de Postgres. El hilo de HN se dio cuenta antes que yo, y es un error muy apropiado para un proyecto dedicado a eliminar la deriva semántica.

docs/mcp.md sigue describiendo el repositorio como interno de NVIDIA y necesitado de credenciales de GitHub (issue #403, abierta). El repositorio es público desde abril.

Una cosa que no deriva: la copia del OpenAPI que viaja dentro del paquete Python y la de docs/ son idénticas byte a byte — mismo MD5, 96625768bb275b472293ec2d6046af6a, 437.217 bytes. La puerta de CI que lo exige funciona de verdad, y por eso la cifra obsoleta de arriba es un comentario viejo y no un problema sistémico.

También comprobé el pipeline de firma de skills que describe AGENTS.md, porque las skills de agente firmadas son una afirmación que vale la pena probar. La issue #432 dice que las firmas ya no coinciden. Ejecuté el verificador del reportero —solo biblioteca estándar, payloads DSSE decodificados, SHA-256 comparado— y obtuve la misma respuesta: 6 de 21 recursos firmados no coinciden, y los seis son BENCHMARK.md y skill-card.md en las tres skills. Quitar la cabecera SPDX de 144 bytes que añadió el PR #363 el 2026-10-12 restaura el digest firmado en todos los casos. Es una re-firma olvidada, no manipulación — exactamente como se reportó.

«No acepta pull requests externos» frente a 18 PR pendientes de fuera

CONTRIBUTING.md, línea 9, es inequívoco:

Este proyecto no acepta pull requests externos. Los cambios de código los hace el equipo de mantenedores de Auto-Ontology.

El README lo repite en la línea 28. Y el proyecto está a la altura de ese planteamiento: tres skills, un AGENTS.md que asigna cada acción del usuario a la skill que la posee, un CLAUDE.md que avisa a los mantenedores de qué puertas de CI son las fáciles de olvidar. Es un repositorio organizado como equipo interno, publicado como código fuente.

Mientras tanto, en el momento de escribir esto hay 28 pull requests abiertos, y 18 vienen de cuentas que no están en la lista de contribuidores:

PRAbiertoAutorQué arregla
#3952026-10-30JGalegoclaves primarias y foráneas declaradas en DuckDB
#4112026-11-04piersrobertsembeddings estilo OpenAI frente al vector store de 2048
#4122026-11-04joemcelroyvector store de Elasticsearch
#4142026-11-04cmscmaddFKs de Postgres que apuntan a otro esquema
#4172026-11-05blueamethystdatabase_name para list_schemas
#4192026-11-05sandeepvijayarao09ocultar valores de muestra con etiqueta PII de los prompts
#4202026-11-05blueamethystevitar alucinación de SQL
#4212026-11-05Aswinesagconector de BigQuery
#4222026-11-05Husseinadqel arreglo de columnas duplicadas de la issue #408
#4232026-11-05klhaislar fallos por consulta en PostgresVDB.retrieval
#4242026-11-05anush008vector store de Qdrant
#4292026-11-05HoneyTyagiinulabilidad en Databricks
#4372026-11-06anupammebetter-auth 1.7.4 → 1.7.7

Ninguno tiene revisión. El más antiguo lleva siete días abierto. El patrón es el previsible al combinar una política documentada de no-PR con un lanzamiento de 290 puntos en Hacker News: la comunidad presenta arreglos como pull requests de todos modos, y el proyecto los trata como sugerencias que no pidió. Es una decisión de gobernanza legítima. Sí implica que el arreglo de la corrupción silenciosa de datos vive en una rama que nadie está obligado a leer, y que quienes reportan bugs, después de leer CONTRIBUTING.md, cada vez meten el parche dentro del cuerpo de la issue, lo que lo hace invisible para las herramientas y para git log.

Uno de esos PR merece nombrarse con cuidado: el #437 sube better-auth de 1.7.4 a 1.7.7 por CVE-2026-114607, que NVD puntúa con 9,1 y describe como una vulnerabilidad que afecta a better-auth desde 1.4.0-beta.18 hasta 1.7.7. El repositorio fija 1.7.4 en seis paquetes. Dos salvedades honestas: el disparador del CVE es el proveedor Magic Link con storeToken en plain, y frontend/auth/auth.ts registra admin, sso, apiKey y OAuth, no magic link, así que la ruta vulnerable parece inalcanzable en esta configuración; y el PR es salida automática de un escáner que dice de sí mismo «no he verificado que tu código llegue a la función afectada». La recomendación sigue siendo subir de versión —un patch no cuesta nada—, pero el 9,1 no significa que este repositorio esté siendo explotado.

Lo que objetó Hacker News y el README nunca responde

La historia del lanzamiento (2026-11-03) llegó a 290 puntos y 139 comentarios. Tres objeciones se repiten, y ninguna se responde en la documentación del repositorio:

Es una capa semántica que no resuelve la brecha semántica. La versión más fuerte: los nombres de columna suelen estar mal, y el conocimiento sobre por qué están mal vive en las personas, no en information_schema. Un comentarista se preocupa por el directivo que confía en una respuesta que no puede auditar; otro sostiene que una ontología con LLM debería leer el código de la aplicación para recuperar el contexto de cada columna, y esta no lo hace.

¿Por qué no RDF/OWL/SPARQL? Varios preguntan qué aporta esto sobre treinta años de estándares de web semántica — la misma pregunta que una base de datos de grafos como TerminusDB tiene que responder, y que responde en la dirección contraria. La respuesta del README va por otro eje: importación y exportación de modelos Apache Ossie, que trata de intercambiar modelos semánticos, no de razonamiento ontológico formal. Si eso basta es una pregunta real, y el proyecto no la argumenta.

El README parece generado. No es una queja de estilo cuando el tema es un motor de ontologías. Varios comentaristas describen haber rebotado con la prosa, y uno dice que tuvo que pasarla por un modelo para que fuera comprensible. Hay una brecha irónica entre un producto cuyo trabajo es hacer el significado legible para las máquinas y una portada que los humanos reportan no poder interpretar.

La duda de la clave de API sí está respondida en el README, y el hilo muestra que la responden otros comentaristas en lugar de los autores: nvapi- solo hace falta para endpoints alojados por NVIDIA; cualquier endpoint compatible con OpenAI o un NIM autoalojado sirve.

Qué verificar por tu cuenta antes de confiar en un número

Digan lo que digan el resto de esta auditoría, las comprobaciones que importan son baratas y concretas. Hazlas sobre tus datos, no sobre el ejemplo.

  1. Integridad de columnas duplicadas, en tu motor. La reproducción son nueve líneas y en SQLite no necesita servidor. Ejecuta el join de la issue #408 contra SQLiteDatabase, luego contra PostgresDatabase, luego contra el que uses, y compara df.values.tolist() con la misma consulta con alias. Si la versión sin alias difiere, la capa semántica que va encima es decorativa.
  2. Comprueba si tu versión tiene el arreglo. grep -n "dict_row\|dictionary=True\|dict(row)" auto_ontology/connectors/{postgres,mysql,sqlite}.py. Filas de tuplas más cursor.description es la forma correcta; filas de diccionario es el bug.
  3. Prueba la salida estructurada antes de confiar en el pipeline. Manda un esquema trivial a tu endpoint de tres maneras —response_format, nvext.guided_json y guided_json en el nivel superior— y revisa no solo el código de estado sino el contenido parseado. Un 200 con contenido vacío es el fallo que cuesta un día.
  4. Lee la frontera de confianza como código, no como prosa. auto_ontology/server/identity.py tiene 42 líneas. Léelo, y luego lee los mapeos de puertos de docker-compose.yml o de los values de Helm que piensas desplegar.
  5. No tomes el número de términos como señal de calidad. La compilación de ejemplo del README sobre Wide World Importers produjo 31 términos. Eso es un dato sobre una base de datos y un modelo por defecto, no un benchmark.
  6. Pregunta al tracker, no al README. Hay 34 issues abiertas, y las dos más consecuentes (#408 corrupción de datos, #440 quickstart roto) tienen cuatro días y cero comentarios. El silencio en un tracker no es un arreglo.

Y para todo lo que implique predicciones: definir KUMO_RFM_API_KEY enruta las preguntas predictivas a un servicio alojado que sube las tablas conectadas a él, limitado por KUMO_MAX_TABLES (20 por defecto) con KUMO_MAX_ROWS_PER_TABLE sin límite salvo que se fije. El README dice que revises qué envía antes de activarlo. Hace bien en decirlo.

Veredicto

Auto-Ontology no es un demo, y no es basura. La arquitectura es defendible, la curaduría de MCP es mejor que la de casi todo lo que se publica en este espacio, la puerta de OpenAPI se ejecuta de verdad, y el proceso de release existe aunque GitHub haga parecer que no. Un equipo con un almacén Postgres grande, disposición a certificar términos a mano y un equipo de plataforma de dos personas podría obtener valor real del chart 1.2.0 actual.

Lo que todavía no es: una herramienta que instalas y apuntas a un almacén sin leerla. El modo de fallo que se construyó para evitar —un número seguro de sí mismo y equivocado— está presente en su propia capa de conectores, en el camino por defecto, en tres de los diez motores soportados, con error=None, y el arreglo lleva esperando en un pull request comunitario sin revisar desde el 2026-11-05. La primera frase del README es el estándar correcto. Exígele al proyecto que lo cumpla: ejecuta el join, no pongas alias y mira los valores.

Preguntas frecuentes

¿Funciona sin una clave de API de NVIDIA? Sí, si apuntas los tripletes de modelo a tu propio endpoint. DEFAULT_MODELS_ENDPOINT, _API_KEY y _MODEL controlan todo, y <ROLE>_ENDPOINT/_API_KEY/_MODEL sobrescriben por rol. La clave nvapi- solo hace falta para endpoints alojados por NVIDIA.

¿Está en PyPI? No. Probé auto-ontology-server, auto-ontology-mcp, auto-ontology y auto_ontology_mcp: los cuatro dan 404. Se instala desde el chart de Helm de NGC, las imágenes OCI de NGC, o un checkout de git de main.

¿Por qué no hay releases ni tags de versión en GitHub? Los releases se publican en NGC, y DEPLOYMENT.md lo documenta. En el índice de Helm solo existen 1.1.0 (2026-10-13) y 1.2.0 (2026-11-06). El único tag de git, pre-main-merge-backup, es una marca de respaldo, no una versión.

¿Puedo contribuir un arreglo? Oficialmente no: CONTRIBUTING.md dice que no se aceptan pull requests externos y que el canal sancionado son las issues. En la práctica, 18 de 28 PR abiertos son de no contribuidores, incluido el arreglo del bug de corrupción de datos.

¿El servidor MCP es de solo lectura? En la práctica sí. Las 9 herramientas mapean a lecturas salvo ask_question (streaming) y check_answerable (un POST que puntúa la cobertura sin mutar nada). Las escrituras van por la superficie /api/... de Next.js, y MCP no tiene credencial propia: cada llamada corre como el usuario autenticado.

¿Qué tamaño tiene? 434 archivos Python y 78.836 líneas de código en auto_ontology, más 43.655 líneas de tests (159 archivos) — una proporción test/código de 0,55. Añade 1,5 MB de frontend TypeScript y 1,2 MB de PLpgSQL. El clon pesa 29 MB.