1. Introducción
Qué es NyxKV
NyxKV es un almacén key-value compatible con Redis, construido enteramente en Nyx. El daemon compila a un único binario nativo de ~290KB sin dependencias de runtime externas, y soporta 52 comandos en strings, listas, sets, hashes y Pub/Sub.
Arquitectura
- Protocolo: RESP (Redis Serialization Protocol) — funciona con cualquier cliente Redis
- Endpoint público:
nyxkv.com:6380, solo TLS - Almacenamiento: en memoria con persistencia binaria (snapshots
.ndb) - Auth: basado en tokens, con aislamiento transparente de namespaces por cuenta
- Persistencia: snapshot en background cada segundo; verificación CRC32 al cargar
Cuándo usar NyxKV
NyxKV es una buena opción cuando querés un store compatible con Redis sin tener que correr y mantener tu propio Redis. Funciona bien para:
- Caches y sesiones
- Mensajería en tiempo real (Pub/Sub)
- Backends SaaS multi-tenant
- Prototipos con el protocolo Redis
- Despliegues edge donde el tamaño del binario y las cero dependencias importan
2. Primeros pasos
El servicio público de NyxKV requiere TLS y un token. Ambos vienen del dashboard.
Requisitos
- Una cuenta en dashboard.nyxkv.com/signup — email y contraseña, sin tarjeta de crédito
- Un token creado en dashboard.nyxkv.com/app/keys
- Cualquier cliente Redis. El camino más corto es
redis-cli
Conectarse
$ export TOKEN=<pegá tu token aquí> $ redis-cli -h nyxkv.com -p 6380 --tls -a $TOKEN PING PONG
Si recibís Connection reset by peer, te olvidaste de --tls. Si recibís NOAUTH, te olvidaste de -a $TOKEN.
Tus primeros comandos
$ redis-cli -h nyxkv.com -p 6380 --tls -a $TOKEN nyxkv.com:6380> SET hola "mundo" OK nyxkv.com:6380> GET hola "mundo"
Entendiendo las respuestas
NyxKV habla RESP. Los tipos de respuesta que vas a ver:
+OK— string simple (éxito)-ERR ...— mensaje de error(integer) N— entero (counts, booleans)"value"— bulk string (datos)(nil)— nulo (key no encontrada)1) ... 2) ...— array (listas, sets)
3. Conectar desde el dashboard
El servicio público de NyxKV es multi-tenant: no hay acceso anónimo. Cada conexión se autentica con un token emitido por el dashboard.
1. Creá una cuenta
Andá a dashboard.nyxkv.com/signup. Pone un email y una contraseña. No hay tarjeta de crédito ni plan que elegir — el tier gratis es el producto.
2. Generá un token
Abrí dashboard.nyxkv.com/app/keys y hacé clic en Crear token. El valor del token se muestra una sola vez; copialo a un password manager o a una variable de entorno. Podés crear todos los tokens que quieras y revocar cualquiera desde la misma página.
3. Conectarte
Pasá el token como password a cualquier cliente Redis, y activá TLS:
$ redis-cli -h nyxkv.com -p 6380 --tls -a $TOKEN nyxkv.com:6380> SET hola "mundo" OK
Errores comunes
- Olvidaste
--tls. El servidor cierra la conexión. Algunos clientes reportanConnection reset by peer. - Olvidaste el token. El primer comando después del connect devuelve
-NOAUTH Authentication required. - Puerto incorrecto. El servicio escucha solo en 6380. No hay puerto en texto plano.
- Token revocado. Revocar un token desde el dashboard surte efecto en el próximo request del cliente afectado. Las conexiones existentes no se cierran proactivamente.
./nyxkv (sin --public ni --tls), todo este libro aplica también — sacá --tls -a $TOKEN de los ejemplos y el prompt pasa a ser 127.0.0.1:6380>.4. Strings
Los strings son el tipo de dato más simple. Toda key empieza como string a menos que uses comandos de lista, set o hash.
SET key value
Guarda un string. Sobreescribe cualquier valor existente y limpia el TTL.
> SET usuario:1 "Alicia" OK
GET key
Devuelve el string. Devuelve (nil) si la key no existe.
> GET usuario:1 "Alicia" > GET inexistente (nil)
SETNX key value
Setea el valor solo si la key no existe. Devuelve 1 si seteó, 0 si no.
> SETNX lock:job42 "worker-1" (integer) 1 > SETNX lock:job42 "worker-2" (integer) 0 # worker-1 tiene el lock
SETEX key seconds value
Setea un valor con TTL (en segundos), atómicamente.
> SETEX session:abc 3600 "user:1" OK # Expira en 1 hora
GETSET key value
Setea un valor nuevo y devuelve el viejo, atómicamente.
> SET counter 10 OK > GETSET counter 0 "10" # Devolvió el viejo, ahora counter es 0
INCR key
Incrementa un entero en 1. Crea la key con valor 0 si no existe.
> SET visitas 0 OK > INCR visitas (integer) 1 > INCR visitas (integer) 2
DECR key
Decrementa un entero en 1. Crea la key con valor 0 si no existe.
> SET stock 50 OK > DECR stock (integer) 49
APPEND key value
Concatena el valor al final del string. Crea la key si no existe. Devuelve el largo nuevo.
> SET saludo "Hola" OK > APPEND saludo " Mundo" (integer) 10 > GET saludo "Hola Mundo"
STRLEN key
Devuelve el largo del string en bytes. Devuelve 0 si la key no existe.
> STRLEN saludo (integer) 10
MSET key value [key value ...]
Setea múltiples pares key-value en un solo comando.
> MSET nombre "Alicia" edad "30" ciudad "BA" OK
MGET key [key ...]
Obtiene múltiples valores en un solo comando. Devuelve (nil) para keys faltantes.
> MGET nombre edad ciudad falta 1) "Alicia" 2) "30" 3) "BA" 4) (nil)
Patrón: contador atómico
# Contador de page views — sin race conditions > INCR page:/docs/intro (integer) 1 > INCR page:/docs/intro (integer) 2 > GET page:/docs/intro "2"
5. Listas
Las listas son secuencias ordenadas de strings. Soportan push/pop desde ambos extremos, ideal para colas y stacks.
LPUSH key value [value ...]
Pushea uno o más valores a la cabeza (izquierda). Crea la lista si no existe.
> LPUSH tareas "Deploy v2" (integer) 1 > LPUSH tareas "Corregir bug #42" (integer) 2
RPUSH key value [value ...]
Pushea uno o más valores a la cola (derecha).
> RPUSH logs "2024-01-01 started" (integer) 1 > RPUSH logs "2024-01-01 completed" (integer) 2
LPOP key
Quita y devuelve el primer elemento (cabeza).
> LPOP tareas "Corregir bug #42"
RPOP key
Quita y devuelve el último elemento (cola).
> RPOP tareas "Deploy v2"
LLEN key
Devuelve el número de elementos.
> LPUSH items "a" "b" "c" (integer) 3 > LLEN items (integer) 3
LRANGE key start stop
Devuelve elementos de start a stop (inclusive). Soporta índices negativos: -1 es el último.
> RPUSH colores "rojo" "verde" "azul" "amarillo" (integer) 4 > LRANGE colores 0 -1 1) "rojo" 2) "verde" 3) "azul" 4) "amarillo" > LRANGE colores 1 2 1) "verde" 2) "azul"
LINDEX key index
Devuelve el elemento en el índice indicado. Soporta negativos.
> LINDEX colores 0 "rojo" > LINDEX colores -1 "amarillo"
Patrón: cola de jobs
# Producer: pushea jobs a la izquierda > LPUSH jobs '{"type":"email","to":"alicia@ejemplo.com"}' (integer) 1 # Consumer: popea desde la derecha (FIFO) > RPOP jobs "{\"type\":\"email\",\"to\":\"alicia@ejemplo.com\"}"
6. Sets
Los sets son colecciones desordenadas de strings únicos. Los duplicados se ignoran automáticamente.
SADD key member [member ...]
Agrega uno o más miembros. Devuelve la cantidad de miembros nuevos (ignora duplicados).
> SADD tags "nyx" "rápido" "ligero" (integer) 3 > SADD tags "nyx" (integer) 0 # "nyx" ya estaba en el set
SREM key member [member ...]
Quita uno o más miembros. Devuelve la cantidad eliminada.
> SREM tags "ligero" (integer) 1
SISMEMBER key member
Verifica si un miembro existe. Devuelve 1 o 0.
> SISMEMBER tags "nyx" (integer) 1 > SISMEMBER tags "lento" (integer) 0
SMEMBERS key
Devuelve todos los miembros del set.
> SMEMBERS tags 1) "nyx" 2) "rápido"
SCARD key
Devuelve la cardinalidad del set.
> SCARD tags (integer) 2
Patrón: visitantes únicos
# Trackea visitantes únicos por página > SADD visitantes:/home "user:1" "user:2" "user:1" (integer) 2 > SCARD visitantes:/home (integer) 2 # user:1 contado solo una vez
7. Hashes
Los hashes guardan pares campo-valor bajo una sola key. Pensalos como objetos o diccionarios.
HSET key field value [field value ...]
Setea uno o más pares campo-valor. Devuelve la cantidad de campos nuevos.
> HSET usuario:1 nombre "Alicia" email "alicia@ejemplo.com" edad "30" (integer) 3
HGET key field
Obtiene el valor de un campo.
> HGET usuario:1 nombre "Alicia" > HGET usuario:1 telefono (nil)
HDEL key field [field ...]
Borra uno o más campos. Devuelve la cantidad eliminada.
> HDEL usuario:1 edad (integer) 1
HGETALL key
Devuelve todos los campos y valores como array intercalado.
> HGETALL usuario:1 1) "nombre" 2) "Alicia" 3) "email" 4) "alicia@ejemplo.com"
HKEYS key
Devuelve los nombres de campo.
> HKEYS usuario:1 1) "nombre" 2) "email"
HVALS key
Devuelve los valores.
> HVALS usuario:1 1) "Alicia" 2) "alicia@ejemplo.com"
HEXISTS key field
Verifica si un campo existe. Devuelve 1 o 0.
> HEXISTS usuario:1 email (integer) 1
HLEN key
Devuelve la cantidad de campos.
> HLEN usuario:1 (integer) 2
Patrón: perfil de usuario
# Guardá datos estructurados como hash > HSET producto:42 nombre "Widget" precio "19.99" stock "150" (integer) 3 # Leé un solo campo > HGET producto:42 precio "19.99" # Actualizá un campo sin tocar los otros > HSET producto:42 stock "149" (integer) 0
8. Gestión de keys
DEL key [key ...]
Borra una o más keys de cualquier tipo. Devuelve la cantidad borrada.
> SET temp "data" OK > DEL temp (integer) 1 > DEL temp (integer) 0
EXISTS key
Verifica si una key existe (cualquier tipo). Devuelve 1 o 0.
> EXISTS usuario:1 (integer) 1 > EXISTS inexistente (integer) 0
TYPE key
Devuelve el tipo del valor: string, list, set, hash o none.
> SET nombre "Alicia" OK > LPUSH items "a" (integer) 1 > TYPE nombre string > TYPE items list
KEYS pattern
Lista keys que matchean el pattern. Usá * para todas.
> KEYS * 1) "usuario:1" 2) "nombre" 3) "items" > KEYS usuario:* 1) "usuario:1"
DBSIZE
Devuelve la cantidad de keys en tu namespace.
> DBSIZE (integer) 3
9. Expiración y TTL
Cualquier key puede tener un TTL. Cuando expira, se borra automáticamente al próximo acceso (lazy deletion).
EXPIRE key seconds
Setea un timeout en una key. Después de seconds segundos, la key se borra. Devuelve 1 si se seteó, 0 si la key no existe.
> SET session "active" OK > EXPIRE session 3600 (integer) 1 # La sesión expira en 1 hora
TTL key
Devuelve el tiempo restante en segundos.
-2— la key no existe-1— la key existe sin expiraciónN— segundos restantes
> TTL session (integer) 3598 > TTL usuario:1 (integer) -1 > TTL inexistente (integer) -2
PERSIST key
Quita la expiración de una key. Devuelve 1 si había TTL, 0 si no.
> PERSIST session (integer) 1 > TTL session (integer) -1
Patrón: sesión con auto-expiración
# Sesión que expira en 30 minutos > SETEX sess:abc123 1800 '{"user":"alicia","role":"admin"}' OK # Chequear tiempo restante > TTL sess:abc123 (integer) 1798 # Extender en cada actividad > EXPIRE sess:abc123 1800 (integer) 1
10. Pub/Sub
Pub/Sub habilita mensajería en tiempo real entre clientes. Los publishers mandan mensajes a canales; todos los subscribers de ese canal los reciben al toque.
SUBSCRIBE channel
Se suscribe a un canal. La conexión entra en modo subscriber y bloquea, recibiendo mensajes a medida que llegan.
# Terminal 1: subscriber > SUBSCRIBE notificaciones 1) "subscribe" 2) "notificaciones" 3) (integer) 1 # Esperando mensajes...
PUBLISH channel message
Manda un mensaje a todos los subscribers del canal. Devuelve cuántos lo recibieron.
# Terminal 2: publisher > PUBLISH notificaciones "Nuevo pedido #1234" (integer) 1
El subscriber en la Terminal 1 recibe:
1) "message"
2) "notificaciones"
3) "Nuevo pedido #1234"UNSUBSCRIBE channel
Se desuscribe de un canal y sale del modo subscriber.
./nyxkv durante el desarrollo — el endpoint público con TLS acepta todos los demás comandos.Patrón: notificaciones en tiempo real
# Sala de chat > SUBSCRIBE chat:general # Otro cliente: > PUBLISH chat:general "alicia: ¡Hola a todos!" # Todos los subscribers reciben el mensaje
11. Persistencia
NyxKV escribe los datos a disco como snapshots binarios en un archivo .ndb con checksum CRC32.
Cómo funciona
- Snapshot en background: un thread dedicado escribe el snapshot a
dump.ndbuna vez por segundo. Los requests del cliente no se bloquean por la persistencia. - Recuperación: al arrancar, si
dump.ndbexiste, el daemon valida el CRC32 y carga todo. Si el checksum falla, rehúsa cargar (en lugar de arrancar vacío silenciosamente). - Ventana de pérdida: un kill brusco (
SIGKILL, corte de luz) puede perder hasta un segundo de writes. Un restart graceful no pierde nada en steady state.
SIGTERM que antes flusheaba al cerrar está intencionalmente desactivado en el build actual — corría en un contexto async-signal-unsafe y corrompía snapshots. El bg-saver cubre los reinicios normales; el peor caso (kill -9) pierde ≤1 s.SAVE
Dispara un snapshot sincrónico a dump.ndb. Bloquea hasta terminar.
> SAVE OK
BGSAVE
Dispara un snapshot en background. Devuelve al toque.
> BGSAVE Background saving started
LASTSAVE
Devuelve el timestamp Unix del último save exitoso.
> LASTSAVE (integer) 1711987200
Formato .ndb
Snapshot binario con header, entries y checksum CRC32:
- Header: magic
NYXDB+ byte de versión - Metadata: timestamp + cantidad de keys
- Entries: tipo (string / list / set / hash / token) + TTL + key + value
- Footer: checksum CRC32 + marker EOF
Si el CRC32 no matchea al cargar, NyxKV reporta corrupción y rehúsa arrancar, en vez de perder datos silenciosamente.
12. Autenticación y multi-tenant
El servicio público de NyxKV es multi-tenant. Cada cuenta autenticada tiene su propio namespace, y los tokens se emiten y revocan desde el dashboard, no desde el protocolo.
Conectarse con un token
AUTH token
Autentica la conexión. Todos los comandos posteriores operan en el namespace de tu cuenta. La mayoría de los clientes lo llaman por vos cuando pasás un password.
> AUTH a1b2c3d4e5f6... OK > SET mikey "midata" OK # Internamente guardado como: alicia::mikey
WHOAMI
Devuelve el estado actual de autenticación.
> WHOAMI "alicia:free"
Cómo funciona el aislamiento de namespaces
Cuando estás autenticado, todas las keys se prefijean transparentemente con el id de tu cuenta. Esto significa:
- La cuenta “alicia” ejecuta
SET mikey "data"→ guardado comoalicia::mikey - La cuenta “bob” ejecuta
SET mikey "otro"→ guardado comobob::mikey - Ninguna de las dos puede ver ni acceder las keys de la otra
- KEYS / DBSIZE / TYPE / EXISTS scopean a tu namespace, sin el prefijo
Los tokens se manejan desde el dashboard
Para crear, listar o revocar tokens, entrá a dashboard.nyxkv.com/app/keys:
- Crear token — el valor se muestra una sola vez. Guardalo. Podés crear todos los que quieras.
- Revocar token — surte efecto en el próximo request del cliente afectado. Las conexiones existentes no se cierran proactivamente.
- Listar tokens — ves el id, fecha de creación y última actividad. Los valores nunca se muestran de nuevo.
No hay comandos TOKEN_CREATE/TOKEN_REVOKE/TOKEN_LIST en el servicio público. Esos existen en el daemon pero están restringidos a conexiones de admin, así que el dashboard es la única fuente de verdad sobre quién tiene acceso.
Patrón: tokens por entorno
Emití tokens separados para staging y producción. Si un token se filtra, revocá solo ese sin afectar el otro entorno:
- Token etiquetado
app-staging— usado por el deploy de staging - Token etiquetado
app-production— usado por el deploy de producción - Token etiquetado
local-dev— usado por tu laptop
13. Librerías cliente
NyxKV habla RESP, así que cualquier librería cliente de Redis funciona. El servicio público requiere TLS y un token — los snippets de abajo muestran el connect mínimo viable en lenguajes populares.
Python (redis-py)
import os, redis r = redis.Redis( host="nyxkv.com", port=6380, ssl=True, password=os.environ["NYXKV_TOKEN"], ) r.set("key", "value") val = r.get("key") # b"value" r.incr("counter") r.lpush("queue", "job1") r.hset("user:1", mapping={"name": "Alicia", "age": "30"})
Node.js (ioredis)
import Redis from "ioredis"; const r = new Redis({ host: "nyxkv.com", port: 6380, tls: {}, // activa TLS password: process.env.NYXKV_TOKEN, }); await r.set("key", "value"); const val = await r.get("key"); // "value" await r.lpush("queue", "job1"); await r.hset("user:1", "name", "Alicia");
Go (go-redis)
import ( "crypto/tls" "os" "github.com/redis/go-redis/v9" ) rdb := redis.NewClient(&redis.Options{ Addr: "nyxkv.com:6380", Password: os.Getenv("NYXKV_TOKEN"), TLSConfig: &tls.Config{}, }) rdb.Set(ctx, "key", "value", 0) val, _ := rdb.Get(ctx, "key").Result() rdb.LPush(ctx, "queue", "job1") rdb.HSet(ctx, "user:1", "name", "Alicia")
Rust (redis-rs)
let token = std::env::var("NYXKV_TOKEN")?; let url = format!("rediss://:{}@nyxkv.com:6380", token); let client = redis::Client::open(url)?; let mut con = client.get_connection()?; redis::cmd("SET").arg("key").arg("value").execute(&mut con); let val: String = redis::cmd("GET").arg("key").query(&mut con)?;
./nyxkv en tu laptop sin --public ni --tls, sacá la config de TLS y el password de estos snippets, y apuntá a localhost:6380.14. Patrones y recetas
Session store
Usá SETEX para guardar sesiones con expiración automática.
# Crear sesión (TTL de 30 min) > SETEX sess:abc123 1800 '{"user":"alicia","role":"admin"}' OK # Leer sesión > GET sess:abc123 "{\"user\":\"alicia\",\"role\":\"admin\"}" # Extender en cada actividad > EXPIRE sess:abc123 1800 (integer) 1 # Logout > DEL sess:abc123 (integer) 1
Rate limiter
Usá INCR con EXPIRE para implementar un rate limiter por key.
# Trackear requests por usuario por minuto > INCR rate:user:42 (integer) 1 > EXPIRE rate:user:42 60 (integer) 1 # En cada request: INCR, chequear si supera el umbral, rechazar > GET rate:user:42 "47"
Cache con TTL
Cacheá cómputos caros con invalidación automática.
# Cachear respuesta de API por 5 minutos > SETEX cache:api:/users 300 '[{"id":1,"name":"Alicia"}]' OK # Chequear cache antes de llamar a la API > GET cache:api:/users "[{\"id\":1,\"name\":\"Alicia\"}]" # Cache miss → llamar API → SETEX de nuevo
Cola de jobs (FIFO)
Usá LPUSH + RPOP para una cola first-in-first-out.
# Encolar jobs > LPUSH jobs '{"task":"send_email","to":"alicia@ejemplo.com"}' (integer) 1 > LPUSH jobs '{"task":"resize_image","id":42}' (integer) 2 # Desencolar (más viejo primero) > RPOP jobs "{\"task\":\"send_email\",\"to\":\"alicia@ejemplo.com\"}" # Largo de la cola > LLEN jobs (integer) 1
Configuración
Usá hashes para guardar configuración con updates por campo.
> HSET config:app max_retries "3" timeout "30" debug "false" (integer) 3 # Actualizar un setting sin tocar los otros > HSET config:app debug "true" (integer) 0 # Leer toda la config > HGETALL config:app 1) "max_retries" 2) "3" 3) "timeout" 4) "30" 5) "debug" 6) "true"
Leaderboard
Usá INCR para tracking simple de scores.
> INCR score:alicia (integer) 1 > INCR score:alicia (integer) 2 > INCR score:bob (integer) 1 > MGET score:alicia score:bob 1) "2" 2) "1"
Feature flags
Usá sets para gestionar feature flags por grupo de usuarios.
> SADD feature:dark-mode "user:1" "user:3" "user:7" (integer) 3 # Chequear si el usuario tiene la feature > SISMEMBER feature:dark-mode "user:3" (integer) 1 > SISMEMBER feature:dark-mode "user:5" (integer) 0
15. Límites
Hay un solo tier en NyxKV: free. No hay plan Pro. No hay plan Enterprise. El tier gratis es el producto.
Lo que recibís
| Límite | Valor |
|---|---|
| Requests por segundo | 1000 |
| Keys máximas | 10.000 |
| Tamaño máximo de valor | 1 MB |
| TTL en cada key | 24 horas |
| TLS | obligatorio |
| Aislamiento multi-tenant | incluido |
| Pub/Sub | incluido (sobre TCP plano, ver capítulo 10) |
Detalle del tier gratis
- Rate limit: 1000 requests por segundo por cuenta, ventana deslizante de 1 segundo.
- Límite de keys: 10.000 keys por cuenta. Cuando se alcanza, los siguientes SET / LPUSH / SADD / HSET devuelven error hasta que borres o expiren keys.
- Tamaño de valor: 1 MB por valor (1.048.576 bytes). Los writes más grandes se rechazan.
- Cap de TTL: toda key tiene un TTL de 24 horas (86.400 segundos). Los EXPIRE mayores se truncan al cap.
- KEYS: devuelve hasta 100 keys, scopeadas a tu namespace.
- Comandos deshabilitados en el servicio público: FLUSHDB, FLUSHALL, CONFIG, SAVE, BGSAVE.
Cómo funciona el rate limiting
Por cuenta, ventana deslizante: cada conexión cuenta contra el budget de tu cuenta. Cuando se supera el límite, el servidor responde:
-ERR rate limit exceededPrecio
$0. Para siempre. Sin tarjeta de crédito. Sin prompts de upgrade. Si te queda chico el tier gratis, te quedó chico el servicio — corré el daemon open source en tu propio host.
Comandos de servidor
PING [message]
Devuelve PONG, o hace eco del mensaje. Útil para health checks y mediciones de latencia.
INFO
Devuelve estadísticas del servidor en formato Redis INFO: versión, total de comandos procesados, info del keyspace.
CONFIG GET save
Stub para compatibilidad con redis-benchmark. Deshabilitado en el servicio público.
FLUSHDB / FLUSHALL
Solo admin en el daemon. No están disponibles en el servicio público.
16. Memoria de agente (beta)
Qué es
Agent Memory es memoria privada y persistente para agentes AI y las apps que se construyen alrededor de ellos — sobre NyxKV mismo, no un servicio aparte. Resuelve dos cosas que un agente de código no te da solo: memoria que sobrevive al cierre de una sesión, y memoria que te sigue entre máquinas.
Por debajo es simplemente claves. Las entradas viven en mem:<colección>:<clave> dentro de tu namespace normal de token, aisladas exactamente igual que cualquier otra clave (ver capítulo 12). No hay cuenta separada, ni token separado, ni protocolo separado — cualquier cosa que hable RESP puede leer y escribir memoria de agente.
Primeros pasos
Cuatro pasos: token, SDK, un round-trip, y el plugin de Claude Code.
1. Token
El mismo token que usás en el resto de NyxKV. Creá uno en dashboard.nyxkv.com/app/keys y guardalo donde el SDK lo busca por defecto:
$ umask 077 && printf '%s' 'TU_TOKEN' > ~/.nyxkv-token
2. Compilar el SDK
nyx-kv-sdk es un CLI chico en Nyx que envuelve el modelo de colección/clave de abajo. Cloná nyx-kv y compilalo con el toolchain de Nyx:
$ cd sdk && nyx build $ ./nyx-kv-sdk help
3. Guardar y leer una entrada
$ ./nyx-kv-sdk put notas readme "primera entrada" OK $ ./nyx-kv-sdk get notas readme primera entrada
4. Instalar el plugin de Claude Code
sdk/claude/ es un plugin drop-in con dos skills centrales, memory-pull y memory-push (más friction-share / friction-review opcionales, para dejar notas entre instancias de agente). Copialo a donde Claude Code carga tus plugins y después simplemente pedíselo en lenguaje natural: “restaurá mi memoria” al empezar una sesión, “guardá mi memoria” antes de cerrarla. Las dos llaman al SDK por debajo.
5. Sincronizar entre máquinas
El plugin envuelve exactamente esto — corré el SDK directo si querés sincronizar un directorio de archivos markdown sin un agente en el medio:
# máquina A $ ./nyx-kv-sdk sync-push miproyecto ./notas sync-push: 3 archivo(s) de ./notas → colección miproyecto # máquina B, mismo token $ ./nyx-kv-sdk sync-pull miproyecto ./notas sync-pull: 3 archivo(s) de colección miproyecto → ./notas
El modelo de claves mem:*
Todo vive bajo el prefijo mem:, que lo distingue visualmente de claves de cache o sesión y le permite al dashboard enumerarlo sin escanear todo tu namespace:
mem:<colección>:<clave>— una entrada (un valor string)mem:<colección>:__keys__— un índice Set de las claves de esa colección, usado porlist/sync-pull/el dashboard en vez deKEYS(que en este tier tiene un tope de 100 resultados — ver capítulo 15)mem:__collections__— un índice Set con todos los nombres de colección de tu namespace, para que el dashboard pueda listarlas sin un escaneo completo
Una “colección” es simplemente un namespace dentro del keyspace de tu token — un proyecto, un tema, cualquier agrupación que te sirva. El plugin de Claude Code usa por defecto una colección por proyecto (agentmem-<nombre del directorio del proyecto>), configurable con la variable de entorno NYXKV_MEMORY_COLLECTION.
Los valores de las entradas viajan codificados en base64 con prefijo b64:, para que el markdown multilínea sobreviva intacto a RESP. El SDK y el plugin codifican/decodifican esto de forma transparente — si inspeccionás una entrada directo con redis-cli GET, vas a ver la forma cruda b64:..., no texto plano.
Ver tu memoria
El dashboard tiene un visor integrado en dashboard.nyxkv.com/app/memory. Lista todas las colecciones y claves bajo el namespace mem:* de tu token, te deja abrir una entrada para leer el contenido ya decodificado, y borrar entradas individuales. Reusa tu sesión del dashboard — no hay un login separado para memoria.
Límites (beta)
Agent Memory es beta. Las restricciones honestas, para que no haya sorpresas:
- Todavía sin cuota dedicada. Las entradas
mem:*cuentan contra los mismos topes del free tier que cualquier otra clave: 10.000 claves y 1 MB por valor, por cuenta (capítulo 15). - Sin TTL forzado. Las claves
mem:*están exentas del TTL estándar de 24h del servicio público — la memoria de agente no expira sola. Sigue contando contra la cuota de claves/bytes de tu cuenta (ítem anterior), y unEXPIREexplícito que vos mismo configurés se sigue respetando. - Una colección por proyecto por defecto. El plugin no reparte automáticamente la memoria de un proyecto en varias colecciones; configurá
NYXKV_MEMORY_COLLECTIONsi querés dividirla vos mismo. - Sin búsqueda semántica. Esto es un key-value store, no una base de datos vectorial. Agent Memory te da almacenamiento y lectura durables por clave exacta, no búsqueda por similitud sobre el contenido.
- Host público compartido. TLS en tránsito y aislamiento por token, pero sin cifrado del lado cliente. No subas secretos a la memoria de agente — las exclusiones por defecto del plugin (
user_*.md,*secret*,*private*,*.local.md) son una red de seguridad, no una garantía. Revisalas para tu propio setup.