FactMem
A local memory engine any AI tool can use. You own the SQLite file. Install with `npx -y @factmem/mcp`.
Documentación
Facthouse
Facthouse es un motor de memoria local para herramientas de IA. La mayoría de los productos de "memoria" indexan registros de chat. Facthouse toma la actividad del agente (mensajes, uso de herramientas y otro tráfico MCP) y aplica consolidación inspirada en la neurociencia para que avance a través de Datos (lo que sucedió en la sesión) → Información (hechos extraídos) → Conocimiento (creencias integradas en un grafo de entidades). Durante este proceso, Facthouse vincula entidades, elimina duplicados, reconcilia conflictos y reemplaza lo que está desactualizado. Los embeddings vectoriales añaden búsqueda semántica opcional sobre ese grafo. El almacén es un archivo SQLite en tu disco.
Inicio rápido
Requiere Node 22.5 o 24+.
npx -y @facthouse/mcp
facthouse init
facthouse init --web es la misma configuración que un formulario de navegador: imprime una URL 127.0.0.1 y no abre un navegador.
Pulsa Enter para aceptar cada valor predeterminado (copy = registros de sesión de Claude Code o Cursor en disco; type record si el asistente debe guardar hechos). Si elegiste copy, init pregunta si copiar los registros existentes y luego si extraer e integrar. Init imprime un fragmento MCP tan pronto como se escribe el almacén: agrégalo a la configuración MCP del cliente mientras copy/extract se ejecutan. Reinicia el cliente cuando init termine.
En el cliente, indica algo duradero en una conversación ordinaria: no hay comando de recordar.
Pregúntalo de nuevo en la siguiente sesión, o facthouse search. Ese es el almacén.
Copia desde registros de Claude Code o Cursor, o graba desde cualquier cliente MCP: Cómo entran las conversaciones. Reproducción: facthouse.dev/demo.html. CLI: abajo.
Lo que obtienes
- SQLite local. Postgres opcional. El aislamiento es el directorio, no una columna.
- Grafo de entidades. Personas, organizaciones, proyectos, lugares, productos: extraídos, tipificados y vinculados.
- Búsqueda híbrida. BM25 + dominio estructurado + rutas del grafo de entidades, fusionados mediante Reciprocal Rank Fusion. Un proveedor de embeddings añade significado como cuarta lista; desactivado por defecto.
- Memoria dentro de la sesión.
get_session_contextes el mismo informe quememory://briefing. Los clientes solo con herramientas deberían llamarlo al inicio de la sesión. - Historial inmutable. Los hechos nunca se eliminan, solo se reemplazan.
Cómo funciona
Una base de datos SQLite. Tres tablas en ella, no tres bases de datos: Datos (lo que sucedió en la sesión) → Información (hechos extraídos) → Conocimiento (creencias integradas).
- D (
session_events) — lo que se dijo (transcripciones copiadas, o lo que el asistente graba) - I (
session_facts) — lo que se acaba de extraer, ocapture_fact - K (
facts) — conocimiento integrado
FTS5 (palabras) y embeddings opcionales (significado) son índices de K. No son un segundo almacén. La búsqueda semántica está desactivada a menos que la actives: search "shellfish" encuentra un hecho sobre mariscos, search "food" no, hasta que elijas un modelo de embeddings: un modelo es una opinión sobre qué significa "similar".
Dos velocidades. Copy sigue transcripciones nombradas hacia Datos. Extract convierte nuevas líneas de transcripción en hechos autocontenidos (D→I). Integrate los ajusta a lo que el almacén ya sabe: dominios, entidades, duplicados, contradicciones, el grafo (I→K). consolidate es el paraguas: copy, extract e integrate juntos. Extract está limitado a 50 líneas por ejecución, por lo que un primer backfill nunca se gasta en todo; cuando extract se ejecuta, toma las 50 líneas más antiguas. La consolidación no inventa una frase que nadie dijo.
Un hook no puede llamar a herramientas MCP (esas existen solo en la conexión del asistente) y no debe esperar un paso del modelo. Por eso no invoca consolidate. Ejecuta facthouse notify …, que le dice al servidor ya en ejecución que ocurrió un momento y regresa de inmediato. consolidate es el verbo de la canalización (herramienta MCP o CLI); el llamador espera. notify compaction es ese verbo solicitado al servidor en vivo, de forma asíncrona. notify threshold es una política diferente (solo extract, si corresponde).
Automático
| Cuándo | Copy | Extract (D→I) | Integrate (I→K) |
|---|---|---|---|
| El servidor MCP de Facthouse se inicia | sí | sí (límite 50) | sí |
| Se llama a una herramienta o recurso de Facthouse | sí, si las fuentes están nombradas y JSONL creció | no | no |
| El proceso MCP de Facthouse sale | no | no | sí |
Invitable
| Llamada | Desde | Copy | Extract (D→I) | Integrate (I→K) |
|---|---|---|---|---|
consolidate | Herramienta MCP o CLI. El llamador espera. | sí | sí (límite 50) | sí |
facthouse notify compaction | Otro proceso (recomendado PreCompact; no lo instalamos). No espera. | sí | sí (límite 50) | sí |
facthouse notify threshold | Otro proceso. No espera. No es un hook de copy-store. | no | sí, si corresponde (límite 50) | no |
En un almacén de copia predeterminado sin hooks adicionales, solo se ejecuta la tabla automática: Facthouse se inicia (los tres), copy en cada llamada a herramienta o recurso de Facthouse si las fuentes nombradas crecieron, e integrate en una salida limpia del proceso. Cerrar una ventana de chat puede omitir la fila de salida; el siguiente inicio aún consolida. "Due on threshold" significa al menos 10 líneas sin examinar y dos minutos desde la última ejecución con compuerta. consolidate --all levanta el límite de extract. La compactación se recomienda con PreCompact (notify compaction): los mismos tres pasos que consolidate, en el servidor en ejecución, sin esperar. No instalamos el hook. No es un hook Stop. record activa el extract por umbral en un almacén de grabación: no instales hooks de grabación en un almacén de copia.
El almacenamiento necesita Node. La inteligencia necesita un modelo de lenguaje. Por defecto, ese es el Claude Code CLI en tu suscripción existente. Sin él, la consolidación recurre a una heurística integrada que no extrae hechos de transcripciones. capture_fact aún almacena hechos, sin entidades y sin enrutamiento de dominio.
Cómo entran las conversaciones
Dos formas. Elige una por almacén.
| Copiar desde transcripciones | El asistente graba | |
|---|---|---|
| Quién | Claude Code o Cursor (registros de sesión en disco, bajo el inicio del cliente) | Cualquier cliente MCP (Grok, Desktop, …) |
| Cómo | Nombra una fuente; Facthouse copia nuevas líneas de esos registros al almacén | sources vacío; el asistente llama a capture_fact |
| Primera ejecución | Recorrido TTY, elige copy, establece cwd; init pregunta si copiar registros existentes y luego si extraer e integrar | Recorrido TTY, elige record |
En un almacén de copia, capture_fact es una corrección para cada cliente MCP, no solo para el que escribe JSONL. Grok no tiene adaptador de transcripción: no pongas Claude Code en copia y Grok en el mismo almacén esperando que Grok grabe.
facthouse init
Elige copy, establece cwd. Init pregunta si copiar registros existentes y luego si extraer e integrar (Enter = todas las líneas copiadas; una selección de 500 o más te pide que escribas la elección de nuevo). Rechaza extract para hacerlo más tarde con facthouse consolidate (--all toma las líneas restantes sin examinar, no las omitidas por estar fuera de una ventana de 7 o 30 días). Después de eso, el servidor copia nuevas líneas cuando maneja una llamada de Facthouse. Extract e integrate siguen la tabla en Cómo funciona.
Compact (recomendado): facthouse notify compaction — no instalamos el hook. No es un hook Stop de fin de turno.
MCP
Funciona con cualquier herramienta compatible con MCP. Almacén predeterminado: ~/.facthouse. Una ruta diferente es "env": { "FACTHOUSE_DATA": "/absolute/path" } en el fragmento MCP. JSON acepta barras diagonales en Windows.
Cursor consume herramientas pero no recursos hasta que exista un adaptador posterior: search_knowledge y get_entity aún funcionan allí; llama a get_session_context al inicio de la sesión.
Los recursos son contexto que el cliente carga automáticamente — sin llamada a herramienta. Las herramientas solo ayudan si el asistente recuerda usarlas; los recursos simplemente están presentes.
memory://briefing— Todo lo que vale la pena saber ahora mismo: perfil, lo aprendido en la última consolidación, hilos abiertos y conocimiento reciente. Markdown, mantenido aproximadamente en una pantalla.memory://profile— Hechos de identidad central, los más importantes primero.
Ambos son vistas de solo lectura sobre la misma base de datos que consultan las herramientas. Los clientes que nunca cargan recursos (Cursor, Windsurf, Grok) obtienen el mismo informe llamando a get_session_context al inicio de una conversación. Sin segundo esquema de perfil.
Herramientas
Sesión
log_event— Registrar eventos de conversación (mensajes, artefactos).get_events— Recuperar eventos de la sesión actual o anterior.get_session_context— Informe de trabajo (el mismo markdown quememory://briefing) más hechos capturados en esta sesión. Llámalo al inicio de cada conversación si el cliente no carga recursos.
Lectura
get_entity— Todo lo conocido sobre cualquier sujeto nombrado — persona, organización, proyecto, lugar, producto — y cómo se conecta. Cuando varias filas comparten el nombre bajo diferentes tipos, los hechos de todas regresan. Guiones, guiones bajos y puntuación suelta cuentan como las mismas letras solo cuando eso no une dos nombres ya almacenados como filas separadas. Si no hay entidad con ese nombre, los hechos que mencionan la redacción aún regresan en lugar de un fallo vacío.get_context— Todo lo relevante para un tema (búsqueda + recorrido de entidades)search_knowledge— Búsqueda híbrida en conocimiento integrado
Escritura
capture_fact— Almacenar un hecho. En un almacén de copia, esto es una corrección para algo que la extracción omitió; en un almacén consourcesvacío, así es como entran los hechos. La descripción que ve el asistente se genera a partir de esa misma regla.consolidate— Integrar hechos pendientes en conocimiento a largo plazo. Extrae entidades, resuelve duplicados, detecta contradicciones, construye el grafo de conocimiento.- Herramientas de inferencia — Opt-in, desactivadas por defecto (
inferences.enableden config.json). Una hipótesis cita ids de hechos existentes y permanece pendiente hasta que se confirma. Esas herramientas no se registran hasta que actives la compuerta. Consolidate nunca inventa una frase que nadie dijo.
Meta
get_schemas— Dominios disponibles y estructuraget_stats— Conteo de hechos, conteo de entidades, distribución de dominios, backlog de extracción, gasto de inteligencia
CLI
El JSON MCP inicia el servidor mediante npx y no necesita una instalación global. npm install -g pone facthouse en PATH para init, settings, stats e inspect. El mismo CLI sin PATH es npx -y -p "@facthouse/mcp" -- facthouse — fija la versión; cita el paquete para que PowerShell no haga splat. -p y -- evitan que un binario global más antiguo gane. npx -y @facthouse/mcp sin -p / facthouse es el servidor; no lo ejecutes como comando de shell para init, settings o stats. El pegado MCP inicia el servidor. No pone facthouse en PATH. Para inspeccionar el archivo desde una terminal, consulta CLI abajo.
Estos comandos CLI funcionan en bash, zsh y PowerShell. Cita @facthouse/mcp en PowerShell. Las rutas Git Bash /c/... no son PowerShell; usa C:/... y pasa --data en lugar de cd o export. En Git Bash, cita una ruta con barra invertida o escribe C:/... — una \ sin citar es un escape. ~/ se expande en todas las plataformas. WSL usa /mnt/c/.... FACTHOUSE_DATA en un fragmento MCP aplica solo a ese proceso de servidor. Un comando facthouse de terminal necesita --data, FACTHOUSE_DATA en el entorno que hereda ese shell, o un almacén .facthouse en este proyecto. Los hooks no ven el entorno de mcp.json.
npm install -g @facthouse/mcp@0.31.0
facthouse init --yes
Si npm install -g falla porque ya existe un comando llamado mcp, elimina ese comando sobrante y reintenta.
npx -y -p "@facthouse/mcp@0.31.0" -- facthouse init --yes
npx -y -p "@facthouse/mcp@0.31.0" -- facthouse settings --json
npx -y -p "@facthouse/mcp@0.31.0" -- facthouse stats
npx -y -p "@facthouse/mcp@0.31.0" -- facthouse inspect
| Tarea | Uso |
|---|---|
| Servidor MCP (lo que inicia el cliente) | El fragmento JSON: npx con argumentos -y y una versión fijada @facthouse/mcp@…. Sin instalación global. |
facthouse en PATH | npm install -g @facthouse/mcp@… (misma fijación). Actualízalo cuando subas el fragmento. |
| Cambiar ajustes adicionales después | facthouse settings (o settings --data <dir>). No restablece el archivo. |
| Un comando CLI, sin PATH | npx -y -p "@facthouse/mcp@…" -- facthouse … |
facthouse init [dir]
El recorrido es cómo un humano en la primera ejecución escribe config.json. Omítelo y el servidor aún crea el directorio en el primer arranque MCP.
En un terminal, init pregunta por el directorio de datos, copiar transcripciones vs registros de asistente (copiar por defecto), búsqueda semántica y más ajustes. --yes nunca pregunta y deja sources vacío. --web imprime una URL 127.0.0.1 y no abre un navegador; --yes rechaza --web. En un terminal, --force aún hace esas preguntas y luego reemplaza todo el archivo; --yes --force es el reinicio silencioso. --force no se fusiona con el archivo anterior.
facthouse init --yes
facthouse init --yes ~/my-memory
facthouse init --yes --force
El config.json generado es donde cambias el comportamiento de consolidación — más notablemente intelligence.provider (cli por defecto; heuristic para un respaldo regex sin dependencias, o FACTHOUSE_PROVIDER=heuristic en tiempo de ejecución). Init no pregunta ese campo.
facthouse settings
Cambia ajustes adicionales en un config.json existente (modelo CLI, tiempo de espera, extracción local opcional). No restablece el resto del archivo. Se rechaza si no hay config.json (este comando no crea un almacén). --json / no un terminal imprime los ajustes actuales y no escribe. --web son los mismos ajustes en una página local (imprime URL, sin apertura automática).
facthouse settings
facthouse settings --data ~/my-memory
facthouse record
Inserta eventos directamente en la base de datos (no se necesita un servidor en ejecución). Compatible con demostraciones y almacenes sin fuente nombrada. No es el valor predeterminado de Claude Code o Cursor — eso es sources más facthouse consolidate.
# From a hook (reads JSON payload from stdin):
echo '{"hook_event_name":"UserPromptSubmit","prompt":"hello"}' | facthouse record --role user
# With explicit content:
facthouse record --role user --event-type message --content "hello world"
# Options:
# --role user | assistant | system | tool (default: user)
# --event-type message | tool_call | tool_result | artifact (default: message)
# --content-type text | json | image | audio | binary (default: text)
# --content Event content (or pipe via stdin)
# --speaker Named participant when the transcript has one
# --session-id Target session (default: most recent)
# --data Data directory (default: FACTHOUSE_DATA, a .facthouse store in this project, or ~/.facthouse)
facthouse consolidate
Copia nuevas líneas de config.sources, extrae hechos candidatos de ellas e integra los hechos pendientes en el conocimiento. El único comando que gasta llamadas de modelo:
facthouse consolidate
facthouse consolidate --copy # copy only; spends nothing
facthouse consolidate --integrate # pending facts to knowledge; no extract pass
facthouse consolidate --all # extract the whole backlog now
facthouse consolidate --limit 200 # extract the oldest 200
# Steps — named steps run, in order; none named means all three:
# -c, --copy copy new transcript lines into the store
# -e, --extract turn new lines into candidate facts (the model call)
# -i, --integrate classify, link, dedupe, supersede, embed
# Extract is capped at 50 lines per run so a first backfill is never spent on
# the lot; the run says how many remain. --all lifts the cap, --limit N sets it.
# --json print the result object instead of the summary
# --data Data directory (default: FACTHOUSE_DATA, a .facthouse store in this project, or ~/.facthouse)
Respeta el proveedor configurado (por defecto claude -p). Un sources vacío hace que el paso de copia no haga nada. Establece cwd en la fuente a menos que pretendas copiar cada grupo de proyectos. No ejecutes también hooks record en un almacén con fuentes nombradas.
facthouse notify <moment>
Dile al servidor MCP en ejecución que ocurrió un momento. El servidor decide qué ejecutar y lo hace en segundo plano, por lo que un hook regresa de inmediato:
facthouse notify compaction # client about to compact: copy new JSONL, extract, integrate (does not wait)
facthouse notify threshold # events arrived: extract if the threshold is due
# Options:
# --data Data directory (default: FACTHOUSE_DATA, a .facthouse store in this project, or ~/.facthouse)
Que no haya un servidor escuchando no es un error: el comando lo dice y sale con código 0, y el siguiente inicio de sesión lo cubre. Esto es lo que llama el hook PreCompact.
facthouse search <query>
facthouse search "coffee"
facthouse search "coffee" --domain preferences
facthouse search "coffee" --json
# Options:
# --domain Prioritise a domain. Biases ranking; does not filter
# --limit Maximum results (default: 20)
# --json Emit the raw search payload
# --data Data directory (default: FACTHOUSE_DATA, a .facthouse store in this project, or ~/.facthouse)
--domain sesga la clasificación en lugar de filtrar. Un filtro estricto ocultaría un hecho archivado bajo un casi-sinónimo.
facthouse stats
facthouse stats
facthouse stats --json
Los hechos son inmutables — los hechos superados se conservan — por lo que el recuento actual y el total difieren legítimamente una vez que algo ha sido superado. --json incluye la versión del paquete del binario que responde. El gasto de inteligencia son llamadas, tokens y tiempo transcurrido para extraer / clasificar / entidades / conciliar / superar / resumir, con proveedor y modelo por etapa. Los embeddings no son ese número.
facthouse inspect
Muestra D, I, K, entidades y el grafo. Escribe un archivo HTML local bajo el directorio de datos (no el directorio de trabajo actual). Imprime la ruta. No abre un navegador. El archivo es una exportación de memoria — trátalo como stats --json. La misma página también muestra el gasto de inteligencia (Grafo / Gasto).
facthouse inspect
facthouse inspect --graph
facthouse inspect --layer k
facthouse inspect --json
facthouse inspect --entity Helios --limit 20 --output ~/inspect.html
--layer health|d|i|k|entities|graph|all imprime tablas de terminal (más recientes primero, con límite). --graph (el predeterminado cuando no hay --layer / --json) escribe inspect.html. --limit es 10 para tablas y 50 para el lienzo. --all dibuja cada nodo — una bola de pelo, explícito. La búsqueda y el filtro de tipo en la página aún pueden alcanzar un nodo que estaba fuera del límite.
Avanzado
Otro almacén
El almacén es este directorio. Los clientes lo comparten usando la misma ruta. Un segundo almacén es un segundo directorio, no una segunda instalación. El nombre predeterminado del servidor MCP es facthouse. La división no es un filtro sobre qué cliente escribió la fila. Trabajo y personal es una razón para dividir, no una configuración requerida.
Un directorio de datos no predeterminado imprime un nombre de servidor MCP distinto para que dos almacenes puedan compartir un mcp.json. Init contra cada directorio adicional imprime ese fragmento. Ejemplo:
{
"mcpServers": {
"facthouse-personal": {
"command": "npx",
"args": ["-y", "@facthouse/mcp@0.31.0"],
"env": { "FACTHOUSE_DATA": "C:\\Users\\alex\\.facthouse-personal" }
},
"facthouse-work": {
"command": "npx",
"args": ["-y", "@facthouse/mcp@0.31.0"],
"env": { "FACTHOUSE_DATA": "C:\\Users\\alex\\.facthouse-work" }
}
}
}
Apunta el sources.cwd de cada almacén (o hook --data) solo a ese almacén. Dos directorios no aíslan nada si ambos copian el mismo hogar.
Postgres (opcional)
SQLite es el predeterminado y no necesita software adicional. Para usar Postgres en su lugar, establece storage.provider a "postgres" en el config.json de ese almacén, o FACTHOUSE_STORAGE=postgres en la entrada MCP, y establece FACTHOUSE_POSTGRES_URL a una URL postgres:// (o postgresql://). La contraseña pertenece al entorno, no a config.json. Si falta la URL o el servidor no se puede alcanzar, Facthouse se detiene; no crea un archivo SQLite.
El directorio de datos sigue siendo la memoria: config.json y el socket del programador viven allí. Las tablas viven en la URL. Dos memorias necesitan dos directorios y dos bases de datos.
Init no pregunta qué motor usar. facthouse init --yes aún escribe sqlite.
Ejemplo — solo marcadores de posición; no pongas una contraseña real en un archivo confirmado:
{
"mcpServers": {
"facthouse": {
"command": "npx",
"args": ["-y", "@facthouse/mcp@0.31.0"],
"env": {
"FACTHOUSE_DATA": "C:\\Users\\alex\\.facthouse-work",
"FACTHOUSE_STORAGE": "postgres",
"FACTHOUSE_POSTGRES_URL": "postgres://USER:PASSWORD@localhost:5432/facthouse"
}
}
}
}
Copiar versus registrar
Elige un mecanismo por almacén.
Recomendado — copiar. Nombra una fuente claude-code o cursor (establece cwd) y ejecuta facthouse consolidate desde la CLI primero. El servidor MCP también copia al inicio de sesión y cuando maneja una llamada. Grok y Codex son adaptadores posteriores. Los valores kind desconocidos se rechazan.
{
"sources": [
{
"kind": "claude-code",
"home": "~/.claude",
"cwd": "C:\\dev\\app"
}
]
}
home es el directorio de configuración del cliente (~/.claude o ~/.cursor — ejemplos de ruta, no descubrimiento adicional). Cursor es "kind": "cursor" y home/projects/*/agent-transcripts/**/*.jsonl solamente — no Composer SQLite. Cursor codifica C:\\dev\\app como c-dev-app (Claude Code usa C--dev-app). Un primer relleno de más de 50 líneas toma varias ejecuciones, o un facthouse consolidate --all.
Alternativa — registrar, sin fuentes. Deja sources vacío. Canaliza un payload de hook del cliente a facthouse record si tienes uno. MCP log_event / capture_fact siguen funcionando.
No instales hooks de registro en este almacén — ambos escriben las mismas filas. Facthouse no detecta ni reescribe configuraciones de hooks existentes.
Modo de solo registro MCP
Para omitir el asistente (solo registro — sin copia de transcripción), pega esto. El servidor crea ~/.facthouse en el primer arranque; no se te hacen esas preguntas.
{
"mcpServers": {
"facthouse": {
"command": "npx",
"args": ["-y", "@facthouse/mcp@0.31.0"]
}
}
}
Hooks
PreCompact notify compaction es el útil: cuando el cliente está a punto de compactar, un hook de corta duración le dice al servidor en ejecución, y el hook regresa de inmediato. El servidor copia nuevas líneas JSONL, luego extrae e integra — la compactación no elimina la transcripción, y el hook no fotocopia la ventana en vivo. Init imprime este JSON con --data completado. Pégalo en Claude Code .claude/settings.json (usuario o proyecto). No lo instalamos. No instales un hook Stop. No instales hooks de registro en este almacén — ambos escriben las mismas filas.
mcp.json env no es visible para los hooks. Pasa el mismo --data (o establece FACTHOUSE_DATA en el entorno que el propio cliente hereda). El comando debe invocar la CLI (facthouse), nunca el binario del servidor. npx -y @facthouse/mcp sin -p / facthouse inicia el servidor MCP y cuelga un hook. Fija la versión del paquete, cítala si el hook ejecuta PowerShell, y pon -- antes de facthouse para que un binario global más antiguo en PATH no pueda ganar.
JSON del hook PreCompact
{
"hooks": {
"PreCompact": [
{
"hooks": [
{
"type": "command",
"command": "npx -y -p @facthouse/mcp@0.31.0 -- facthouse notify compaction --data /absolute/path/to/the-same-store"
}
]
}
]
}
}
PreCompact notify compaction le pide al servidor en ejecución que consolide: copiar las líneas JSONL más nuevas, extraer, integrar. El hook regresa de inmediato; el servidor hace el trabajo. No instalamos un hook Stop de fin de turno. En Windows, la ruta --data es el mismo directorio absoluto que pusiste en FACTHOUSE_DATA (por ejemplo C:\\Users\\alex\\AppData\\Local\\Temp\\facthouse-try).
La copia incremental frecuente intercala conversaciones en la secuencia global: un chat largo mantenido abierto se corta entre otros chats. El progreso de extracción es por conversación, por lo que un tiempo de espera en un chat no descarta otro. Reducir extraction.batch_size significa más llamadas de extracción (más posibilidades de tiempo de espera), no un retén para todo el almacén. facthouse stats informa eventos no extraídos contra esa marca de agua de extracción.
Si el servidor MCP no se inicia, o no lista herramientas, verifica la versión del paquete que el cliente realmente generó. Un facthouse global en PATH puede estar años detrás del pin en este README. Diagnostica con facthouse stats --data <dir> (la CLI imprime si el programador está escuchando) e inspeccionando serverInfo.version desde initialize más tools/list sobre stdio. 0.2.x responde initialize y luego lanza una excepción en tools/list.
Embeddings, modelo, tiempo de espera, bitemporal
Establece embedding.provider en config.json a "ollama" (local, sin clave API) o "voyage" (alojado), ejecuta facthouse consolidate, y search "food" comienza a devolver la alergia. Los hechos se incrustan cuando se consolidan. Voyage aplica un límite de 3 solicitudes/minuto hasta que haya un método de pago en la cuenta.
La búsqueda por significado es un escaneo exacto de vectores almacenados cuando el conjunto es pequeño. Cuando ese conjunto es grande (32 MiB predeterminados del modelo actual), se usa un índice HNSW de esos vectores en su lugar: en proceso en SQLite, o un sidecar Postgres vector cuando la extensión está habilitada. Los almacenes pequeños permanecen exactos. Un motor faltante mantiene la búsqueda exacta e imprime una advertencia; Facthouse no instala un complemento nativo. embedding.ann es null (auto), false (nunca) o true (forzar cuando el motor lo permite). Esto no activa los embeddings.
intelligence.cli.model y intelligence.cli.timeout_ms son ajustes adicionales. Los ajustes de primera ejecución (Y) pueden escribirlos; más tarde, facthouse settings. Init no pregunta intelligence.provider; FACTHOUSE_PROVIDER=heuristic es el interruptor de apagado. El respaldo heurístico no extrae hechos de transcripciones.
El habla de canal de usuario sin nombre se atribuye al propietario del almacén; un nombre para mostrar aún no crea una persona. El respaldo adicional (asentimiento, una observación de herramienta, un hablante diferente reformulando) se registra, no se puntúa, a menos que el almacén establezca pesos de clasificación interlocutor en config.json. El motor no incluye ninguno. Las claves de peso coinciden con la cadena del hablante tal como se almacena, por lo que dos personas con el mismo nombre comparten una clave.
Establece temporal.mode a bitemporal para registrar cuándo el sistema retractó una creencia, para que la búsqueda pueda responder qué creía el almacén en un instante.
Gasto de inteligencia
facthouse stats y get_stats informan llamadas de consolidación facturadas: tokens, tiempo transcurrido y el proveedor más el modelo en cada etapa (extraer, clasificar, entidades, conciliar, superar, resumir). Una ejecución que no informó tokens omite esos campos en lugar de mostrar cero. Los embeddings son una API diferente y no son este número.
El intelligence.token_budget opcional limita el extract facturado por proveedor en ventanas móviles. Sin establecer es ilimitado. Sobre el límite, consolidar omite el extract, mantiene la marca de agua y no recurre a la heurística. Las estadísticas e inspeccionar Gasto muestran usado y restante en cada límite, y cuándo el uso más antiguo en esa ventana caduca (resets).
"intelligence": {
"token_budget": {
"cli": { "week": "10M" }
}
}
hour, day, week y month son móviles. Omite una escala para dejarla ilimitada. El espacio restante está en facthouse stats, get_stats e inspeccionar Gasto. Establece el límite en el config.json de este almacén — no hay comando de presupuesto.
La inteligencia local opcional es un interruptor diferente de los embeddings. Agrega intelligence.http en un host compatible con OpenAI. El protocolo es POST /v1/chat/completions; solo cambia el puerto:
| Host | URL típica |
|---|---|
| Ollama | http://localhost:11434/v1 (la predeterminada si omites la URL) |
| LM Studio | http://localhost:1234/v1 |
| vLLM | http://localhost:8000/v1 |
| llama.cpp | http://localhost:8080/v1 |
La cadena del modelo es la que ese host liste. GET {base_url}/models imprime los nombres. nomic-embed-text es solo de incrustación y no extraerá. Si el host está activo y sirve exactamente un modelo de chat, Facthouse lo usa para esta ejecución y te dice que fijes intelligence.http.model. Si hay varios modelos de chat listados, establece ese campo; la extracción no adivinará.
Extrae y resume, luego usa ese host; reconciliar y sobrescribir permanecen en la CLI a menos que listes intelligence.stages. Cada etapa puede establecer on-fail en cli, http o none (ver el JSON a continuación). La extracción HTTP por defecto reintenta en la CLI (cuenta contra el presupuesto de tokens de la CLI). La contradicción por defecto es none — sin cambio de proveedor. none mantiene la marca de agua de extracción — no cae en la heurística. La configuración adicional de la primera ejecución (Y, después de la ruta recomendada) puede establecer el host, el modelo y el on-fail de extracción. Más tarde, facthouse settings fusiona esos ajustes en un archivo existente sin restablecerlo. facthouse inspect Spend muestra los mismos ajustes y copia JSON; no guarda config.json.
El script en vivo npm run test:http-intelligence ha pasado en qwen2.5vl:7b.
"intelligence": {
"http": {
"base_url": "http://localhost:11434/v1",
"model": "qwen2.5vl:7b"
},
"stages": {
"extract": { "provider": "http", "on_fail": "cli" },
"summarise": { "provider": "http", "on_fail": "cli" },
"reconcile": { "provider": "cli", "on_fail": "none" },
"supersede": { "provider": "cli", "on_fail": "none" }
}
}
Demo de CLI (sin fuente de transcripción)
Almacén desechable, no la ruta de captura para un hogar real de Claude Code o Cursor. Estas tres líneas se escriben.
export FACTHOUSE_DATA=/tmp/facthouse-demo
om() { npx -y -p "@facthouse/mcp@0.31.0" -- facthouse "$@"; }
om init --yes
om record --role user --content "I prefer dark mode in every editor, and I never want telemetry enabled."
om record --role user --content "I am allergic to shellfish, so avoid seafood restaurants when booking anything."
om record --role user --content "My colleague Robin at Acme is leading the Atlas migration project this quarter."
om consolidate
om search "Atlas"
om stats
$env:FACTHOUSE_DATA = Join-Path $env:TEMP "facthouse-demo"
function om { npx -y -p "@facthouse/mcp@0.31.0" -- facthouse @args }
om init --yes
om record --role user --content "I prefer dark mode in every editor, and I never want telemetry enabled."
om record --role user --content "I am allergic to shellfish, so avoid seafood restaurants when booking anything."
om record --role user --content "My colleague Robin at Acme is leading the Atlas migration project this quarter."
om consolidate
om search "Atlas"
om stats
allergies no es un dominio que Facthouse distribuya. El motor no tiene vocabulario incorporado — leyó la conversación y decidió que ese hecho necesitaba un hogar. Un dominio sesga la clasificación en lugar de filtrar. Limpieza: rm -rf /tmp/facthouse-demo (Git Bash / macOS / Linux) o Remove-Item -Recurse -Force $env:TEMP\facthouse-demo (PowerShell).
Integración
Las descripciones de herramientas de Facthouse indican a los asistentes cuándo buscar y cuándo vale la pena preparar una corrección. No son cómo las conversaciones de Claude Code entran al almacén — eso es copia desde una fuente nombrada.
Sin configuración
Claude Code o Cursor: nombra una entrada sources (establece cwd) y ejecuta facthouse consolidate desde la CLI primero. El inicio de sesión de MCP también copia. capture_fact está ahí si el asistente necesita corregir o agregar algo que la copia más extracción no producirá.
Los clientes sin adaptador de copia aún dependen de log_event / capture_fact hasta que exista su adaptador.
Puntos de enganche
| Punto de enganche | Cuándo | Qué llamar | Por qué |
|---|---|---|---|
| Inicio de sesión | Comienza la conversación | memory://profile (automático), search_knowledge | El asistente sabe quién eres desde el primer mensaje |
| Corrección | Falta un hecho duradero en el almacén | capture_fact | Opcional; las conversaciones de Claude Code ya están en session_events mediante copia |
| Búsqueda previa a la respuesta | Antes de generar una respuesta | search_knowledge, get_context | Respuestas informadas por conocimiento almacenado |
| Pre-compactación | Antes de la compresión de la ventana de contexto | facthouse notify compaction | El servidor copia nuevas líneas, extrae, integra |
| Puntos de interrupción naturales | Cambio de tema, finalización de tarea | consolidate (opcional) | Mantiene el grafo de conocimiento actualizado |
Sobre pre-compactación: facthouse notify compaction pide al servidor consolidar. No es un enganche record.
Claude Code
Crea .claude/rules/facthouse.md en tu proyecto (o ~/.claude/rules/facthouse.md globalmente):
# Facthouse
- Conversations are copied from the named Claude Code source (first backfill: `facthouse consolidate` on the CLI)
- Do not install record hooks on this store — both write the same rows.
- Identity context loads automatically from the `memory://profile` resource — no tool call needed
- Before answering questions this store might already know, call `search_knowledge`
- Call `capture_fact` only to correct or add something that is not in the transcript
- When the conversation is getting long, call `consolidate` (or rely on PreCompact `facthouse notify compaction`)
- At natural breakpoints (topic change, task completion), call `consolidate` to keep the knowledge graph current
Para permitir herramientas de Facthouse sin avisos de aprobación por llamada, agrega al arreglo permissions.allow en .claude/settings.json:
{
"permissions": {
"allow": [
"mcp__facthouse__*"
]
}
}
Cursor / Windsurf
En Cursor Directory, Add to Cursor es por componente: haz clic en el servidor MCP y nuevamente en la regla. Eso inicia un almacén de registros en ~/.facthouse — sin facthouse init. La pestaña Hooks es Copiar en ~/.cursor/hooks.json, no Add to Cursor. Para copiar transcripciones de Agent, ejecuta facthouse init, elige copiar, tipo cursor.
Agrega a .cursorrules (Cursor) o .windsurfrules (Windsurf) en la raíz de tu proyecto:
When the facthouse MCP server is available:
- At the start of every conversation, before answering, call get_session_context unless you already loaded the memory://briefing resource. That call returns the same working briefing the resource would have injected. Tools-only clients never fetch resources.
- Before answering questions this store might already know, call search_knowledge
- To find out everything known about a particular person, project, or thing, call get_entity
- Call capture_fact only to correct or add something copy or extraction missed
Cursor y Windsurf consumen herramientas pero no recursos, por lo que memory://profile no se cargará solo allí. Las conversaciones de Cursor se copian con kind: "cursor" (JSONL bajo ~/.cursor/projects/, no el almacén de compositor SQLite).
Claude Desktop / otros clientes MCP
Aún no hay adaptador de copia. Las descripciones de herramientas manejan la búsqueda y capture_fact opcional; las conversaciones no se rastrean hasta que exista un adaptador posterior.
Recuperación de espacio
Facthouse registra conversación cruda y salida de herramientas en session_events. En un almacén conectado a un cliente agéntico, esto se convierte en casi toda la base de datos. Un almacén medido en uso diario tenía 47,000 eventos y 493 MB contra 21 hechos integrados.
facthouse stats informa la capa cruda junto con el conocimiento, incluido cuánto es recuperable. Para recuperarlo:
facthouse prune # report only — nothing is deleted
facthouse prune --apply --vacuum # delete, then rebuild the file
Establece retention.disk_budget en config.json a un tamaño como "2GB" para limitar memory.db. Sin establecer es ilimitado; init no escribe un límite. Cuando hay un límite y el archivo está lleno, los eventos crudos inalcanzables se podan automáticamente para que los nuevos registros puedan reutilizar ese espacio; si no queda nada sin usar, se rechazan más eventos crudos. Los hechos nunca se eliminan para cumplir el número. Compactar (--vacuum) sigue siendo un paso humano — copia todo el archivo para que el sistema operativo vea el tamaño más pequeño.
Si la mayor parte de ese volumen es salida de herramientas que consideras ruido, extraction.event_types y extraction.roles restringen lo que se examina, y extraction.min_content_length omite eventos triviales. Mide antes de hacerlo. Volumen y valor no son el mismo eje.
La regla es alcanzabilidad, no edad. Un evento se elimina solo cuando se cumplen las tres condiciones:
- La extracción ya lo ha leído. Cualquier cosa antes de la marca de agua de consolidación sigue siendo entrada.
- Ningún hecho cita su procedencia.
- Ha caído fuera de los eventos
extraction.working_memory_sizemás recientes de su propia sesión — un margen para que la consolidación aún pueda mirar notas crudas recientes. Esa ventana es evidencia del tema actual, no un diccionario de pronombres.
Ningún hecho, entidad, incrustación o resultado de búsqueda se ve afectado. Eliminar filas no encoge el archivo por sí solo — eso es --vacuum. Sin un límite, nada se poda automáticamente.
Desarrollo
git clone https://github.com/gordonkjlee/facthouse
cd facthouse
npm install
npm run build
npm test
npm test siempre ejecuta pipelines herméticos (JSONL de fixture → copia → extracción →
búsqueda) con un extractor de grabación, y omite evaluaciones en vivo que necesitan un modelo
real:
- La recuperación semántica necesita Ollama con
nomic-embed-text. Inícialo, luegonpm run test:semantic. - La evaluación en vivo del primer hecho necesita la CLI
claude. Ejecutanpm run test:first-fact. - La evaluación en vivo del almacén de codificación (transcripciones de Cursor con forma de almacén) también
necesita la CLI
claude. Ejecutanpm run test:coding-store. - La extracción HTTP local necesita un modelo de chat en un host compatible con OpenAI y
FACTHOUSE_HTTP_MODEL(verificado enqwen2.5vl:7b). Ejecutanpm run test:http-intelligence.
Cada uno de esos scripts falla en lugar de omitir cuando falta su dependencia, así que una ejecución verde significa que la afirmación se verificó realmente en lugar de pasarse por alto silenciosamente.
Contribuir
Las issues y pull requests son bienvenidas. Abre una issue primero si el cambio es más que un error tipográfico.
- Preguntas: GitHub Discussions
- Cómo construir y probar: CONTRIBUTING.md
Licencia
MIT