ULTRON Control Center
Cockpit personal de escritorio (Tauri 2 + React 19) construido sobre la CLI de
Claude Code. Vive bajo ~/.ultron/ y reune tres piezas: memoria gobernada,
AI Router y un orquestador de skills/agentes. No reemplaza a Claude
Code: lo envuelve con estado persistente, inspeccionable y versionable.
Repositorio MIT de un solo mantenedor, pensado para publicarse (hoy la visibilidad la decide el mantenedor: si puedes leer esto en GitHub, ya es publico). No es un producto comercial ni un SaaS. Esta documentacion describe el sistema tal y como esta en el disco; no contiene secretos ni datos personales (la informacion personal vive solo en ficheros locales fuera de control de versiones).
Version: 15.8.0 (
control-center/package.json,Cargo.toml,tauri.conf.json)Plataforma: Windows 11 (objetivo principal); Linux x86_64 compila pero el flujo end-to-end no esta verificado por el autor.
Licencia: MIT (ver
LICENSE).
Quickstart
Sistema completo (app + skills + hooks + memoria semantica) — el camino recomendado; es idempotente y pregunta antes de tocar nada:
git clone https://github.com/SkiTemplar/ultron-control-center.git $env:USERPROFILE\.ultron
cd $env:USERPROFILE\.ultron
powershell -ExecutionPolicy Bypass -File .\install.ps1 # Linux: ./install.shInstalacion por componentes (sin wizard, determinista; -DryRun lista el
plan sin tocar nada):
.\install.ps1 -Core # app + memoria + hooks (el set por defecto)
.\install.ps1 -All # core + skills + tones + agents
.\install.ps1 -Skills -Tones # a la carta
.\install.ps1 -Core -DryRun # solo listar que haria
# Linux: ./install.sh --core | --all | --skills | --tones | --agents | --dry-runSolo la app de escritorio (sin skills/hooks/sidecar de memoria):
git clone https://github.com/SkiTemplar/ultron-control-center.git ~/.ultron && cd ~/.ultron/control-center
cp ../.env.example ../.env # opcional: claves de proveedores LLM (todas vacias por defecto)
npm install
npm run build:app # = kill-app + tauri build -> ejecutable de escritorioGuia completa (bootstrap one-liner desde release, flags, troubleshooting):
INSTALL.md.
Qdrant es opcional (el recall degrada a sparse-only sin el); ver la seccion
Qdrant de docs/INSTALL-ADVANCED.md.
Las rutas per-maquina se documentan en
config/paths.example.toml.
Related MCP server: MCP Memory Server
Caracteristicas
Memoria gobernada —
brain.db(SQLite) como unica fuente de verdad; todo cambio pasa por un unico servicio que anexa un evento de auditoria.Recall hibrido — denso (E5 1024d / Qdrant) + sparse (FTS5/BM25) fusionados con Reciprocal Rank Fusion; degrada a sparse-only sin Qdrant.
Inbox de candidatos — las capturas automaticas proponen, el humano aprueba; nunca se auto-escribe memoria activa.
Redaccion + dedupe en el write-path — secretos/PII fuera, duplicados por
content_hashfuera, antes de persistir o embeber.AI Router — cadena primario -> fallbacks por zona, deteccion de claves y telemetria de uso/ahorro; routing directo en Rust (sin sidecar LiteLLM).
Orquestador por reglas — mapea prompt -> intent -> workflow -> agentes -> memorias; reserva el modelo grande solo para la cola ambigua.
Tonos / personalidades — deteccion determinista del tono del chat (senales lexicas + peticion explicita) dentro del orchestrate; los tonos se editan en Library -> Tones. La config real (
~/.ultron/personality.json) es local y gitignored; el repo publica solo los seeds compilados (orchestrator/personality.rs). El tono viste unicamente la conversacion: nunca commits, docs ni artefactos.
Que es
ULTRON Control Center no reemplaza a Claude Code: lo envuelve. Le da memoria persistente y gobernada, enruta peticiones a varios proveedores LLM segun coste y disponibilidad, y detecta automaticamente que skill/agente especialista conviene para un prompt. Todo el estado vive en ficheros locales (SQLite + JSON + markdown) que puedes inspeccionar, versionar y editar a mano.
Pilar | Que hace |
Memoria gobernada |
|
Recall hibrido | Fusion de dos fuentes con Reciprocal Rank Fusion (RRF): denso (vectores E5 1024d en Qdrant) + sparse (FTS5/BM25 sobre |
AI Router | Catalogo de proveedores + zonas con cadena primario -> fallbacks, deteccion de claves, telemetria de uso/ahorro. Sin sidecar LiteLLM: routing directo en Rust. |
Orquestador | Mapea un prompt (posiblemente vago) a intent -> workflow -> agentes a delegar -> memorias relevantes -> restricciones, mediante reglas (no usa el modelo grande para lo que resuelven reglas/triggers). |
Arquitectura del backend (real)
El backend Rust vive en control-center/src-tauri/src/. El modulo central de
memoria esta en control-center/src-tauri/src/memory/.
Memoria: SQLite como fuente de verdad
~/.ultron/brain.db(SQLite, modo WAL) es la SoT canonica. El esquema canonico vive enmemory/schema_v3.rs(memoria) +memory/schema_v4.rs(migracion historica v4: tablasedges/unresolved_refs, hoy inertes — el grafo de codigo lo provee el MCP CodeGraph externo) /memory/migrations.rs, con modelos enmemory/model.rs(MemoryItem,MemoryCandidate,MemoryEvent, y los enums de gobernanzaStatus,Scope,Sensitivity,Source, etc.).MemoryService(memory/service.rs) es el unico escritor persistente. Invariante de gobernanza: toda mutacion pasa por aqui y anexa unMemoryEventde auditoria. Hooks y agentes nunca escribenmemory_itemsdirectamente; solo proponenMemoryCandidates que un humano (o una politica de auto-aprobacion) promueve.En el camino de escritura se aplican guardas: redaccion de secretos/PII (
memory/redaction.rs) antes de persistir o embeber, dedupe exacto porcontent_hash(memory/texthash.rs) y dedupe lexico por FTS.
Qdrant: indice derivado (no fuente de verdad)
La coleccion
ultron_memory(Qdrant) indexa los items ACTIVE con MultilingualE5Large, 1024 dimensiones (memory/qdrant_index.rs). Es un indice derivado: se puede reconstruir en cualquier momento conreindex_allybrain.dbsigue siendo la verdad.Tras cada escritura aprobada/editada/restaurada,
sync_indexmantiene Qdrant en paso con la SoT (best-effort; cualquier deriva es detectable/reparable viareconcile).La coleccion antigua
ultron_sessions(384d BGE) esta retirada; Qdrant aqui es siempre un indice, nunca la verdad.
Recall hibrido denso + sparse con RRF
El comando unico
recall(commands/memory/recall_unified.rs) fusiona con Reciprocal Rank Fusion (RRF_K = 60):DENSO: vectores E5 en
ultron_memory(Qdrant).SPARSE: FTS5/BM25 sobre
memory_items(solostatus=active).
Devuelve un context pack compacto de resumenes bajo presupuesto de tokens (
TOKEN_BUDGET = 1500), con trazas de por que esta memoria (rangos por fuente, scores, descartes) para el Retrieval Inspector.El antiguo
recall_hybrid(union de scores constantes, multi-store) fue eliminado el 2026-06-28 sin callers vivos: el unico camino de recall es el comando unificadorecallcon RRF. Las patas multi-store ECC, KG y Mem0 estan retiradas (Mem0 esta muerto por politica; no reintroducir): hoy las unicas fuentes vivas son Qdrant (denso) + SQLite/FTS5 (sparse).
Captura automatica via Stop hook
En
Stop, el hook pasa el transcript de la sesion amemory/capture.rs::capture_session. Este:pide a un LLM (via
ai_router::route, zonachat) extraer unos pocos hechos/decisiones durables;convierte cada hecho en un
MemoryCandidate(pasando por redaccion + dedupe) y lo deja en el inbox gobernado para aprobacion humana — nunca se auto-promueve a activo.
Fail-safe: si el router no tiene proveedor utilizable, degrada a una heuristica local barata para que el Stop hook nunca falle.
El inbox se gestiona desde
commands/memory/inbox.rs(memory_inbox_list,approve_candidate,reject_candidate).
AI Router: zonas, proveedores, fallback y telemetria
Backend en el modulo
ai_router/(mod.rs + exec.rs + providers/ + seed.rs + store.rs). Estado en tres JSON bajo~/.ultron/cockpit/ai-router/:providers.json(catalogo),zones.json(zonas conprimary+fallbacks),metrics.json(contadores + ahorro).route(zone, prompt)recorre la cadena primario -> fallbacks, salta proveedores sin clave API utilizable, registra latencia/tokens/ahorro en la telemetria y devuelveResult<String, String>(errores verbatim, nunca panic, cap de 10s).Wrappers por proveedor: anthropic (claude-haiku), codex (OpenAI-compat), gemini, groq, ollama (local, sin clave), deepseek. Los health checks usan sondas baratas y no gastan tokens; las invocaciones de test si.
Zonas por defecto:
chat,code-edit,code-review,summarize,utilityylight— las seis, y solo esas, tienen un consumidor real en el codigo (tabla abajo).
Para que sirven los LLM secundarios (y para que no)
El router no toca tu conversacion con Claude Code: esa sesion habla directa con Anthropic. Los modelos secundarios son la fontaneria barata de la app — tareas cortas, de una sola vuelta, donde gastar el modelo grande no aporta nada. Con una clave gratuita de Groq (y Gemini de relevo) funciona todo lo de abajo; sin ninguna clave, cada una cae a su camino sin IA o devuelve un error explicito, y el resto de la app sigue igual.
Zona | Quien la consume hoy | Para que |
| resumen de sesion, etiquetado de sesiones, alerta de coste | comprimir texto a una o pocas frases |
| captura de memoria y juez de candidatos | extraer decisiones de un turno y decidir si merecen guardarse |
| nombrado de hooks | poner nombre legible a un hook a partir de su codigo |
| categorias de apps, resumen de novedades de plugins | respuestas de una palabra o una linea |
| analisis previo a instalar un repo desde Library | informe JSON de que instala y que riesgo tiene |
La tabla es la lista completa: una zona sin consumidor es configuracion que
miente sobre lo que hace el sistema, asi que research-web, routing-decision
y code-fast-local se retiraron el 2026-09-21 (ninguna aparecia en un
route(...), ni en un comando Tauri, ni en la UI). La migracion
retire_unused_zones tambien las borra del zones.json ya escrito.
El enrutado de skills, el destilado de lecciones y el perfil de proyecto usan
una cadena aparte (orchestrator/skill_llm), con cuota propia, para no competir
con estas zonas. Ollama es opcional: hoy solo respalda el ultimo relevo de
light; si no vas a trabajar sin conexion, no hace falta instalarlo.
Orquestador: deteccion automatica de skills/agentes
El modulo
orchestrator/(rules.rs + ranking.rs + orchestrate.rs) mapeaprompt -> intent -> workflow -> agentes a delegar -> memorias -> restricciones. La clasificacion de intent es basada en reglas (bilingue es/en); el modelo grande se reserva para la cola ambigua.Reutiliza (no duplica): el catalogo de agentes (
memory/catalog.rs), el recall unificado y los workflows integrados (agent_orchestration.rs). Nunca escribe memoria persistente y delega a agentes reales en~/.claude/agents(los "ghost agents" inexistentes en disco se sanean).
Grafo de codigo: MCP CodeGraph (externo)
El grafo de codigo (que simbolos existen, quien llama a quien, analisis de impacto) lo provee CodeGraph (
@colbymchenry/codegraph, MIT), instalado como servidor MCP y consultado por los agentes viacodegraph_explore/codegraph_callers/codegraph_impact. Indexa el repo con tree-sitter (AST) en.codegraph/(SQLite local, incremental) — 20+ lenguajes.El casero v4 anterior (regex + tablas
edges/unresolved_refsen brain.db + panel System) fue jubilado (2026-06-08): aportaba menos y no se inyectaba al contexto del agente. La migracionschema_v4se conserva como historia inerte (las tablas existen vacias; no hay codigo que las consuma).
Plugin Updates: chequeo de actualizaciones de plugins
Sub-tab Updates dentro de Library (
src/components/library/PluginUpdates.tsx) que consume los comandos de backendplugin_check_updates_bulk(force)yplugin_changelog_summary(coordinate, installed_sha?).Compara el SHA instalado contra el ultimo SHA del marketplace por cada plugin, marca cuales tienen actualizacion disponible y muestra el ultimo mensaje de commit / resumen de changelog.
Stack
Capa | Tecnologia |
Frontend (Control Center) | Tauri 2 + React 19 + TypeScript ( |
Backend (Control Center) | Rust estable ( |
Memoria (SoT) | SQLite (FTS5) en |
Indice denso | Qdrant nativo ( |
Embeddings | E5 (denso) via |
Sidecar CLI hooks |
|
Scripting OS | PowerShell 5.1+ / scripts en |
Runtimes LLM | Claude Code (principal); Codex CLI opcional. Gemini CLI retirado 2026-06-19 (Google corto el free-tier OAuth); Gemini queda solo como fallback cloud del AI Router |
Binarios sidecar declarados en control-center/src-tauri/Cargo.toml:
ultron-memory (requiere la feature qdrant).
Build
# desde control-center/
npm install
npm run build:app # = kill-app + tauri build (genera el ejecutable de escritorio)Otros scripts utiles (en control-center/package.json):
npm run dev # vite dev server (frontend)
npm run tauri # CLI de Tauri
npm test # vitest (frontend)Nota Windows:
build:appejecuta primerokill-apppara cerrar cualquier instancia en marcha; un binario obsoleto es la causa habitual de "no se ha aplicado el cambio". Verifica HEAD y rebuild antes de re-implementar.
Estructura de carpetas
~/.ultron/
├── brain.db # SQLite — fuente de verdad de la memoria
├── qdrant-native/ # binario nativo de Qdrant (indice denso derivado)
├── qdrant_storage/ # datos persistidos por Qdrant
├── control-center/ # la app Tauri 2 + React 19
│ ├── src/ # frontend React/TS (componentes, tabs)
│ │ └── components/ # Dashboard, AIRouter, Library, Projects, ...
│ └── src-tauri/
│ └── src/
│ ├── memory/ # kernel de memoria (service, sqlite_store,
│ │ # qdrant_index, capture, redaction, texthash, ...)
│ ├── commands/ # comandos Tauri por dominio (memory, ai_router,
│ │ # projects, system_ops, ...)
│ ├── ai_router/ # AI Router (mod/exec/health/providers/seed/store/types)
│ ├── orchestrator/ # mod/orchestrate/ranking/rules/types_model
│ └── bin/ # sidecar ultron-memory
├── cockpit/ # config + estado en JSON/markdown
│ └── ai-router/ # providers.json, zones.json, metrics.json
├── personality.json # tonos del usuario (LOCAL, gitignored; se
│ # auto-siembra desde los seeds compilados)
├── hooks/ # hooks de ciclo de vida
├── skills/ # skills core (SKILL.md; catalogo curado no se publica)
├── plans/ projects/ # planes y proyectos
├── sessions/ # logs de sesion / telemetria de routing
└── docs/ # documentacion ampliadaEstado actual
Memoria: kernel canonico activo. SoT =
brain.db; indice densoultron_memory(E5 1024d) sincronizado en escritura; recall unificado denso+sparse con RRF operativo (degrada a sparse-only sin Qdrant). Write-path con redaccion de secretos y dedupe por content_hash cableados y testeados.Captura automatica: Stop hook ->
capture_session-> candidatos al inbox gobernado; aprobacion/rechazo humano via comandos de inbox.AI Router: routing real con cadena primario/fallback, deteccion de claves y telemetria de uso/ahorro; sin sidecar LiteLLM.
Tonos: deteccion determinista en el orchestrate (paridad JS/Rust del detector verificada con gate 16/16); editor visual en Library -> Tones y playground de deteccion.
personality.jsonlocal (gitignored) con seeds publicables compilados; limite duro: el tono solo aplica al chat, jamas a artefactos.Detector de texto IA (apoyo TFG): hook PostToolUse que avisa cuando la prosa escrita "canta" a IA + Lab de patrones deterministas sobre el catalogo de investigacion; matcher con CLI y banco de casos. Senala, no reescribe.
UI (Control Center, v15.8.0): barra lateral con Dashboard, Usage, AI Router, System (con sub-tabs de Hooks/Schedules), MCPs, Library (sub-tabs Skills/Agents/Rules/Updates), Memory, Notes, Learn, Sessions, Projects, Finance (solo build local con
VITE_FINANCE=1), Settings y Notifications. La pestana Memory esta viva (re-anadida 2026-06-04,Sidebar.tsx): expone el inbox de candidatos (aprobar/rechazar/editar) y la salud debrain.db; el kernel de memoria sigue siendo solo-backend, pero su gobierno human-in-the-loop se hace desde esta pestana (ademas de los comandos).
Licencia
MIT — ver LICENSE. Copyright (c) 2026 Rodrigo Fernandez.
This server cannot be deployed
Maintenance
Related MCP Connectors
An MCP memory server. One memory your agents share — across models, devices and apps.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Private persistent memory for Claude, ChatGPT & Gemini via MCP - semantic search, zero-code setup.
- mcpOAuthai.butlerbrain
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Related MCP Servers
- -licenseNot gradedqualityBmaintenanceEnterprise-grade MCP server for persistent, intelligent memory management across Claude Code sessions.-
- AlicenseNot gradedqualityDmaintenanceAn MCP server that gives Claude persistent memory by storing conversation context, entities, and enabling semantic search across sessions.18 npm1MIT
- AlicenseNot gradedqualityDmaintenanceMCP server providing Claude with persistent, local memory for tracking architectural decisions, dead ends, and project context across conversations.MIT
- AlicenseNot gradedqualityCmaintenanceA persistent memory MCP server for Claude Code that enables long-term recall across sessions via hybrid search, code intelligence, and tools for reading/writing memory.9 npm5MIT