Memgate

Control de acceso, resolución de conflictos y auditoría para la memoria compartida de agentes.

Documentación

Memgate

Control de acceso, resolución de conflictos y auditoría para la memoria compartida de agentes.

Memgate se sitúa frente a la memoria que comparten tus agentes de IA. Decide quién puede leer y escribir qué, resuelve escrituras conflictivas y registra cada operación — para que la memoria de un sistema multiagente se mantenga confiable a medida que crece.

Habla MCP, por lo que los agentes se conectan con una entrada de configuración y sin cambios de código.

Estado: temprano pero funcional. El núcleo (política, manejo de conflictos, auditoría, herramientas MCP) se ejecuta y se prueba de extremo a extremo con agentes reales. Los adaptadores para backends de memoria externos y un panel alojado están en la hoja de ruta, aún no construidos. Comentarios y problemas son bienvenidos.


Demostración

asciicast

El problema

La memoria de un solo agente es fácil: mantener la conversación en contexto, listo. Pero cuando varios agentes comparten un mismo pool de memoria — uno manejando soporte, uno escribiendo código, uno haciendo facturación — ese pool se degrada:

  • Escrituras conflictivas. Un agente registra "el cliente está contento", otro registra "el cliente está enojado". Nadie sabe cuál es la actual.
  • Sin límites de acceso. El agente de facturación puede leer datos personales del cliente; el agente de soporte puede sobrescribir registros financieros. Nada lo impide.
  • Sin responsabilidad. Cuando algo sale mal, no hay registro de qué agente escribió qué, ni cuándo.

Los almacenes de memoria como pgvector, Mem0 o Zep contienen memoria bien. No la gobiernan. Memgate es la capa de gobierno que se sitúa encima.

La idea

Piensa en la memoria compartida como un libro de contabilidad, y en Memgate como el guardián que se sitúa frente a él. Los agentes nunca tocan el libro directamente — cada solicitud pasa por la puerta, que hace tres cosas:

  1. Política — verifica si el rol de este agente puede leer o escribir en este espacio de nombres. Por defecto, se deniega.
  2. Resolución de conflictos — cuando ya existe un registro para una entidad, aplica la estrategia del espacio de nombres (last-write-wins, versioned o require-review) en lugar de sobrescribirlo silenciosamente.
  3. Auditoría — añade cada operación, permitida o denegada, a un registro de solo apéndice.

La identidad está vinculada a la clave API, no a nada que el agente diga. Un agente no puede elevar sus propios privilegios afirmando un rol diferente.

Cómo funciona

Agent A ─┐
Agent B ─┼── MCP ──▶ [ Memgate ] ──▶ Postgres + pgvector
Agent C ─┘             policy · conflict · audit

Los agentes llaman a tres herramientas a través de MCP:

HerramientaQué hace
memory_write(namespace, entity_key, content)Verificación de política → resolución de conflictos → escritura → auditoría
memory_read(namespace, entity_key)Verificación de política → devolver el registro activo → auditoría
memory_search(namespace, query)Verificación de política → búsqueda semántica en espacios de nombres autorizados → auditoría

Inicio rápido

Requiere Docker.

git clone https://github.com/denizayhan04/memgate
cd memgate
docker compose up --build

Esto inicia Postgres (con pgvector), ejecuta migraciones y sirve el endpoint MCP en :8088.

Crea un agente y obtén su clave API:

docker compose exec memgate memgate agent create --name support-bot --role support
# → API key (shown once): mg_live_...

Conecta un cliente MCP (Claude Code, Cursor o cualquier cosa que hable MCP). Añade a .mcp.json de tu proyecto:

{
  "mcpServers": {
    "memgate": {
      "type": "http",
      "url": "http://localhost:8088/mcp",
      "headers": { "Authorization": "Bearer mg_live_YOUR_KEY" }
    }
  }
}

Ahora el agente tiene herramientas memory_write, memory_read y memory_search, limitadas a lo que su rol permita.

Inspecciona lo que sucedió:

docker compose exec memgate memgate audit --entity "customer:acme"
ID  AT                    AGENT         ACTION  NAMESPACE      ENTITY_KEY     RESULT
14  2026-07-08T15:43:30Z  test-eng      write   customer-data  customer:acme  denied
13  2026-07-08T15:43:14Z  test-eng      read    customer-data  customer:acme  allowed
12  2026-07-08T15:41:05Z  test-support  read    customer-data  customer:acme  allowed
11  2026-07-08T15:41:02Z  test-support  write   customer-data  customer:acme  allowed

Dos agentes, un registro compartido, permisos diferentes — el agente de soporte escribe y lee; el ingeniero lee pero no puede escribir. Cada intento, permitido o denegado, queda registrado.


Políticas

Las políticas viven en un archivo YAML (config/policies.example.yaml por defecto), no en la base de datos — de modo que se versionan en git y se revisan como cualquier otra configuración. La regla es denegación por defecto: cualquier cosa no otorgada explícitamente está cerrada.

namespaces:
  customer-data:
    conflict_strategy: versioned        # old record superseded, new active; history queryable
  tech-context:
    conflict_strategy: last-write-wins  # new record overwrites old
  billing:
    conflict_strategy: require-review   # write parked as pending until a human approves

roles:
  support:
    customer-data: [read, write]
    tech-context:  [read]
  engineer:
    tech-context:  [read, write]
    customer-data: [read]
  finance-bot:
    billing:       [read, write]
    customer-data: [read]
  auditor:
    "*":           [read]

El servidor en ejecución recarga el archivo de políticas sin reiniciar, en SIGHUP o mediante memgate reload.

Estrategias de conflicto

Cuando una escritura apunta a una entidad que ya tiene un registro activo:

  • last-write-wins — el nuevo registro se convierte en activo, el anterior se marca como superado.
  • versioned — lo mismo, pero el historial se conserva y se puede consultar (qué sabíamos y cuándo).
  • require-review — la nueva escritura se aparca como pending_review; el registro existente permanece activo hasta que un humano lo apruebe.

Revisión de escrituras aparcadas:

memgate review list              # list memories awaiting review
memgate review approve <id>      # make a pending memory active
memgate review reject <id>       # reject it

CLI

memgate serve                            Start the MCP (Streamable HTTP) server
memgate migrate                          Apply SQL migrations
memgate agent create --name N --role R   Create an agent and print its API key
memgate review list                      List memories awaiting review
memgate review approve <id>              Approve a pending memory
memgate review reject <id>               Reject a pending memory
memgate reload                           Reload the policy YAML in a running server
memgate audit [--entity K] [--namespace N] [--agent A] [--limit N]
                                         Show audit log, most recent first

Entorno

VariablePropósito
MEMGATE_DATABASE_URLDSN de Postgres (obligatorio)
MEMGATE_POLICY_FILERuta del YAML de políticas (por defecto config/policies.example.yaml)
MEMGATE_LISTEN_ADDRDirección de escucha para serve (por defecto :8080)
MEMGATE_MIGRATIONS_DIRDirectorio de migraciones (por defecto migrations)
MEMGATE_PID_FILEArchivo PID escrito por serve, leído por reload
MEMGATE_OPENAI_API_KEYOpcional. Se establece para embeddings reales; si no se establece, se recurre a un embedder determinista sin conexión, por lo que la búsqueda funciona sin clave.

Desarrollo local

make build      # compile to bin/memgate
make test       # run tests
make migrate    # apply migrations (needs MEMGATE_DATABASE_URL)
make run        # run the MCP server locally
make up         # docker compose up --build
make down       # stop and remove services

Ejecutar desde el código fuente sin Docker:

export MEMGATE_DATABASE_URL="postgres://memgate:memgate@localhost:5432/memgate?sslmode=disable"
go run ./cmd/memgate agent create --name support-bot --role support

Notas de diseño

  • Agóstico respecto al backend por diseño. El almacén de memoria está detrás de una interfaz. Hoy la única implementación es Postgres + pgvector; se pueden añadir adaptadores para almacenes externos (Mem0, Zep) sin tocar las capas de política, conflicto o auditoría.
  • La identidad es la clave, no la afirmación. El rol de un agente se resuelve desde su clave API en cada solicitud. Lo que el agente dice sobre su rol es irrelevante: no hay forma de autoescalar.
  • La auditoría es de solo apéndice. El registro de auditoría rechaza actualizaciones y eliminaciones a nivel de base de datos, no solo en el código de la aplicación.

Hoja de ruta

  • Adaptadores de backend (Mem0, Zep)
  • Endpoints REST junto a MCP, para clientes que no hablan MCP
  • Un panel de auditoría de solo lectura
  • Gestión de políticas para equipos y SSO (alojado)

Tecnología

Go · Postgres + pgvector · mark3labs/mcp-go · Transporte MCP Streamable HTTP.

Licencia

Apache 2.0. Consulte LICENSE.