Skip to main content
Glama
thammarongg

blueocean-vector

by thammarongg

BlueOcean Vector

Memoria compartida y persistente para agentes de codificación.

Licencia Python MCP Docker Compose Estado

El tipo de memoria que sobrevive al cambiar de Claude Code a Codex a Cursor en medio de un proyecto — y sobrevive a que te quedes sin tokens en uno de ellos.

Si alguna vez has consumido una ventana de contexto, abierto una herramienta diferente y luego dedicado diez minutos a reexplicar lo que estabas haciendo, esto es para ese problema. BlueOcean Vector ejecuta un pequeño servidor en tu máquina. Cualquier agente compatible con MCP puede leer de él y escribir en él. La herramienta que abras a continuación simplemente pregunta "¿qué sabemos de este proyecto?" y continúa desde donde la anterior lo dejó.

[!TIP] Guarda una decisión en Claude Code → abre Codex mañana → ya sabe por qué elegiste Postgres sobre DynamoDB, no solo que lo hiciste.


Contenido


Related MCP server: AIVectorMemory

Por qué existe

Cada sesión de agente comienza desde cero. Explicas el proyecto, las restricciones, el "ya lo intentamos, no funcionó" — y luego la sesión termina y todo desaparece. Multiplica eso por cada herramienta que uses, y estás gastando tokens reales solo para restablecer un contexto que ya existía hace una hora.

BlueOcean Vector es una solución pequeña y aburrida: un almacén de memoria compartido, una URL y un conjunto común de herramientas (memory_store, memory_search, memory_summarize_session y algunas más) que cualquier cliente MCP puede llamar. No intenta ser inteligente sobre qué recordar — solo les da a los agentes un lugar para dejar cosas y recuperarlas, con alcance por proyecto para que una búsqueda en un código base no saque a la superficie ruido de otro.


Cómo se compara esto

Ya existe un campo bien poblado de proyectos de "memoria para agentes de IA". Vale la pena ser sincero sobre dónde se sitúa este realmente, en lugar de fingir que el espacio está vacío.

Proyecto

Cómo habla un agente con él

Quién decide qué se recuerda

Búsqueda semántica de vectores

mem0

SDK / API alojada

Automático — un LLM extrae hechos al ingerir

Sí, envuelta detrás de la capa de extracción

Zep / Graphiti

SDK, o un servidor MCP oficial

Automático — entidades/relaciones extraídas en un grafo de conocimiento

Secundario a la travesía del grafo

Letta (anteriormente MemGPT)

Plataforma de agente con estado completo, servidor + SDK

Semiautomático — el propio LLM del agente pagina la memoria de entrada/salida

Sí, para memoria de archivo

Memorix

Nativo MCP, sin servidor que ejecutar

Explícito — el agente llamante escribe

Solo como respaldo (~1.8s), la búsqueda por palabras clave es primaria

threadctx-mcp

Nativo MCP

Explícito + captura pasiva opcional de git

Nivel de nube de pago — el modo local es solo por palabras clave

BlueOcean Vector

Nativo MCP, un servidor compartido

Explícito — el agente llamante escribe

Principal y siempre activo

Dos conclusiones honestas:

  • El nicho "Nativo MCP, funciona con cualquier cliente" no está vacío — Memorix ya vive allí, con más herramientas integradas. Lo que es diferente aquí es que la búsqueda vectorial es la ruta de recuperación principal en lugar de un respaldo o algo detrás de un nivel de pago, el modelo de incrustación predeterminado es genuinamente multilingüe (tailandés+inglés probado), y está construido para ejecutarse como un servidor único, compartido y persistente en lugar de una herramienta por agente sin instalación — autenticación por token de portador, una ruta documentada hacia ECS, sondas de salud listas para Kubernetes y correcciones reales para los problemas de concurrencia que un servidor compartido realmente encuentra.

  • Sin extracción o consolidación automática — a diferencia de mem0, Graphiti, Letta, cognee o LangMem, nada aquí lee tu conversación y decide qué vale la pena recordar. Eso es una compensación de simplicidad deliberada, no una característica faltante: un agente tiene que llamar explícitamente a memory_store. Si quieres un sistema que razone sobre qué conservar en tu nombre, uno de los proyectos anteriores hará eso mejor que este.

La memoria no debería intentar contener un millón de líneas

Algunos proyectos tienen un millón de líneas de código. Y ningún sistema de memoria — BlueOcean Vector incluido — debería intentar almacenarlo todo. Almacenar código es trabajo de una herramienta de búsqueda de código, no de un servidor de memoria.

El trabajo de BlueOcean es más estrecho y más útil: recordar lo que importaba, y dónde encontrarlo. Contiene las decisiones, la arquitectura, el "lo intentamos, no funcionó" — el conocimiento condensado que un agente tendría que redescubrir a partir de un millón de líneas — más el contexto justo suficiente para señalar al agente de vuelta al código real cuando necesite detalles.

El resultado es que la memoria crece con lo que realmente vale la pena recordar, no con el tamaño del código base. Un proyecto de un millón de líneas puede tener unos pocos miles de entradas de memoria. Eso mantiene la recuperación barata sin importar lo grande que se vuelva el proyecto.

Las matemáticas de los tokens

Leer la memoria es donde esa distinción da sus frutos. La alternativa más barata — una habilidad o plugin que vierte notas del proyecto en un archivo .remember que un agente lee — funciona muy bien hasta que el archivo supera la ventana de contexto, entonces silenciosamente deja de ser útil.

BlueOcean limita cada búsqueda a un presupuesto de tokens (por defecto 2000 tokens, configurable mediante BLUEOCEAN_MAX_TOKENS). La búsqueda semántica extrae solo las entradas relevantes, luego divide el presupuesto: ~60% para resúmenes condensados, ~40% para el contenido completo de los mejores resultados. Las entradas que superan el presupuesto se truncan, nunca se vuelcan por completo.

Enfoque

Costo por recuperación

¿Crece con el tamaño de la memoria?

BlueOcean Vector (memory_search)

limitado al presupuesto de tokens (por defecto 2000)

No — acotado, independientemente del tamaño de la colección

Archivo .remember (leer archivo completo)

igual al tamaño total del archivo

Sí — lineal; eventualmente excede la ventana de contexto

Archivo .remember (el agente lee una sección)

igual a esa sección

Parcial — pero el agente debe adivinar qué sección sin clasificación por relevancia

Una búsqueda real contra un pequeño proyecto de demostración devolvió 121 tokens para un resumen + una entrada completa — un pequeño porcentaje del presupuesto de 2000 tokens, y ese presupuesto nunca crece a medida que el proyecto acumula memoria. Con un archivo simple, la misma lectura cuesta el archivo completo cada vez, por lo que un proyecto de 5k entradas (cientos de miles de tokens) es ilegible de una sola vez.


Cómo encaja todo

┌────────────┐ ┌──────┐ ┌────────┐ ┌───────────────┐ ┌──────┐
│Claude Code │ │Cursor│ │ Codex  │ │Gemini/Antigrav│ │ Kiro │  ...any MCP-http tool
└─────┬──────┘ └──┬───┘ └───┬────┘ └───────┬───────┘ └──┬───┘
      └───────────┴─────────┴──────────────┴────────────┘
                            │  http://localhost:8765/mcp
                 ┌───────────────────────────┐
                 │  blueocean-mcp             │   Python MCP server
                 │  (one shared, persistent   │   (docker compose)
                 │  server, not per-agent)    │
                 └─────────────┬─────────────┘
                               │
                 ┌───────────────────────────┐
                 │  Qdrant (vector DB)        │   Docker locally → ECS Fargate in the cloud
                 └───────────────────────────┘

Algunas decisiones de diseño que vale la pena conocer:

Decisión

Por qué

Un servidor, accesible por URL

Cada cliente MCP convencional (y muchas variantes) tiene su propio comando "agregar un servidor remoto". Apúntalos todos a la misma URL y ninguno necesita edición de archivos de configuración personalizada de nuestra parte.

Qdrant debajo, una colección por proyecto

La memoria de proyecto-a nunca se filtra en una búsqueda de proyecto-b.

Multilingüe por defecto

El modelo de incrustación es intfloat/multilingual-e5-large, por lo que las notas del proyecto que mezclan tailandés e inglés (o cualquier otro par que cubra) aún buscan en ambos sin configuración adicional.

Lecturas con presupuesto de tokens

memory_search devuelve primero resúmenes cortos y solo expande las mejores coincidencias en contenido completo hasta alcanzar un presupuesto que tú establezcas — los agentes se mantienen baratos de ejecutar incluso contra un almacén de memoria que ha crecido mucho.

El transporte stdio también funciona si prefieres que cada herramienta genere su propio proceso local en lugar de hablar con el servidor compartido — consulta Alternativa: stdio a continuación. El servidor HTTP compartido sigue siendo la ruta recomendada; stdio inicia una copia separada del modelo de incrustación por agente.


Primeros pasos

# 1. Bring up Qdrant + the MCP server (both run in the background via docker compose)
./scripts/setup_local.sh

# 2. Register the URL with whichever agents you use
./scripts/register_mcp.sh

Eso es todo. setup_local.sh inicia ambos contenedores, espera a que Qdrant realmente responda (no solo "el proceso comenzó"), copia .env.example a .env en la primera ejecución y sincroniza el paquete de Python. register_mcp.sh luego llama al CLI mcp add de cada herramienta (o, para Cursor, edita ~/.cursor/mcp.json directamente, ya que el CLI de Cursor solo funciona mientras la aplicación está abierta) para que apunte a http://localhost:8765/mcp.

Para cualquier otra herramienta compatible con MCP-http, incluidas aquellas de las que nunca hemos oído hablar, simplemente proporciona la misma URL a través de la función "agregar servidor MCP remoto" de esa herramienta:

http://localhost:8765/mcp

Enseñar a los agentes a usarlo realmente

Registrar el servidor hace que las herramientas estén disponibles; no hace que un agente las busque por sí mismo. scripts/install_skill.sh instala una pequeña habilidad — "revisar la memoria al inicio de una sesión, escribir en ella antes de quedarte sin contexto" — en los agentes que uses, para que el hábito esté presente sin que lo repitas en cada indicación:

./scripts/install_skill.sh          # interactive picker
./scripts/install_skill.sh all      # install into every supported tool found
./scripts/install_skill.sh --list   # see what's installed where

Es un SKILL.md canónico, enlazado simbólicamente en el directorio de habilidades de cada herramienta — edítalo una vez, cada herramienta recoge el cambio.

Alternativa: stdio (proceso local por agente)

¿No tienes Docker disponible o prefieres no ejecutar un servidor compartido? Ejecuta:

uv run blueocean-mcp --transport stdio --qdrant-url http://localhost:6333

y apunta la configuración MCP de la herramienta al command (consulta .venv/bin/blueocean-mcp) en lugar de una url.


Las herramientas que obtiene un agente

Tool

What it does

memory_store

Guardar una entrada — contenido, un resumen condensado, una puntuación de importancia y etiquetas de área/módulo

memory_search

Búsqueda semántica con presupuesto de tokens: primero resúmenes baratos, contenido completo para lo que quepa

memory_get

Obtener el contenido completo de una entrada por ID

memory_delete

Eliminar una entrada por ID

memory_list_projects

Listar todos los proyectos que tienen una colección de memoria

memory_manifest

Ver qué áreas/módulos existen antes de buscar, para acotar la consulta de forma sensata

memory_summarize_session

Dejar una nota de traspaso condensada para el agente que lo retome después

memory_stats

Conteos y distribución, principalmente para administración/depuración

Un flujo de trabajo razonable para el agente: llamar a memory_manifest y luego a memory_search al inicio de una sesión para cargar contexto de forma económica; memory_store decisiones reales sobre la marcha (importancia 5 para "por qué elegimos X sobre Y", importancia 3 para estado rutinario); llamar a memory_summarize_session antes de cambiar de herramienta o cuando quede poco presupuesto.


Configuración

Todo está en .env (copia .env.example para empezar). Los valores predeterminados funcionan para uso local en una sola máquina; los parámetros interesantes son:

  • BLUEOCEAN_EMBEDDINGfastembed (predeterminado, local y gratuito), openai o bedrock. Fija también BLUEOCEAN_EMBED_MODEL: los vectores escritos con un modelo no se pueden buscar de forma significativa con otro, por lo que local y nube deben coincidir.

  • BLUEOCEAN_QDRANT_URL — dónde reside Qdrant.

  • BLUEOCEAN_MAX_TOKENS / BLUEOCEAN_TOP_K — el presupuesto de búsqueda predeterminado.

  • BLUEOCEAN_AUTH_TOKEN — no establecido por defecto (válido para uso solo en 127.0.0.1). Consulta Seguridad si expones esto más allá de tu propia máquina.

El transporte (streamable-http vs stdio) es un indicador de CLI, no una variable de entorno — es una elección de "cómo ejecuto esto" que se toma al inicio, no una configuración persistente.


CLI de administración

uv run blueocean-admin stats <project>
uv run blueocean-admin manifest <project>
uv run blueocean-admin list
uv run blueocean-admin export <project>
uv run blueocean-admin prune <project> --older-days 90 --max-importance 2 [--dry-run]
uv run blueocean-admin snapshot <project> [--out ./backups]
uv run blueocean-admin restore <project> <snapshot-file> --yes
uv run blueocean-admin generate-token --write-env

[!WARNING] Si más de una sesión de agente comparte un proyecto, prune no lo sabe. Elimina todo lo que coincida con tus filtros, incluso entradas que otra sesión escribió hace cinco minutos. Ejecuta con --dry-run primero y prefiere filtros estrechos a un reinicio amplio.

export solo vuelca el payload como JSON (with_vectors=False) — restaurar desde él significa re-embedding todo desde cero, no una restauración real en un punto en el tiempo. snapshot/restore usan el mecanismo de snapshot nativo de Qdrant: vectores, payload y estado del índice, capturados atómicamente. snapshot descarga el archivo al disco local y elimina la copia del servidor una vez que se confirma que la descarga está intacta (las copias de seguridad que viven solo dentro del mismo volumen de Qdrant que están respaldando no son copias de seguridad). restore sobrescribe los datos actuales del proyecto, por lo que requiere --yes.

Los nombres de proyecto se validan estrictamente (^[a-z0-9][a-z0-9_-]*$, coincidiendo con la convención de nombres de directorio que este proyecto ya recomienda) en lugar de normalizarse silenciosamente — dos agentes que adivinan ortografías ligeramente diferentes del mismo proyecto ("Team A" vs "team-a") solían fusionarse en una sola colección sin advertencia; ahora el que no coincide se rechaza.


Ejecutar las pruebas

Los archivos de prueba en tests/ son scripts independientes (if __name__ == "__main__":), no archivos descubiertos por pytest — ejecútalos como módulos:

uv run python -m tests.smoke
uv run python -m tests.auth
uv run python -m tests.mcp_e2e
uv run python -m tests.backup   # real snapshot -> delete collection -> restore cycle
uv run python -m tests.health   # /health diagnostics + the cloud-provider self-test TTL cache

tests/auth.py verifica específicamente que las solicitudes no autenticadas y con token incorrecto sean rechazadas (401) y que un token correcto funcione tanto a través del encabezado como de la ruta del parámetro de consulta ?token=.


Seguridad

Sin autenticación por defecto — razonable para uso local solo en 127.0.0.1, no razonable en cuanto esto sea accesible desde cualquier otro lugar.

[!IMPORTANT] Si expones este servidor más allá de localhost (una máquina compartida, la nube), establece BLUEOCEAN_AUTH_TOKEN antes de hacer cualquier otra cosa.

uv run blueocean-admin generate-token --write-env
docker compose up -d --force-recreate blueocean-mcp
./scripts/register_mcp.sh   # reads the token from .env, re-sends it to every tool

No todas las herramientas pueden establecer un encabezado personalizado al registrar un servidor remoto por URL, por lo que el servidor acepta el token de dos maneras y cada cliente usa la que soporta:

  • Authorization: Bearer <token> — Claude Code, Gemini/Antigravity

  • ?token=<token> on the URL — Codex, Kiro, Cursor

El transporte stdio omite esto por completo: es un subproceso generado localmente, ya controlado por los permisos de generación de procesos del SO en lugar de estar en la red.

GET /health está deliberadamente no autenticado y verifica que Qdrant sea realmente accesible, no solo que el proceso esté vivo. Es lo que sondea el healthcheck de docker-compose.yml. También informa el proveedor/modelo de embedding activo, y para openai/bedrock (no fastembed, cuya carga de modelo ya bloquea el inicio del proceso) valida las credenciales mediante una llamada gratuita al plano de control en lugar del endpoint de embedding facturado, almacenando en caché el resultado durante BLUEOCEAN_HEALTH_EMBED_TTL segundos (por defecto 60) para que un intervalo de sonda de 10s no se convierta en una llamada a la API del proveedor en cada golpe:

{"status": "ok", "qdrant": "reachable", "embedding": {"provider": "fastembed", "model": "intfloat/multilingual-e5-large", "ok": true}}

Establece el token mediante BLUEOCEAN_AUTH_TOKEN (variable de entorno / .env), no el indicador de CLI --auth-token — un valor pasado como argumento de CLI es visible para cualquier otro usuario local a través de ps. El registro de acceso a las solicitudes también está desactivado por defecto (access_log=False), ya que tres de los cinco clientes compatibles envían el token como ?token=... y un registro de acceso sin formato lo pondría en texto plano en tus registros en cada solicitud.


Desplegar más allá de localhost

docker compose up -d ejecuta dos servicios de larga duración: qdrant (puerto 6333) y blueocean-mcp (puerto 8765). Para la nube, los mismos dos servicios se trasladan a ECS Fargate (o Qdrant Cloud más un pequeño servicio Fargate/App Runner para blueocean-mcp) — registra la URL pública con cada herramienta exactamente como lo harías localmente. El Dockerfile fija el modelo de embedding para que los vectores producidos en la nube sean compatibles con los producidos en tu portátil.

Kubernetes no lee el healthcheck: de docker-compose.yml — necesita sus propias sondas en la especificación del Pod, pero pueden apuntar a la misma ruta:

readinessProbe:
  httpGet: { path: /health, port: 8765 }
livenessProbe:
  httpGet: { path: /health, port: 8765 }

Algunos detalles que vale la pena conocer antes de tocar esto

  • qdrant-client está fijado a la versión exacta del servidor Qdrant (consulta la etiqueta de imagen en docker-compose.yml). Qdrant versiona su cliente y servidor al unísono, y la API ha cambiado entre versiones — .search() fue eliminado en favor de .query_points() en 1.19. Si actualizas la imagen del servidor, actualiza qdrant-client para que coincida y vuelve a ejecutar el conjunto de pruebas; no saltes varias versiones con datos reales sin un snapshot primero.

  • mcp está fijado >=2.0.0,<3.0.0, más estricto que la mayoría de las dependencias aquí. Su API (mcp.server.mcpserver.MCPServer y similares) ha cambiado significativamente entre versiones, y una restricción flexible corre el riesgo de que una compilación de Docker resuelva silenciosamente algo incompatible — las compilaciones de Docker no usan uv.lock.

  • El proveedor de embedding y el modelo son un par emparejado. Cambia cualquiera de ellos y los vectores antiguos se convierten en basura no buscable frente a los nuevos. Fija el modelo en .env en lugar de confiar en un valor predeterminado de la biblioteca que podría cambiar sin previo aviso.


Licencia

MIT — consulta LICENSE.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    A self-hosted MCP server that provides AI assistants with a shared, persistent SQLite-backed memory for storing and retrieving project context, decisions, and discoveries. It enables cross-session continuity and team-wide knowledge sharing to keep AI coding tools aligned and informed.
    3
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    MCP server that provides cross-session persistent memory for AI coding assistants using local vector database and semantic search, enabling automatic recall of project context, issues, and tasks.
    9
    91
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    Shared memory MCP server for AI coding agents, enabling context sharing across sessions with local SQLite or cloud-based semantic search, compatible with Claude Code and Cursor.
    2
    66
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Persistent memory and cross-session learning for AI coding assistants (hosted remote MCP).

  • Hosted MCP memory: save sessions/decisions once, search from Claude, Cursor, ChatGPT. EU-hosted FTS.

  • Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/thammarongg/blueocean-vector'

If you have feedback or need assistance with the MCP directory API, please join our Discord server