Documentación de Concentus
Qué hace la aplicación, por qué lo hace así y dónde hay que hacer clic. Escrito contra la app tal como se distribuye — donde algo es una limitación, lo dice, en vez de dejar que lo descubras tú.
Qué es
Una app de escritorio para construir y ejecutar equipos de agentes de IA.
Dibujas un flow en un lienzo: un disparador, uno o más agentes, y las herramientas y datos a los que pueden llegar. Concentus lo ejecuta con la sesión de Claude que ya tienes en tu máquina — sin servidor que desplegar, sin base de datos que aprovisionar, sin API key que pegar.
El flow que dibujas es el flow que se ejecuta. No hay ningún archivo de configuración detrás del dibujo que pueda contradecirlo, y esa es la propiedad que hace que un lienzo merezca la pena.
Instalación
Windows, macOS y Linux. Un instalador, nada más.
Descárgalo desde la página de descargas y ábrelo. La app lleva su propio runtime de Java y su propio PostgreSQL, así que no hay nada que instalar aparte.
Para ejecutar el backend por su cuenta — un servidor, un contenedor, una máquina ante la que no se sienta nadie:
Gestores de paquetes
También se puede instalar con un gestor de paquetes — lo que esquiva el aviso de SmartScreen que recibe una descarga sin firmar desde el navegador, porque el archivo nunca lleva la marca de origen web del navegador:
# Windows — scoop (the bucket lives in the main repository)
scoop bucket add concentus https://github.com/Gergilcan/concentus
scoop install concentus
# Windows — winget
winget install concentus
# macOS — Homebrew
brew tap gergilcan/concentus
brew install --cask concentus
# Anywhere with Node — fetches the right installer from Releases
npx concentus
Actualizar: winget, brew y los instaladores normales conservan el actualizador integrado en
la app; una instalación con scoop se actualiza con scoop update concentus.
En Windows, que SmartScreen avise sobre el .exe descargado es normal:
el instalador aún no está firmado, y Windows lo dice de toda descarga sin firmar. Más
información → Ejecutar de todas formas sigue adelante; los gestores de paquetes de
arriba evitan el aviso por completo. La compilación para macOS no tiene ningún muro
equivalente — está firmada y notarizada, así que Gatekeeper la abre como cualquier app
cercana a la App Store.
El backend a pelo
java -jar concentus-backend.jar
Sin ningún entorno, eso arranca un PostgreSQL integrado, genera su propia clave de cifrado y
pide una primera cuenta en http://localhost:8080.
Los flows se ejecutan a través de Claude Code en la máquina que corre el backend, o contra la API de Anthropic con una clave. La pantalla de configuración pregunta cuál, e instala e inicia sesión por ti si eliges la primera. Ver Pagar las ejecuciones.
Primer arranque
Crea la cuenta dueña de la instalación.
El primer arranque muestra una pantalla de configuración. Crea una cuenta con un correo y una contraseña, o inicia sesión con Google, Microsoft o Discord si has registrado alguno — en cualquier caso, la primera identidad que cruza la puerta administra la instalación.
Todos los que vienen después llegan como Lector. Llegar con una cuenta de empresa válida demuestra quién es alguien, no qué debería poder cambiar.
La interfaz habla inglés, español y catalán. Sigue el idioma de tu sistema por defecto; la elección vive junto al tema en Recursos → Ajustes, se aplica al instante y pertenece a este navegador, no a la instalación.
En un despliegue ante el que no se sienta nadie, define CONCENTUS_ADMIN_EMAIL
y CONCENTUS_ADMIN_PASSWORD antes del primer arranque. Si no, la ventana entre
que el puerto se abre y tú llegas a él es una ventana en la que otra persona podría
reclamar la instalación.
Pagar las ejecuciones
Una suscripción que ya tienes, o una clave facturada por token.
La pantalla de configuración lo pregunta una vez, antes de instalar nada — porque la respuesta decide si hace falta instalar algo.
Tu suscripción de Claude
La opción por defecto, y la más barata: los flows se ejecutan a través de Claude Code en
esta máquina, con la suscripción que ya pagas. No hay clave que cuidar, ni segunda factura
por lo que quepa en la bolsa de uso no interactivo de Claude Code de tu plan — Anthropic
mide esa bolsa por separado de tus sesiones interactivas, la página de Uso mide lo que ha
consumido esta máquina, y un flow puede recurrir a una API key o a un modelo local cuando se
agota. Necesita la CLI instalada y con la sesión iniciada una vez, y Concentus hace ambas
cosas desde la pantalla de configuración: un botón ejecuta el instalador oficial de
Anthropic, y se abre un terminal en el propio inicio de sesión — no en un prompt
donde lo siguiente que hay que saber es que se escribe /login.
El binario instalado se añade también a tu PATH, así que claude es un comando
que tienes a partir de entonces, y no algo que solo Concentus sabe encontrar. En Windows eso
es el Path por usuario del registro, escrito directamente — nunca a través de
setx, que trunca un PATH largo a 1024 caracteres y se lleva la mitad de tus
herramientas por delante. En Linux y macOS es una línea en los archivos de arranque que
existan, escrita una vez y marcada para que una segunda instalación no añada una segunda
copia.
Una API key de Anthropic
Nada que instalar y sin inicio de sesión: lo adecuado para una máquina ante la que no se sienta nadie. Pega la clave en la pantalla de configuración y se guarda en el llavero del sistema operativo, solo en esa máquina. Donde no hay llavero — un servidor sin sesión de escritorio — es un archivo legible únicamente por esa cuenta, y la pantalla lo dice en vez de fingir lo contrario.
La pantalla de configuración vuelve a estar accesible desde Configuración… en el
icono de bandeja de Concentus. Una clave que ya esté en el entorno como
ANTHROPIC_API_KEY sigue funcionando; una guardada en la app tiene prioridad
sobre ella.
El lienzo
Donde se dibuja un flow, y qué significa el dibujo.
Los bloques se añaden desde la paleta de la izquierda. Un bloque nuevo se coloca pegado a aquel al que se engancha — la cadena va de izquierda a derecha, y las capacidades cuelgan debajo — y cuando exactamente un bloque existente puede aceptar legalmente la conexión, el cable se dibuja por ti.
Seleccionar un bloque rodea lo que lo alimenta y lo que él alimenta, un salto en cada
dirección. Un doble clic abre sus propiedades; un bloque enfocado con Tab se
abre con Enter.
Deshacer, ordenar, guías
Cada cambio en el lienzo se puede deshacer — Ctrl+Z /
Ctrl+Y, o los botones ↶ ↷ — incluido borrar un bloque, que antes
era irreversible salvo recargando sin guardar. Una ráfaga de escritura en un inspector
cuenta como un paso, y un arrastre como un paso, así que deshacer se mueve en las unidades
en las que piensas.
⌗ Ordenar dispone un flow que creció a mano: la cadena de izquierda a
derecha, las capacidades colgadas bajo sus agentes — la misma forma que dibuja el lienzo
cuando coloca los bloques por ti. Una disposición que odies está a un
Ctrl+Z de desaparecer. Al arrastrar, las guías de alineación
ajustan un bloque a los bordes y centros de sus vecinos.
Los cables se tiñen según la salida de la que parten: el camino si falla en rojo y discontinuo, el camino si no en ámbar — para que a tres pasos de distancia el camino del fallo y el del éxito dejen de parecer idénticos.
Qué significa un cable
La dirección tiene significado, así que el lienzo rechaza un cable que no lo tendría: un agente no puede alimentar a su servidor MCP, y una base de conocimiento no puede alimentar a una fuente SQL, porque ninguno tiene nada que hacer con lo que llega. Solo los consumidores — agentes, merges, verificadores — pueden estar en el extremo receptor de una capacidad.
Dos salidas por bloque
Cada bloque que se ejecuta tiene una segunda salida bajo la principal, y el cable recuerda de cuál partió. En un agente, un subflow, una llamada a API, un merge o un verificador es si falla: la rama cableada ahí solo se ejecuta cuando el bloque falló, y recibe el propio fallo, con el nombre del bloque que lo produjo — «Presupuestos falló: el buzón rechazó la credencial» es algo sobre lo que una rama de recuperación puede actuar, y «la ejecución falló» no lo es.
Una ejecución cuyo fallo se gestionó así se completa. Alguien dibujó qué debía pasar cuando sale mal y pasó; dejar la ejecución en rojo informaría de un fallo desatendido por funcionar como se diseñó. Sin nada cableado a la salida de error, un fallo se comporta exactamente como siempre.
En una condición la segunda salida es si no. La rama principal se ejecuta cuando la prueba se cumple, la rama «si no» cuando no — una sola prueba leída desde ambos lados. Antes, «si es urgente haz X, si no Y» requería dos condiciones con pruebas opuestas, y las dos podían separarse hasta que alguna entrada cayera entre ellas. Tras un «para cada», la rama «si no» recibe los elementos rechazados en vez de tirarlos al suelo.
Teclado
| Teclas | Qué hace |
|---|---|
Ctrl + K | Paleta de comandos — llega a cualquier vista o acción |
Ctrl + C / V | Copiar y pegar bloques. El texto seleccionado gana: el lienzo se aparta |
Ctrl + D | Duplicar el bloque seleccionado |
Ctrl + Z / Y | Deshacer / rehacer cualquier cambio del lienzo, borrados incluidos |
Delete | Eliminar la selección (se puede deshacer) |
Enter | Abrir las propiedades del bloque enfocado |
Esc | Cerrar el diálogo de propiedades |
Bloques
Cada tipo de caja, y cuándo recurrir a ella.
| Bloque | Qué es |
|---|---|
| Entrada / disparador | De dónde sale el texto de la ejecución: escrito por ti, una programación, un webhook o un correo entrante. |
| Coordinador | El líder: planifica el trabajo, lo reparte entre los agentes conectados debajo y escribe la respuesta. Uno por flow; la paleta lo dice cuando el lienzo ya tiene uno. |
| Agente | Un modelo con un system prompt, un nivel de esfuerzo y un techo de tokens, que hace un trabajo en su propio contexto. |
| Verificador | Lee un resultado y devuelve un veredicto. Su punto final es un veredicto, no una conversación. |
| Merge | Reconcilia lo que produjeron varias ramas en una sola respuesta. Llega a MCP igual que un agente. |
| Servidor MCP | Herramientas que un agente puede llamar. Los servidores HTTP pasan por un proxy; los servidores stdio los lanza el propio worker. |
| Repositorio | Una copia git en la que trabaja el agente — leer el código, cambiarlo, abrir un pull request. |
| Fuente SQL | Una consulta de solo lectura cuyas filas se inyectan como contexto antes de que arranque el agente. |
| API / endpoint | Cualquier endpoint HTTP como herramienta tipada — desde un documento OpenAPI, o desde una URL que escribes. |
| Base de conocimiento | Documentos de los que el agente puede recuperar pasajes. Ver Bases de conocimiento. |
| Condición | Manda la ejecución por un camino u otro según lo que realmente volvió. |
| Para cada | Toma una lista y ejecuta la misma rama sobre cada elemento. |
| Ejecutar otro flow | Un flow dentro de un flow. Ver Subflows. |
| Enviar correo | Envía por SMTP lo que le llega — el resultado, o el de una rama — a las direcciones que indiques. Las credenciales salen del almacén, nunca del fichero del flow. |
| Nota | Texto en el lienzo para la siguiente persona. Las ejecuciones lo ignoran. |
| Grupo | Una caja alrededor de varios bloques para moverlos, copiarlos y leerlos como uno solo. |
Disparadores
Cuatro maneras de arrancar una ejecución.
- Manual — escribes el primer mensaje en la consola.
- Programación — una expresión cron, construida a partir de opciones sencillas en vez de escrita a mano. La tarjeta del lienzo lo dice con palabras: cada 15 minutos los días laborables.
- Webhook — una URL con un secreto. Hacer un POST a ella arranca el flow con el cuerpo de la petición.
- Correo — se sondea una carpeta IMAP y cada mensaje que coincide arranca una ejecución. IMAP y no SMTP, porque las carpetas, las marcas y el estado de leído son lo que hace posible «procesa esto una sola vez».
Y sin el secreto del webhook del original. Copiar una programación activa te daría dos flows saltando cada mañana, que no es lo que «duplicar» significa para nadie.
Subflows
Un flow dentro de un flow, cableado de dos maneras.
Cablea un flow hacia un agente y se ejecuta primero, con el texto con el que arrancó esta ejecución, y su respuesta llega como contexto. Cabléalo desde un agente y se ejecuta cuando ese agente termina — un relevo. El dibujo dice cuál de los dos, así que no hay ningún desplegable que pueda contradecirlo.
El agente también recibe una herramienta run_flow para el mismo flow, para
poder volver a preguntar con sus propias palabras cuando la primera respuesta plantea una
duda. Las dos no son redundantes: una es lo que el flow siempre necesita, la otra es lo que
esta ejecución concreta resultó necesitar.
Un hijo se ejecuta con su propio presupuesto y su propio modo de permisos. Los ciclos se cortan con una cadena de ancestros, y el anidamiento se detiene a tres niveles de profundidad.
Workers independientes
Un proceso por agente, con el acceso a herramientas impuesto de verdad.
Por la vía de sesión compartida, una ejecución local es un solo proceso de la CLI para todo el flow, así que las carpetas de contexto y las listas de delegación se escriben en las instrucciones de cada agente en vez de imponerse: a un agente se le dice qué carpetas y qué agentes son suyos, y aun así podría llegar a los demás.
Los workers independientes son la cosa de verdad. Cada agente recibe su propio proceso y su propia ventana de contexto, y llega a MCP a través de una fachada que decide qué herramientas puede llamar y si las escrituras se bloquean (solo lectura) o se simulan (dry-run) — impuesto por el backend en cada llamada, no pidiéndoselo al modelo por favor.
Un techo manda sobre todo lo demás: execution.max-processes (Ajustes, 10 por
defecto) limita el total de procesos claude en la máquina, sea cual sea la
ejecución o el reparto que los arrancó. Los límites por grupo se multiplican — ocho
ejecuciones de cuatro workers serían treinta y dos procesos, cada uno de cientos de MB — y
esto limita el producto. Un worker que no cabe espera un hueco, y su ejecución lo dice;
subir el ajuste libera el trabajo en cola sin reiniciar.
Qué pasa entre ellos
Dos herramientas, y nada más. share_finding cuenta a los demás workers algo que
de otro modo tendrían que descubrir por su cuenta — un hecho establecido, un callejón sin
salida que no vale la pena repetir, una fuente que resultó estar equivocada.
read_findings lee lo que han dicho. Vale la pena llamarla antes de empezar
cualquier cosa que suene a que puede estar ya hecha.
Deliberadamente estrecho: notas cortas, sin conversación, y sin manera de preguntar algo a un hermano y esperar respuesta. Un worker que pudiera bloquearse esperando a otro worker sería un worker que puede quedarse en interbloqueo con él. Las notas son borrador — pertenecen a esta ejecución, no al flow — y el paso de merge las lee junto a los informes, porque una nota suele ser la razón por la que un informe dice lo que dice.
Cuando un agente deja de avanzar
A un agente que llama a la misma herramienta con los mismos argumentos y obtiene la misma respuesta tres veces seguidas se le rechaza una vez, y se le dice qué ha estado haciendo. La regla es misma herramienta, mismos argumentos y mismo resultado: un sondeo de estado cuya respuesta cambia no se toca nunca, que es la diferencia entre esperar y dar vueltas. Los fallos también cuentan — hay tan poco que aprender del cuadragésimo error idéntico como del cuadragésimo éxito idéntico.
Es un badén, no un muro. El contador se reinicia tras un rechazo, así que un agente que de verdad está esperando algo se retrasa en vez de detenerse; rechazar para siempre convertiría una manera de ahorrar dinero en una manera de romper una ejecución que estaba a punto de salir bien.
Una fachada solo puede mediar HTTP. Un perfil que retira una herramienta de un servidor stdio retira el servidor entero, porque no se puede imponer nada a un proceso que la fachada nunca ve.
Bases de conocimiento
Material de referencia demasiado grande para entregarlo entero.
Una base de conocimiento es una colección con nombre de documentos de los que un agente recupera pasajes. Es distinta de una carpeta de contexto, y la distinción es a cuál recurrir en cada caso: una carpeta de contexto entrega al agente los propios archivos — lo adecuado cuando los archivos son el trabajo, como un repositorio. Una base de conocimiento es para manuales, políticas e informes pasados, donde solo deben inyectarse los pasajes relevantes para la tarea.
Qué se puede meter
| Fuente | Notas |
|---|---|
| Capa de texto. Un escaneo sin capa de texto pasa por OCR si está instalado. | |
Word .docx | Párrafos y tablas. Las tablas salen delimitadas por barras verticales para que una cita conserve sus columnas. |
| Excel / CSV | Hojas como filas. |
PowerPoint .pptx | Diapositiva a diapositiva, numeradas, con las notas del orador — que suele ser donde vive la frase que explica una diapositiva de cuatro palabras. |
| Texto, Markdown, HTML | Tal como están escritos. |
| Imágenes | A través de OCR, cuando está instalado. |
| Páginas web | Por dirección. Ver más abajo. |
Se pueden subir carpetas enteras de una vez, con exclusiones por carpeta — una carpeta real
siempre tiene un .gitignore o una imagen perdida en alguna parte.
Páginas
Añadir una página toma una URL. El documento se archiva bajo esa dirección, así que añadirlo otra vez lo sustituye en vez de archivar una segunda copia — que es lo que hace que Actualizar páginas signifique algo: un clic vuelve a descargar cada página de la base cuando la wiki avanza. Los archivos subidos no se tocan en una actualización; un archivo que alguien eligió no tiene dirección a la que volver.
Se descarga una dirección — los enlaces de la página no se siguen. Un rastreador que deambula ingiere toda la intranet porque alguien pegó una página de navegación, y luego responde preguntas con el menú de la cafetería.
Un servidor que descarga una dirección que tú escribes puede llegar mucho más lejos que
tú. Las direcciones de loopback, link-local y de metadatos de la nube se rechazan, las
redirecciones se vuelven a comprobar en cada salto, y un host que no resuelve falla
cerrado. Nombra hosts en knowledge.allowed-web-hosts para admitir los que de
otro modo estarían bloqueados.
Quién puede leer una base
Cualquier otro recurso de aquí es accesible para cualquiera que pueda editar flows, y para la definición de un agente eso es correcto — es configuración. Una base de conocimiento no es configuración; es los propios documentos. Así que una base puede nombrar el rol más bajo que puede leerla, en la misma escalera que usa todo lo demás.
Ausente significa todo el mundo, que es lo que significaba cada base creada antes de que esto existiera y debe seguir significando. Se impone en la API, y otra vez cuando una ejecución inyecta una base — contra el rol de quien arrancó la ejecución, no de quien dibujó el flow. Un flow sobrevive a la sesión de su autor, y heredar su alcance haría que cada base restringida fuera legible por cualquiera que pudiera pulsar Ejecutar en el flow adecuado.
Fragmentación
Los documentos se parten por límites de párrafo a unos 1.500 caracteres, con 200 caracteres de solapamiento para que una frase cortada en un límite siga apareciendo entera en uno de sus dos fragmentos. Un solo documento se detiene en 2.000 fragmentos, y lo dice cuando ocurre.
Recuperación
Cómo se encuentra un pasaje. la parte importante
Cada consulta ejecuta dos búsquedas, y se fusionan en vez de elegir entre ellas.
Una búsqueda vectorial no sabe distinguir un token exacto. Una referencia de documento, un código de error, un nombre de archivo se sitúan en el espacio de embeddings junto a todos sus vecinos, así que pedir una política por su número devuelve otras doce políticas. Una búsqueda por palabras clave la encuentra a la primera. El caso espejo es igual de común: ninguna búsqueda por palabras clave casa «qué pasa cuando alguien se va» con un documento titulado Offboarding, porque no comparten ninguna palabra. Ejecutar ambas no es cubrirse las espaldas — es la única manera de responder a las dos preguntas.
keyword (ts_rank_cd, top 50) ─┐
├─ Reciprocal Rank Fusion ─ cross-encoder ─ top k
semantic (cosine, top 50) ─┘
La fusión es por posición, no por puntuación. Una similitud de coseno y un rango de texto de PostgreSQL no son cantidades comparables, y ponderarlas una contra otra significaría inventarse un tipo de cambio y luego ajustarlo para siempre. Reciprocal Rank Fusion solo pregunta cuán cerca de la cima de su propia lista puso cada rama un pasaje — y un pasaje que solo encontró una rama sigue aflorando, que es toda la gracia.
El reranker
Después un cross-encoder reordena a los supervivientes. Lee la pregunta y un pasaje juntos y puntúa el par, que es lo que le permite notar que un pasaje describe el proceso correcto para el departamento equivocado — una distinción que dos embeddings calculados por separado no pueden expresar. Demasiado lento para una base entera; exactamente lo adecuado para los cincuenta candidatos que una búsqueda ya encontró.
Los dos modelos
Ambos son opcionales, ambos se ejecutan dentro de la app, y ambos se descargan bajo demanda desde Recursos → Conocimiento. Sin Ollama, sin Docker, sin servidor.
| Modelo | Tamaño | Sin él |
|---|---|---|
| multilingual-e5-small embedding | ~130 MB | La búsqueda por palabras clave sigue funcionando; nada se ordena por significado. |
| bge-reranker-base reranker | ~282 MB | El orden fusionado se mantiene, y el panel dice qué falta. |
Un servidor de modelos que sirva bge-m3 se detecta automáticamente si tienes uno.
Qué llega al agente
Los pasajes recuperados se ensamblan, no se pegan:
- Fusionados — los pasajes adyacentes se unen sin repetir el solapamiento entre fragmentos, que de otro modo se leería como énfasis.
- Ordenados por documento y posición, nunca por puntuación. Un documento se lee hacia delante; el orden por puntuación entrega al modelo el paso 4, luego el paso 1, luego el paso 7 y le pide que explique el proceso.
- Recortados a un presupuesto de caracteres por fuente (
knowledge.context-chars, 12.000 por defecto), y se le dice al agente que algunos se quedaron fuera. - Numerados con una clave de cita, y el prompt pide esos marcadores de vuelta. Una respuesta que nadie puede contrastar con sus fuentes es el fallo que todo este subsistema existe para evitar.
Volver a preguntar
El agente también recibe una herramienta search_knowledge. La precarga responde
a lo que el flow siempre necesita; la herramienta responde a la pregunta que solo existe por
lo que dijo la primera respuesta.
Medir la recuperación
Porque todo cambio en la ordenación suena a mejora.
La prueba habitual de un cambio en la recuperación son tres consultas escritas después de hacerlo. Bajo ese régimen una base empeora en silencio mientras todos coinciden en que se nota más afinada.
Así que una base puede guardar un conjunto dorado: preguntas que alguien hace de verdad, cada una con el documento que la responde. Recursos → Conocimiento → Medir esta base. Ejecutarlo da tres números, porque un solo número esconde los dos fallos que importan.
| Número | Qué significa |
|---|---|
| Respondidas | Proporción de preguntas en las que un documento esperado entró en el top 5. Con qué frecuencia alguien habría obtenido siquiera una respuesta. |
| Documentos encontrados | Proporción de todos los documentos esperados recuperados. Más baja que Respondidas siempre que una pregunta necesita dos documentos y volvió uno — media respuesta que el titular ocultaría. |
| Calidad de la posición | 1,00 cuando las respuestas llegan primero, 0,50 cuando segundas, 0 cuando nunca. Un pasaje que llega quinto gasta el presupuesto de contexto de cuatro erróneos para llegar ahí. |
Ejecuta las mismas preguntas con y sin el reranker, que es la única manera honesta de responder «¿valen la pena 282 MB con mis documentos?» — un benchmark sobre el corpus de otro no es evidencia sobre el tuyo. Un fallo muestra qué volvió en su lugar, porque eso es la explicación y no el veredicto.
Lo que se mide es si volvió el documento correcto. Calificar texto generado necesita un modelo que juzgue a un modelo — una segunda cosa que puede equivocarse, y una factura por ejecución — y responde a una pregunta distinta: una respuesta errónea sobre el pasaje correcto es un problema de prompt, mientras que una respuesta que suena bien sobre el pasaje equivocado es este problema, y es el que se cuela sin que nadie lo note.
Fuentes SQL
Filas como contexto, antes de que arranque el agente.
Un bloque SQL ejecuta una consulta de solo lectura e inyecta sus filas en el contexto del agente conectado. JDBC genérico; PostgreSQL viene incluido y se pueden añadir otros drivers al backend. Prueba la consulta desde las propiedades del bloque antes de ejecutar el flow.
Solo se permite un único SELECT, como defensa en profundidad junto a los
permisos que imponga la propia base de datos. Las credenciales se referencian por id desde
Recursos → Credenciales, nunca se escriben en línea.
Los hosts de loopback, link-local y de metadatos de la nube están bloqueados por defecto.
Añade hosts a rag.allowed-jdbc-hosts para permitirlos — salvo la dirección de
metadatos, que está bloqueada en cualquier caso.
APIs y MCP
Dos maneras de darle a un agente algo que llamar.
Servidores MCP
Cualquier servidor Model Context Protocol, por HTTP o lanzado como proceso local. Un catálogo ofrece los habituales con su configuración — las variables que necesitan, el runtime que necesitan instalado — en vez de una caja JSON en blanco. Los servidores OAuth guardan sus tokens en una credencial cifrada y los renuevan en mitad de una ejecución cuando una llamada vuelve con 401.
Cuando un servidor ofrece muchísimas herramientas, el agente recibe una herramienta de búsqueda en vez de cien esquemas: pide lo que necesita y recibe las pocas definiciones que coinciden.
Endpoints de API
Pega una URL y se convierte en una herramienta tipada — sin necesidad de documento OpenAPI. Los marcadores de la ruta se convierten en los argumentos, y solo se ofrece un cuerpo donde corresponde. Con un documento OpenAPI, se listan las operaciones y eliges cuáles puede llamar el agente.
Ejecuciones y la consola
Qué pasó, bloque a bloque.
Cada ejecución registra sus eventos, su entrada y salida por bloque, sus recuentos de tokens y un coste estimado. Un bloque puede volver a ejecutarse por su cuenta, con exactamente la entrada que recibió — un paso que falló al final de una ejecución larga no te cuesta los veinte minutos anteriores — y opcionalmente con otro modelo.
Dos ejecuciones se pueden comparar lado a lado. Las ejecuciones, los eventos y la salida por bloque se persisten; los manejadores vivos de una sesión en marcha no, así que reiniciar el backend deja el historial intacto y descarta cualquier cosa a medio vuelo.
Una estimación a las tarifas por token publicadas. Con una suscripción de Claude es uso equivalente contra la bolsa no interactiva de tu plan, no un cargo; con la API se aproxima al cargo real.
Aprobaciones
Cuándo una ejecución debe esperar a una persona.
El modo de permisos se fija en el coordinador, porque un solo proceso de la CLI ejecuta todo el flow: bypass (el único modo que funciona sin supervisión), solo plan y pídeme aprobación. Una ejecución que espera una respuesta lo dice, y se puede responder desde la consola — o desde Slack o Teams, en el hilo en el que llegó la notificación.
Una ejecución que ya ha entregado su resultado queda cerrada a más mensajes.
Versiones y ejecuciones doradas
Un historial al que solo se añade, y una referencia de la que desviarse.
Cada guardado añade una revisión, atribuida a quien la hizo. El historial es accesible desde Historial en el panel: previsualiza una revisión en el lienzo, o restáurala — una restauración se añade como revisión nueva en vez de borrar lo que sustituyó, así que aquello sobre lo que restauraste sigue a un clic.
Una ejecución se puede marcar como ejecución dorada: una referencia de lo que este flow debería producir. Las ejecuciones posteriores se comparan con ella, y un flow cuya salida se ha desviado lo dice en su tarjeta.
Replay contra el flow actual
Las ejecuciones doradas comparan salidas; depurar suele necesitar comparar decisiones — con la misma entrada, ¿dónde diverge el camino? Desde cualquier ejecución, ⟲ Replay vs actual pasa las salidas por bloque grabadas de esa ejecución por el flow tal como está guardado hoy, sin ejecutar nada, y pinta la respuesta en el lienzo: un anillo ámbar en cada bloque cuyo destino cambia (se ejecutó y ahora se saltaría, o al revés), un chip que dice en qué sentido y por qué, y los bloques que se ejecutaron pero ya no existen nombrados en la cabecera.
Reproduce el enrutado, no los agentes — las puertas deciden a partir del texto grabado, así que sus respuestas son exactas, pero donde una decisión necesitaría una salida que nunca se grabó, el bloque dice no se puede decidir en vez de adivinar.
Marketplace
Donde se comparten e instalan las piezas con las que se construye un flow.
Una vista propia, junto a Studio. La gente publica servidores MCP, agentes de biblioteca, fachadas, skills, plugins, definiciones de API y plantillas de flow; el resto los instala en su propia organización con un clic y un flow los usa directamente. La búsqueda es instantánea y local; filtros por tipo, ámbito, estado y etiqueta; orden por instalaciones, más reciente o nombre. Cada tarjeta es una línea y un chip de estado — Instalado, Actualizar, Pendiente — y la explicación vive en el tooltip.
Dos ámbitos
Un elemento publicado en esta organización lo ven sus miembros y no necesita
aprobación — cualquier miembro puede publicar. Un elemento publicado
globalmente lo ven todas las organizaciones del despliegue cuando un
curador lo aprueba; hasta entonces solo lo ven su autor y los curadores,
marcado como pendiente, y un rechazo lleva una frase que el autor lee. Los curadores son los
administradores de la organización indicada en el ajuste
marketplace.curator-organization — por defecto la más antigua, la del autor.
En un despliegue con una sola organización el control de ámbito no se muestra.
Qué crea instalar
El recurso que el elemento describe, en tu organización: una definición de servidor MCP (con su hueco de credencial vacío y con nombre), un agente de biblioteca, un perfil de fachada, una skill, la instalación de un plugin o un flow (en pausa, sin secretos, como un duplicado). Una definición de API no crea nada: el inspector del bloque API ofrece Usar del Marketplace… y rellena sus campos. Las credenciales nunca viajan — publicar un recurso las elimina y dice qué quitó. Los recursos que vienen de una instalación llevan un chip Marketplace · vN y ofrecen Actualizar cuando el autor vuelve a publicar; desinstalar elimina lo que la instalación creó.
Qué hay el primer día
La app siembra su propia biblioteca como elementos integrados: el catálogo de MCP (Linear, GitHub, los servidores de Google y Microsoft, …), los cuatro agentes de biblioteca y los ocho flows de inicio. Un elemento integrado no se puede editar; una actualización de la app lo vuelve a sembrar, y uno que borraste sigue borrado. Publicar, aprobar, rechazar, instalar y desinstalar se escriben en el registro de auditoría.
Equipos e inicio de sesión
Quién puede cambiar qué.
| Rol | Puede |
|---|---|
| Lector | Leer flows e historial. |
| Operador | Ejecutar flows y responder aprobaciones. |
| Miembro | Crear y editar flows y recursos. |
| Administrador | Todo, incluidos miembros, ajustes y almacenamiento. |
Impuesto en cada petición tanto por método como por ruta — no solo por lo que la interfaz decide dibujar.
Iniciar sesión con un directorio
Microsoft, Google y Discord se registran desde dentro de la app, en Recursos → Miembros → Proveedores de inicio de sesión, y surten efecto de inmediato. La pantalla de inicio de sesión muestra los tres estén o no configurados: uno sin registrar dice qué necesita en vez de mandar a alguien a un proveedor que lo rechazará después de haber escrito su contraseña.
Las personas se emparejan por el id inmutable del propio proveedor, nunca por su dirección — las direcciones se reasignan cuando la gente se va, y emparejar por una acabaría entregando los flows de quien se fue a quien heredara el buzón. Una dirección que ya tiene cuenta se vincula a ella en vez de duplicarse.
Todos los registros fallan igual la primera vez. Cópiala de la pantalla de proveedores —
se calcula a partir de la petición que estás haciendo — y registra exactamente esa cadena.
En Microsoft, el campo donde ponerla es web.redirectUris en el manifiesto,
porque el portal rechaza http:// con una dirección de loopback.
Varias cuentas a la vez
Un navegador puede tener varias cuentas con sesión iniciada y cambiar entre ellas, con el rol de cada una mostrado al lado — que es además la manera práctica de comprobar que un permiso se cumple de verdad. Dos cuentas activas a la vez necesitan dos ventanas, porque una sesión es una cookie.
Grupos
Una organización puede dividirse en grupos — el equipo de plataforma, el de soporte, el de un cliente — en Recursos → Grupos. Dos cosas siguen al grupo: un recurso (un flow, un servidor MCP, un agente, una fachada, una base de conocimiento, una credencial, …) puede ser visible para un solo grupo en vez de para toda la organización, elegido con Visible para en el recurso o en la tarjeta del flow, y lo ven solo los miembros del grupo y los administradores; y un grupo tiene su propia política y sus propias sobrescrituras de los ajustes que aplican por ejecución, en capa sobre los de la organización para los flows que contiene. Los administradores crean grupos; los gestores de un grupo añaden y quitan miembros y editan sus ajustes. Borrar un grupo devuelve sus recursos a la organización. El Marketplace puede publicar en un grupo e instalar en uno. Enterprise; con una licencia Team la pantalla explica por qué y lo que un grupo ya acota sigue acotado.
Cuentas de servicio
Tokens para máquinas — un job de CI, una entrada de cron, otro sistema — en
Recursos → Cuentas de servicio. Cada una actúa con su rol en cada petición
y no ocupa asiento; el token (csa_…) se muestra una sola vez y se guarda con
hash. El CLI sin interfaz lo lee de CONCENTUS_TOKEN y se salta el inicio de
sesión. Una licencia Team admite dos a la vez; Enterprise, las que necesites.
Varias organizaciones
Un despliegue puede alojar varias organizaciones, cada una con sus flows, credenciales, ejecuciones y ajustes, en Recursos → Organizaciones. Una persona puede pertenecer a más de una y cambia desde el menú de cuenta; los asientos se cuentan por persona, no por pertenencia. Crear la segunda organización es una función Enterprise — el resto de esa pantalla funciona en Team.
Políticas de organización
Reglas sobre todos los flows de la organización, en Recursos → Políticas: una fachada por defecto para los workers independientes (se rellena donde un bloque no indica ninguna, o se rechaza), un techo al modo de permisos que cualquier bloque puede pedir, un presupuesto mensual para toda la organización junto al de cada flow, y aprobación antes de que un endpoint publicado responda — hasta que un administrador aprueba el token guardado, el endpoint responde el mismo 404 que uno sin publicar. El doctor del flow avisa de las tres cosas antes de ejecutar. Enterprise; un despliegue Team ve lo guardado, solo lectura.
Registro de auditoría y retención
Quién hizo qué y cuándo — ejecuciones iniciadas y detenidas, aprobaciones, flows guardados
y publicados, miembros y roles, credenciales (solo etiqueta y tipo), ajustes (solo la
clave), licencias instaladas, copias de seguridad — en Recursos → Auditoría,
legible por administradores en todos los niveles, con filtros por autor, tipo y fecha.
Exportarlo como CSV o JSON es Enterprise. La retención sigue al nivel: un despliegue Team
conserva noventa días de ejecuciones, versiones de flow y filas de auditoría y purga cada
noche (las ejecuciones doradas y la versión actual de cada flow se quedan siempre);
Enterprise lo conserva todo salvo que retention.enterprise-days diga otra
cosa; una instalación gratuita nunca se purga.
Runners
Ejecución en una máquina que alguien opera, para un hub que alguien ha desplegado.
La aplicación de escritorio es un solo backend que es a la vez el plano de control y el
sitio donde se ejecutan los flows: el CLI claude corre en la máquina donde
está la ventana, con la sesión que ya hay allí. Un runner es esa mitad de
ejecución por sí sola — un proceso en una máquina que tú operas (un portátil que se queda
encendido, un NAS, un contenedor en tu propio clúster) que se conecta hacia fuera
a un backend de Concentus, el hub, se registra con un token acuñado allí
y ejecuta los turnos del CLI que el hub le entrega. El hub se queda con los flows, las
ejecuciones, las aprobaciones, las credenciales, los grupos, las políticas y la interfaz;
el runner se queda con la sesión, las carpetas, los clones y los procesos. La aplicación
por sí sola no cambia — los runners son para la forma en que un hub corre en algún sitio
(java -jar, o la imagen Docker) y se abre en un navegador.
Dónde vive la sesión
Las condiciones de Anthropic no permiten que las credenciales de una suscripción pasen
por un tercero, y un hub que guardara tu claude setup-token sería exactamente
eso. Así que el hub nunca guarda una sesión de Claude: un runner lo registra
quien lo opera, en una máquina que opera, y lleva su propia autenticación — la
sesión del CLI en esa máquina, CLAUDE_CODE_OAUTH_TOKEN salido de
claude setup-token, o ANTHROPIC_API_KEY. El hub solo sabe de qué
tipo es, y la lista lo muestra.
Ámbitos
Quien registra un runner elige quién puede ejecutar flows en él. Organización: todos sus miembros; los registra un administrador. Grupo: sus miembros, un administrador, y una programación o un webhook de un flow que pertenezca al grupo; un gestor del grupo puede registrar uno, y necesita grupos, así que Enterprise. Solo yo: el propietario y nadie más — ni un administrador que no sea el propietario, ni nunca una programación o un webhook. Es la máquina de alguien y la sesión de alguien; cualquier miembro puede registrar uno para sí. Los administradores ven todos los runners; el resto ve los de la organización, los de sus grupos y los suyos.
Arrancar uno
Recursos → Runners → + Nuevo pide un nombre y un ámbito y responde con
el token (crn_…), mostrado una sola vez y guardado con hash, y las tres
maneras de arrancarlo con la URL del hub ya rellena:
java -jar concentus-backend.jar runner --url https://hub.example.com --token crn_…
docker run -d -v concentus-runner:/data \
-e CONCENTUS_RUNNER_URL=https://hub.example.com -e CONCENTUS_RUNNER_TOKEN=crn_… \
-e CLAUDE_CODE_OAUTH_TOKEN=… ghcr.io/gergilcan/concentus-runner:latest
O la propia aplicación de escritorio, desde la bandeja, en Configurar… → Servidor: sigue
funcionando como hasta ahora y además ejecuta para ese hub. En modo runner
el jar nunca arranca Spring — ni base de datos ni puerto — y sale con 3 si
el token se rechaza, en vez de reintentar. Lo que necesita de su lado: git,
el CLI claude, LOCAL_CONTEXT_ROOTS para las carpetas que los
flows pueden leer allí (vacío las rechaza todas, como en un hub), y
EXECUTION_MAX_PROCESSES para cuántos turnos a la vez — aplica su propio
techo, no el del hub. Un hub y un runner juntos, con compose, están en
packaging/docker del repositorio.
Qué runner usa un flow
Se ejecuta en, en los Ajustes del flow. Este servidor (por defecto): aquí cuando el CLI tiene sesión en este backend; si no, el runner en línea menos ocupado que puedas usar — el registro lo dice —; si no, una API key o el rechazo. Cualquier runner: el runner utilizable en línea menos ocupado; sin ninguno en línea, el arranque falla en el acto, no hay cola. Un runner por nombre: ese; desconectado, revocado o no tuyo para usarlo, y el arranque se rechaza nombrándolo. Solo los flows del CLI de Claude van a runners; un modelo autoalojado se queda en el hub. La primera línea de la ejecución nombra al runner, la lista de ejecuciones lleva un chip con su nombre, y la ejecución se factura como una local — con la suscripción de ese runner.
Un turno no sobrevive a que el runner se desconecte: tras 45 s sin latido el hub lo termina como desconectado, y lo que el runner estaba ejecutando acaba de su lado con la salida perdida. El runner se reconecta solo; nada se reanuda. Los espacios de trabajo terminados no se limpian en el runner, y ninguna cola espera a que un runner se conecte.
Almacenamiento
Integrado por defecto; una base de datos de empresa cuando la quieras.
Cada compilación guarda sus datos en un PostgreSQL integrado bajo el directorio de datos de la app. Eso no es un modo demo — es el mismo esquema, las mismas migraciones y la misma ruta de código que un despliegue en servidor.
Recursos → Almacenamiento apunta la instalación a tu propio PostgreSQL y copia lo que ya hay, tabla por tabla, informando de lo que se movió. La copia es una copia: los datos integrados se quedan donde estaban hasta que estés satisfecho.
Las credenciales se cifran con una clave que la instalación genera en el primer arranque y
guarda en secret.key junto a sus datos. Una copia de la base de datos sin ese
archivo restaura filas que nadie puede descifrar. Define CONCENTUS_SECRET_KEY
para guardarla en otro sitio — un vault, un secreto de contenedor.
Actualizaciones
Una marca en la esquina, no un diálogo.
La app de escritorio se actualiza sola: comprueba cada cuatro horas, descarga en segundo plano e instala cuando sales. Nada de eso interrumpe nada, lo que también lo hacía invisible — así que el estado ahora está arriba a la derecha de la ventana. Silencioso mientras no hay nada que decir, un punto verde cuando hay una versión descargada y esperando. Al hacer clic dice en qué estado están las cosas y ofrece la única acción que tiene ese estado: comprobar ahora, o reiniciar e instalar.
Un diálogo de actualización que interrumpe el trabajo enseña a la gente a descartar diálogos de actualización. Una marca que espera a que la vean no cuesta nada y mañana sigue ahí.
Instalar sin que te pregunten nada
Pulsar instalar ejecuta el instalador en silencio: sin asistente, sin página de licencia que ya aceptaste, y sin preguntar dónde ponerlo — va donde ya está la instalación existente. La app se vuelve a abrir cuando termina.
Antes de que arranque el instalador, Concentus termina su propio backend y espera a que de verdad haya desaparecido, llevándose todo el árbol de procesos si pedirlo por las buenas no funciona. Esa espera no es cortesía: el runtime de Java incluido vive dentro del directorio de instalación, así que un instalador que arranca mientras el backend aún retiene esos archivos se detiene e informa de que la aplicación sigue abierta — detrás de una ventana que ya ha desaparecido.
Qué versiones se te ofrecen
Una compilación preliminar sigue tanto las versiones preliminares como las finales, tomando la más nueva. Una compilación final solo sigue versiones finales: quien instaló una versión estable no pidió que lo pasaran a una preliminar.
-beta.N, y eso no es cosmético
electron-updater deriva el canal de actualización del identificador de preliminar de la
versión, y solo ofrece una versión final a compilaciones cuyo canal es nulo,
alpha o beta — esos tres nombres están escritos a fuego. Con
cualquier otro identificador, rc incluido, una compilación no puede llegar
nunca a una versión estable. También debe llevar punto: 0.1.3-beta.1 da a
cada versión del tren el mismo canal, mientras que 0.1.3-beta1 da a cada una
el suyo y a nadie se le ofrece nunca la siguiente. El flujo de publicación rechaza ambos
errores.
Una ejecución de desarrollo no tiene app empaquetada que actualizar, y una instalación
.deb la actualiza el gestor de paquetes del sistema. Ambas lo dicen y se
retiran en vez de fallar en bucle.
Ajustes
Lo que antes eran variables de entorno.
Recursos → Ajustes. Un valor se busca en tres sitios, por orden: lo que alguien fijó en la aplicación, aquello con lo que se arrancó el despliegue, y después el valor por defecto integrado. Ese orden es lo que mantiene funcionando a ambos públicos — un contenedor arrancado por un pipeline sigue tomando su entorno, y la persona delante de la app puede cambiar lo mismo desde un formulario.
La pantalla dice de dónde salió cada valor, porque «8» significa tres cosas distintas y solo una de ellas te toca a ti borrarla, y si el cambio espera a un reinicio — la mayoría sí, porque dimensionan un pool de hilos o una política cuando arranca la aplicación. Los proveedores de inicio de sesión son la excepción deliberada: quien acaba de pegar un client id quiere probarlo.
Vaciar un campo elimina la anulación en vez de guardar una vacía. Los secretos se sellan con la misma clave que protege las credenciales guardadas y nunca se vuelven a leer desde la API.
Apariencia está arriba de la misma pantalla — oscuro, claro o alto contraste. No es uno de los ajustes de debajo: vive en este navegador, se aplica en el instante en que se elige y no tiene Guardar. Antes era un botón en la cabecera, que rotaba de clic en clic entre tres valores, lo que es mucho de la esquina más valiosa de la pantalla para algo que una persona fija una sola vez.
Trazas y métricas
OpenTelemetry, en las unidades de trabajo propias de esta aplicación.
El framework ya instrumenta lo que un framework puede ver. Nada de eso responde a la pregunta que de verdad tiene alguien aquí, que es sobre una ejecución. Así que hay seis nombres de span y un solo vocabulario de atributos:
| Span | Cubre |
|---|---|
concentus.run | Una ejecución, desde su disparador hasta su último bloque |
concentus.node | Un bloque: un agente, una puerta, un subflow, una llamada a API |
concentus.worker | Un worker independiente en un reparto en paralelo |
concentus.tool | Una llamada a herramienta MCP, rechazos incluidos |
concentus.model | Una petición a un modelo |
concentus.retrieval | Una búsqueda de conocimiento: ambas ramas, la fusión, cualquier reordenación |
Los atributos llevan identificadores, recuentos y resultados. Una traza acaba en el sistema de otro, normalmente con una retención más larga que cualquier cosa de aquí y leída por gente a la que nunca se dio acceso a los flows. Lo que es útil para depurar y lo que es seguro exportar son conjuntos distintos, y donde difieren gana el más pequeño.
No se exporta nada hasta que se nombra un colector, y está apagado por un interruptor y no
por una dirección en blanco — un endpoint vacío no es «ninguna parte» para un exportador
OTLP, es una URL inválida. Configúralo en Ajustes, o con OTLP_ENABLED y
OTLP_ENDPOINT. Las trazas se exportan en cualquier plan, instalaciones
gratuitas incluidas; solo la exportación de métricas es una función Enterprise.
Enviar las trazas a una herramienta de observabilidad LLM
Cualquier cosa que hable OTLP/HTTP las lee, y las orientadas a agentes agrupan solas los spans de una ejecución. El endpoint y una cabecera son toda la integración.
| Dónde | Endpoint | Cabecera |
|---|---|---|
| Langfuse (cloud) | https://cloud.langfuse.com/api/public/otel/v1/traces | authorization: Basic <base64 de pública:secreta> |
| LangSmith | https://api.smith.langchain.com/otel/v1/traces | x-api-key: <clave> |
| Phoenix (autoalojado) | http://localhost:6006/v1/traces | ninguna en local |
| Collector · Tempo · Jaeger | http://localhost:4318/v1/traces | la que pida |
La cabecera authorization tiene su propia fila en Ajustes. Cualquier otra es
una propiedad de Spring: management.otlp.tracing.headers.x-api-key=….
CLI sin interfaz
Ejecutar un flow desde un script.
pnpm desktop:build # once — builds the jar
export CONCENTUS_EMAIL=you@company.com
export CONCENTUS_PASSWORD=…
# o, para una máquina: el token de una cuenta de servicio en vez de iniciar sesión
export CONCENTUS_TOKEN=csa_…
node scripts/concentus-run.mjs my-flow.json --input "go"
echo $? # 0 completed · 1 failed · 2 needs a human
Inicia sesión como todo lo demás. Un script que pudiera manejar el backend sin credenciales
sería un agujero, no una comodidad. Prefiere las variables de entorno a --email
/ --password: un argumento acaba en el log del trabajo y en la lista de
procesos.
Licencias
Qué es gratis, qué necesita un asiento y dónde va una licencia.
Concentus funciona sin ninguna licencia instalada: la base de datos integrada, un asiento. Eso no es una prueba — nada de ello caduca ni deja de funcionar, y es con lo que arranca toda instalación.
Qué no necesita licencia
Todo lo que usa un individuo: el lienzo, cada bloque, cada disparador, las bases de conocimiento, la vía del modelo local — todo, con el límite de un asiento de arriba. Una licencia individual es gratis y no cambia nada funcional; solo pone un nombre en la instalación. Pide una desde el sitio y llega por correo.
Qué necesita una licencia enterprise
Tres cosas, todas más allá de ese asiento único por defecto:
- Una base de datos compartida — apuntar la instalación a un PostgreSQL al que se conecta tu equipo, en vez de al integrado.
- Miembros más allá del primero — a partir del segundo asiento.
- SSO — iniciar sesión con Microsoft, Google o Discord en vez de con una contraseña local.
Una licencia Team cubre hasta diez asientos — 25 € por asiento al mes, o 20 € por asiento al mes si pagas el año de una vez — y se compra con tarjeta en la sección de precios: la licencia llega por correo minutos después del pago, renovar es volver a comprar y todos los miembros pegan el mismo token. Incluye todo lo que un equipo necesita para trabajar junto: las tres cosas de arriba, el registro de auditoría en pantalla, cuentas de servicio, endpoints publicados y los inicios de sesión con Google y Microsoft.
Enterprise es escala y gobernanza — cualquier número de asientos, factura en vez de tarjeta, o un contrato: escribe a gila791@hotmail.com. Diez cosas son solo Enterprise, y cada una se llama igual en el sitio, en el panel de licencia y en la frase que ves cuando una licencia Team no la cubre:
- Proveedores de identidad personalizados — cualquier emisor OpenID Connect (Okta, Keycloak, una app de Entra propia). Team tiene los preajustes de Google y Microsoft.
- Cuentas automáticas para un dominio de correo — el primer inicio de sesión crea la cuenta. En Team se invita.
- Exportación de métricas OpenTelemetry a tu colector. Las trazas se exportan en cualquier plan.
- Políticas de organización — ver Equipos e inicio de sesión.
- Exportación del registro de auditoría como CSV o JSON.
- Retención ilimitada — Team conserva noventa días.
- Varias organizaciones en un despliegue.
- Cuentas de servicio ilimitadas — Team tiene dos.
- Endpoints publicados sin límite de peticiones — Team: 60 peticiones por minuto y token.
- Grupos dentro de una organización — recursos visibles para un solo grupo, y ajustes y política propios del grupo.
Enterprise es también el nivel para un despliegue detrás de un proxy o sin internet: la licencia se verifica sin conexión, la telemetría es opcional y un despliegue en servidor no hace ninguna llamada externa por su cuenta — Claude sigue necesitando llegar a Anthropic; un flow con un modelo propio no necesita nada fuera de la red.
Dónde va una licencia
Dos fuentes, gana la primera coincidencia:
| Fuente | Cuándo usarla |
|---|---|
CONCENTUS_LICENSE |
Una variable de entorno. Para un contenedor o un despliegue por script sin disco escribible digno de mención — y siempre gana sobre el archivo de abajo mientras esté definida. |
license.key |
Junto al directorio de datos de la app. Lo que Recursos → Ajustes → Licencia escribe para todos los demás — pega el token que te llegó por correo y la app escribe el archivo por ti. |
Caducidad y periodo de gracia
Una licencia individual nunca caduca — es gratis, así que no hay nada que vencer. Una licencia enterprise caducada sigue funcionando 14 días más después de su fecha: la renovación es una orden de compra, no un clic, y un flow que deja de ejecutarse en el momento en que cambia la fecha — a media tarde, a quien esté de guardia — es un fallo peor que un aviso durante dos semanas.
La instalación no se bloquea; baja al mismo estado de un asiento y base de datos integrada con el que arranca una instalación nueva, hasta que se instala una licencia renovada.
API HTTP
Lo que llama la propia interfaz.
Cada escritura devuelve un token CSRF que llega como cookie legible en el primer GET. Una cookie por sí sola no demostraría intención, que es toda la gracia de la cabecera.
| Método | Ruta | Qué hace |
|---|---|---|
| GET | /api/account/session | Quién tiene sesión iniciada, qué proveedores existen, si esta instalación necesita su primera cuenta |
| POST | /api/account/setup | Crear esa primera cuenta. Se niega en cuanto existe una |
| POST | /api/account/login | Iniciar sesión · /logout |
| GET/POST | /api/account/members | Miembros de la organización admin |
| GET/PUT | /api/account/providers | Registrar Microsoft / Google / Discord admin |
| GET/POST | /api/flows | Listar y guardar flows · /{id}/versions |
| POST | /api/runs | Arrancar una ejecución · /{id}/events la transmite |
| GET/POST | /api/knowledge | Bases de conocimiento · /{id}/documents · /{id}/urls · /{id}/refresh |
| POST | /api/knowledge/{id}/search | Probar una consulta contra una base |
| GET/POST | /api/knowledge/{id}/evals | El conjunto dorado · /evals/run lo puntúa |
| GET | /api/knowledge/embedder | Los modelos opcionales · /reranker · …/download |
| GET/PUT | /api/settings | Todo lo ajustable, con el origen de cada valor admin |
| GET/POST | /api/storage | Dónde viven los datos · /migrate los copia admin |
| GET | /api/audit | El registro, filtrado y paginado · /export?format=csv|json admin |
| GET/POST | /api/retention | La ventana en vigor · /run-now purga hoy admin |
| GET/POST | /api/organizations | Organizaciones · /{id}/members · /{id}/switch admin |
| GET/POST | /api/service-accounts | Tokens para máquinas · /{id}/revoke admin |
| GET/POST | /api/runners | Runners · /{id}/revoke · /usable — en los que puedes ejecutar flows · /self — el agente de este mismo backend |
| WS | /ws/runner | La conexión de un runner, con su token crn_… como bearer |
| GET/PUT | /api/org-policy | Las reglas de la organización · /publish/{flowId}/approve admin |
| POST | /api/public/flows/{id}/run | Un endpoint publicado, con su token bearer · /runs/{runId} lo consulta |
| GET/POST | /api/license | La licencia en vigor y lo que desbloquea · instalar un token admin |
Entorno
No se requiere nada. Estas son las excepciones que vale la pena conocer.
Cuatro cosas no pueden ser ajustes, porque son lo que hay que saber antes de que haya dónde guardar un ajuste.
| Variable | Cuándo la necesitas |
|---|---|
PERSIST_DB_URLPERSIST_DB_USERPERSIST_DB_PASSWORD |
Apuntar a un PostgreSQL externo desde el principio. Si no, se usa el integrado, y la pantalla de Almacenamiento puede moverte más tarde. |
CONCENTUS_SECRET_KEY |
Guardar la clave de cifrado en otro sitio que no sea secret.key junto a los datos. |
CONCENTUS_ADMIN_EMAILCONCENTUS_ADMIN_PASSWORD |
Crear la primera cuenta en un despliegue ante el que no se sienta nadie. |
APP_DATA_DIR · SERVER_PORT |
Dónde viven los datos y a qué puerto escuchar. |
CONCENTUS_RUNNER_URLCONCENTUS_RUNNER_TOKENCONCENTUS_RUNNER_NAME |
Arrancar el jar como runner (con runner como primer argumento), o hacer que un backend completo actúe también como uno. |
CONCENTUS_RUNNER_DATA_DIR · CLAUDE_COMMAND · LOCAL_CONTEXT_ROOTS · EXECUTION_MAX_PROCESSES |
Lo que un runner guarda de su lado: espacios de trabajo y clones, el CLI, las carpetas que puede leer, cuántos procesos del CLI a la vez. |
Todo lo demás — longitudes de cola, tiempos de espera, precios de modelos, listas de permitidos, el endpoint OTLP — es un ajuste, y el entorno se sigue leyendo como la capa intermedia de las tres.