Documentación de mem4dev
mem4dev es la capa de contexto para el desarrollo con IA. Registra las decisiones y la actividad de tus proyectos, las conecta entre sí y con tu código, y las comparte con tu equipo y con tus asistentes de IA (Claude Code, Claude Desktop, Cursor, VS Code o cualquier cliente MCP) mediante un servidor MCP nativo o una API REST.
Contenido:
- Conectar por MCP: agrega el servidor MCP de mem4dev a tu cliente de IA con OAuth.
- Crear una API key: claves de solo lectura o de lectura y escritura, por ámbito.
- Ejemplo con curl: listar ámbitos, registrar una entrada, buscar, editar y relacionar.
- Ámbitos y tags: cómo se organizan, comparten y aíslan las entradas.
- Relaciones y referencias: conectar entradas entre sí y con commits, pull requests e issues.
- Límites públicos y planes.
Esta documentación también está en Markdown crudo (/docs/es/index.md). English version: /docs/.
Conectar por MCP
mem4dev expone un servidor público de Model Context Protocol (MCP) para que un asistente de IA lea el contexto de tus proyectos y, si lo permites, escriba en él.
- URL del servidor:
https://app.mem4dev.com/mcp - Transporte: HTTP streamable (JSON-RPC 2.0)
- Autenticación: OAuth 2.1 con PKCE (S256) y Dynamic Client Registration. Nunca pegas una contraseña ni un token en el cliente.
Agrégalo a tu cliente
Claude Code:
claude mcp add --transport http mem4dev https://app.mem4dev.com/mcp
Cursor (~/.cursor/mcp.json):
{ "mcpServers": { "mem4dev": { "url": "https://app.mem4dev.com/mcp" } } }
VS Code (.vscode/mcp.json):
{ "servers": { "mem4dev": { "type": "http", "url": "https://app.mem4dev.com/mcp" } } }
Claude Desktop y otros clientes: agrega un conector remoto/personalizado con la misma URL.
Autorizar
La primera vez que el cliente se conecta, se abre en tu navegador la pantalla de consentimiento de mem4dev (inicia sesión si hace falta). Eliges:
- Tipo de acceso: solo lectura (por defecto) o lectura y escritura.
- Ámbitos: todos tus ámbitos (incluidos los futuros) o solo los que selecciones.
Puedes revocar el acceso en cualquier momento desde tu cuenta. Un cliente autorizado en solo lectura que intente una tool de escritura recibe un error explícito que le indica volver a autorizar con escritura.
Tools
| Tool | Acceso | Qué hace |
|---|---|---|
list_scopes | lectura | Lista tus ámbitos (llámala primero para obtener el scope_id). |
get_plan_usage | lectura | Tu plan, sus límites y cuánto llevas usado (ámbitos, entradas, interacciones del mes, adjuntos). |
get_usage_guide | lectura | Instrucciones recomendadas para usar este MCP (consultas baratas con compact, entradas obsoletas, relaciones, cómo escribir entradas). Llámala primero, una vez por conversación. |
get_scope_context | lectura | El contexto que escribiste para el ámbito (quién es quién, reglas, vocabulario), sus instrucciones de consulta, quién eres tú en él y si es compartido. Léelo una vez por ámbito. |
query_entries | lectura | Búsqueda en lenguaje natural, con tags, rango de fechas, filtro de texto, relaciones (related_to), referencias (ref) y formato compacto opcionales; excluye las entradas obsoletas salvo que lo pidas. |
get_entry | lectura | Texto completo, adjuntos, marcas de obsoleta, relaciones y referencias de una entrada (aunque esté obsoleta). |
get_related_entries | lectura | Las entradas relacionadas con una dada, siguiendo las relaciones hasta 3 saltos. |
list_tags | lectura | Tags personalizados de un ámbito, con cuántas entradas usa cada uno. |
get_attachment_download_url | lectura | Enlace de descarga temporal (5 minutos) de un adjunto. |
add_entries_bulk | escritura | Registra hasta 20 entradas en una llamada, con sus tags, relaciones y referencias. |
update_entry | escritura | Edita texto, fecha, tags, relaciones y referencias de una entrada, o la marca como obsoleta (se conserva la versión anterior). |
link_entries | escritura | Relaciona una entrada existente con otras del mismo ámbito o le agrega referencias a commits, pull requests o issues, sin tocar su texto. |
delete_entry | escritura | Manda una entrada a la papelera (una por llamada). |
Las tools que tocan entradas reciben un scope_id; nunca se devuelven datos de otros ámbitos ni de otras cuentas. list_scopes incluye los ámbitos que otras personas compartieron contigo (marcados como compartidos): en ellos escribes solo si tu permiso lo permite, y valen los límites del plan de quien es dueño del ámbito.
Cada descripción de tool termina con la versión del catálogo (hoy 2026-10-22.2): sirve para comprobar qué versión recibió tu cliente. Si ves una fecha más vieja, tu cliente tiene la lista en caché; reconecta el servidor.
Los archivos solo se pueden adjuntar desde la web, no por MCP ni por la API. Por MCP se pueden consultar y descargar los adjuntos existentes; eliminarlos también es solo desde la web.
Eliminar entradas
delete_entry no borra de inmediato: la entrada sale de las búsquedas y queda 30 días en una papelera que solo el dueño del ámbito ve y puede recuperar desde la web. Desde el MCP no se recupera. Si la entrada era el único reemplazo de otras, esas siguen obsoletas salvo que envíes reactivate_obsolete: true; la respuesta trae kept_obsolete o reactivated.
Entradas obsoletas
Una entrada deja de estar vigente cuando otra más nueva la reemplaza. La forma recomendada es la relación replaces (ver Relaciones y referencias): la entrada nueva deja obsoleta a la vieja sola, y quitar la relación la reactiva. También puedes marcarla a mano con update_entry: obsolete: true y, si la conoces, replaced_by con el id de la entrada nueva (debe ser una entrada viva del mismo ámbito). Para marcarla no hace falta reenviar el texto. Nunca se borra: sigue en el historial, get_entry la devuelve siempre y marcarla crea una versión nueva, como cualquier edición. add_entries_bulk también acepta obsolete y replaced_by por entrada.
query_entries y get_related_entries excluyen las obsoletas por defecto y responden omitted_obsolete (cuántas coincidían) para que la IA sepa que existe historia; con include_obsolete: true las incluyen. Cada entrada devuelta trae obsolete y replaced_by. El chat de Consultar de la web también las excluye, con una casilla «Incluir entradas obsoletas» para verlas.
Búsquedas más baratas y con menos ruido
Además de question, tags, date_from, date_to, limit y offset, query_entries acepta:
format:"full"(por defecto, texto completo) o"compact": por entrada soloid,event_date,tags,obsolete,replaced_by,score,title(la primera línea# ...) yfragments(hasta 3 extractos de unos 200 caracteres alrededor de las coincidencias defiltero, sin filtro, desde la sección «Decisión»). El texto completo se pide después conget_entry.filter: lista de términos (basta con uno) u objeto{ "all": [...], "any": [...] }; yfilter_regex: expresión regular opcional (hasta 200 caracteres, sin cuantificadores anidados y con límite de costo). Se aplican sobre el texto completo, sin distinguir mayúsculas ni tildes.related_to:{ "entry_id", "types"?, "depth"? }limita la búsqueda a las entradas relacionadas con otra.ref:{ "type"?, "value", "repo"? }limita la búsqueda a las entradas que apuntan a ese commit, pull request, issue, rama o URL (un hash se encuentra por prefijo de 7 o más caracteres).explain:trueagrega a cada entrada su puntaje semántico y su puntaje léxico crudos (null= sin coincidencia en esa señal) y elmatch_type(qdrant= solo significado,lexical= solo palabras,hybrid= ambos). Solo conquestion. Si tu cliente no puede enviar listas u objetos,filtertambién los acepta escritos como texto JSON.candidates: cuántas candidatas reunir por fuente antes de filtrar (por defecto 50, máximo 200). Confilterofilter_regexy sincandidatesse usa el máximo. El orden es: candidatas → descartar obsoletas →filter→ ordenar por score → cortar alimit, así el filtro no pierde entradas que habrían quedado fuera del top 20.
La respuesta informa total_candidates (la unión de las candidatas semánticas y por palabras, por eso puede superar el tope), total_after_filter, omitted_obsolete, candidates_limit (el tope aplicado a cada fuente) y candidates_truncated (true = las candidatas que superan el puntaje mínimo llenaron ese tope, así que pueden existir entradas sin evaluar: sube candidates o acota con fechas o tags). has_more es true cuando hay más resultados después de esta página. Con filter y sin question solo se evalúan las candidates entradas más recientes que cumplen tags y fechas, y total_matches cuenta las que cumplen el filtro.
Contexto, autores y ranking
Cada ámbito tiene un contexto escrito en la web (quién es quién, el proyecto, reglas, vocabulario) y, si quieres, instrucciones para consultas. get_scope_context los entrega para que cualquier IA los use, como lo hace la pestaña Consultar; también dice quién eres en el ámbito (current_user) y si es compartido. get_usage_guide y las instrucciones de conexión le piden a la IA leer ambos una vez, primero.
Un ámbito puede ser compartido por varias personas. Cada entrada trae author (quién la escribió), en formato completo y compacto, así una IA distingue lo que hizo Ana de lo que hizo Luis.
Con question, los resultados salen ordenados por score (0 a 1), de mayor a menor, y a igual score primero la más reciente. El orden no depende de limit: las N primeras entradas son las mismas con cualquier limit, y offset lee más allá mientras has_more sea true. El score mezcla dos señales, cada una normalizada en su propia escala: 65 % similitud semántica y 35 % coincidencia de palabras (pesan más los términos raros y los del título), más un pequeño peso de recencia; una entrada con ambas señales nunca puntúa menos que una con una sola de igual valor. Lo que importa es el orden dentro de la respuesta, no el valor absoluto.
Límites del MCP
Cada tool tiene su propio límite por hora y por cuenta: query_entries 20; get_related_entries 60; add_entries_bulk, update_entry, delete_entry y link_entries 30 cada una. Además, cada llamada al MCP cuenta como una interacción del mes de tu plan (igual que cada llamada a la API y cada pregunta en Consultar; lo que haces desde la web no cuenta).
Crear una API key
Las API keys permiten que scripts, jobs de CI y tus propias herramientas usen la API REST sin iniciar sesión en el navegador. Para asistentes de IA, prefiere MCP.
Pasos
- Inicia sesión en
https://app.mem4dev.com/y abre API keys (https://app.mem4dev.com/api-keys). - Crea una clave y ponle un nombre que reconozcas (por ejemplo
ci-notas). - Elige a qué ámbitos tiene acceso. La lectura siempre está incluida en un ámbito asignado; la escritura es opcional y se define por ámbito.
- Copia el secreto ahora. Se ve como
mk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy se muestra una sola vez. - Revoca la clave desde la misma página cuando ya no la necesites.
Úsala
Envíala como Bearer token:
Authorization: Bearer mk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
URL base: https://app.mem4dev.com/api/v1
Endpoints
| Método y ruta | Permiso | Qué hace |
|---|---|---|
GET /scopes | lectura | Lista los ámbitos que tu clave puede usar. |
GET /entries | lectura | Lista entradas por ámbito y rango de fechas (scope_id, date_from, date_to, limit). Cada entrada trae relations y refs. |
POST /entries/search | lectura | Búsqueda en lenguaje natural (equivale a query_entries). |
GET /entries/related | lectura | Entradas relacionadas con una dada (equivale a get_related_entries). |
GET /entries/versions | lectura | Historial de ediciones de una entrada. |
GET /tags | lectura | Tags de un ámbito, con su conteo. |
GET /plan | lectura | Tu plan, límites y consumo. |
POST /entries/bulk | escritura | Registra hasta 20 entradas, con tags, relaciones y referencias. |
PUT o PATCH /entries | escritura | Edita una entrada: texto, fecha, tags, obsoleta, relaciones y referencias. |
POST /entries/links | escritura | Relaciona una entrada con otras o le agrega referencias, sin tocar su texto (equivale a link_entries). |
DELETE /entries | escritura | Manda una entrada a la papelera (reactivate=1 reactiva las que solo estaban obsoletas por ella). |
Permisos
| Configuración de la clave | Puede |
|---|---|
| Ámbito asignado, solo lectura | Los endpoints de lectura de la tabla anterior |
| Ámbito asignado, lectura y escritura | Todo lo anterior más los endpoints de escritura |
| Ámbito no asignado | 403 forbidden |
Una clave solo llega a los ámbitos a los que la cuenta que la creó tiene acceso: los propios y los que otras personas compartieron con ella (en estos últimos, escribir depende del permiso que te dieron). Si pierdes el acceso a un ámbito compartido, la clave también lo pierde.
Errores
Los errores son JSON: { "error": { "code": "forbidden", "message": "..." } }
| HTTP | code | Significado |
|---|---|---|
| 400 | invalid_request | Falta un campo o tiene formato inválido. |
| 401 | unauthorized | Clave faltante, inválida o revocada. |
| 402 | plan_limit | Se alcanzó un límite del plan de la cuenta dueña del ámbito (entradas o interacciones del mes). Nada se borra: solo se bloquea crear más. |
| 403 | forbidden | Sin acceso (o sin escritura) a ese ámbito. |
| 404 | not_found | El ámbito o la entrada no existe. |
| 429 | rate_limited | Límite superado: 120 solicitudes por hora, por clave y endpoint. |
Ejemplo con curl
Reemplaza mk_live_... por tu API key. URL base: https://app.mem4dev.com/api/v1.
1. Lista los ámbitos que tu clave puede usar
curl https://app.mem4dev.com/api/v1/scopes -H "Authorization: Bearer mk_live_..."
{ "ok": true, "scopes": [ { "scope_id": 1, "scope_name": "Trabajo", "can_read": true, "can_write": true } ] }
2. Registra una entrada (requiere escritura)
curl -X POST https://app.mem4dev.com/api/v1/entries/bulk -H "Authorization: Bearer mk_live_..." -H "Content-Type: application/json" -d '{"scope_id": 1, "entries": [{"entry_text": "# Límite de subidas\n\nDecisión: limitar las subidas a 50 MB.", "tags": ["adr"]}]}'
Hasta 20 entradas por llamada; cada una se valida por separado y la respuesta informa saved_count, failed_count y un resultado por entrada.
3. Registra una entrada que reemplaza a otra y apunta a un commit
curl -X POST https://app.mem4dev.com/api/v1/entries/bulk -H "Authorization: Bearer mk_live_..." -H "Content-Type: application/json" -d '{"scope_id": 1, "entries": [{"entry_text": "# Nuevo límite de subidas\n\nDecisión: 100 MB.", "relations": [{"type": "replaces", "target": 4821}], "refs": [{"type": "commit", "value": "a1b2c3d", "repo": "mem4dev-app"}]}]}'
La entrada 4821 queda obsoleta sola y deja de aparecer en las búsquedas. Si una relación o referencia falla, la entrada se guarda igual y el error va en link_errors.
4. Busca en lenguaje natural
curl -X POST https://app.mem4dev.com/api/v1/entries/search -H "Authorization: Bearer mk_live_..." -H "Content-Type: application/json" -d '{"scope_id": 1, "question": "¿qué decidimos sobre las subidas de archivos?", "date_from": "2026-09-01"}'
Omite question para filtrar solo por tags y fechas. Los resultados vienen de a 20 (usa offset para paginar). Las entradas obsoletas se excluyen salvo que envíes include_obsolete: true.
5. Lee por rango de fechas
curl "https://app.mem4dev.com/api/v1/entries?scope_id=1&date_from=2026-09-01&limit=50" -H "Authorization: Bearer mk_live_..."
6. Sigue las relaciones de una entrada
curl "https://app.mem4dev.com/api/v1/entries/related?scope_id=1&entry_id=4821&depth=2&include_obsolete=1" -H "Authorization: Bearer mk_live_..."
7. Relaciona una entrada existente (requiere escritura)
curl -X POST https://app.mem4dev.com/api/v1/entries/links -H "Authorization: Bearer mk_live_..." -H "Content-Type: application/json" -d '{"scope_id": 1, "entry_id": 4830, "add_relations": [{"type": "implements", "target": 4821}], "add_refs": [{"type": "pull_request", "value": "128", "repo": "mem4dev-app"}]}'
8. Edita y elimina (requieren escritura)
curl -X PUT https://app.mem4dev.com/api/v1/entries -H "Authorization: Bearer mk_live_..." -H "Content-Type: application/json" -d '{"scope_id": 1, "entry_id": 4821, "entry_text": "Texto corregido.", "add_tags": ["adr"]}'
curl -X DELETE "https://app.mem4dev.com/api/v1/entries?scope_id=1&entry_id=4821" -H "Authorization: Bearer mk_live_..."
Eliminar manda la entrada a la papelera: el dueño del ámbito puede recuperarla desde la web durante 30 días.
9. Consulta tu plan y tu consumo
curl https://app.mem4dev.com/api/v1/plan -H "Authorization: Bearer mk_live_..."
Devuelve el plan, sus límites, lo usado y lo que queda (ámbitos, entradas, interacciones del mes y almacenamiento). Si se alcanza un límite, las escrituras y búsquedas responden 402 plan_limit.
También disponibles: GET /entries/versions?scope_id=&entry_id= (historial de ediciones) y GET /tags?scope_id=.
Límites: 120 solicitudes por hora por clave y endpoint. Ver los límites públicos.
Ámbitos y tags
Ámbitos (scopes)
Un ámbito es un espacio separado dentro de tu cuenta: por ejemplo Trabajo, Cliente A, Proyecto personal. Cada ámbito tiene sus propias entradas y su contexto de IA.
- Cada cuenta y cada ámbito están aislados. Las consultas, respuestas MCP y llamadas a la API solo devuelven datos del ámbito que pides, y solo si tu clave o autorización MCP lo incluye.
- Toda llamada de API o MCP que toca entradas recibe un
scope_id. Obtén el tuyo conGET /api/v1/scopeso la tool MCPlist_scopes. - El acceso se otorga por ámbito: una API key tiene lectura (siempre) y escritura (opcional) por ámbito; una autorización MCP cubre todos los ámbitos o los que selecciones.
Ámbitos compartidos
El dueño de un ámbito puede compartirlo con otras personas por correo, con permiso de solo lectura o de lectura y escritura. Está disponible en todos los planes.
- Quien acepta la invitación ve el ámbito compartido junto a los suyos; en la API y en MCP aparece marcado como compartido, con su rol.
- Quien escribe puede editar y eliminar cualquier entrada del ámbito, como el dueño; lo eliminado queda 30 días en una papelera que solo el dueño ve y puede recuperar. Solo el dueño invita, revoca y gestiona el ámbito, y las invitaciones vencen a los 7 días.
- Los límites (entradas, interacciones del mes, adjuntos y personas) son los del plan del dueño, no los de quien consulta.
- Una API key o una autorización MCP de una persona invitada llega a ese ámbito solo mientras esa persona conserve el acceso.
- En cada entrada,
authordice quién la escribió.
Entradas
Una entrada es texto libre (hasta 5.000 caracteres) con un event_date (por defecto hoy en tu zona horaria; no puede ser futuro). Las ediciones conservan un historial de versiones. Para que una IA las aproveche mejor, escribe cada entrada con un título (# ...) y una sección «Decisión», de forma que se entienda sola.
Tags
Los tags personalizados organizan las entradas dentro de un ámbito, más allá del texto libre.
- Asigna tags al crear una entrada (
tagsenentries/bulk) o después (add_tags/remove_tagsal editar). - Lista los tags de un ámbito, con cuántas entradas usa cada uno:
GET /api/v1/tags?scope_id=1o MCPlist_tags. Reutiliza un tag existente en vez de crear uno casi igual. - Filtra por tags en
POST /api/v1/entries/searcho en MCPquery_entries. Varios tags se combinan con AND (la entrada debe tenerlos todos); se pueden combinar con una pregunta y un rango de fechas.
Relaciones y referencias
Una entrada puede relacionarse con otras del mismo ámbito y apuntar a tu código. Las relaciones nunca cruzan ámbitos.
Tipos de relación
| Tipo | Inversa | Significado |
|---|---|---|
replaces | replaced_by | La entrada nueva reemplaza a la vieja. La vieja queda obsoleta mientras exista la relación. |
caused_by | causes | Una decisión o jornada nace de un incidente o problema. |
implements | implemented_by | Una jornada ejecuta una decisión. |
refines | refined_by | Una entrada ajusta una parte de otra, que sigue vigente. |
continues | continued_by | Una entrada es la parte siguiente de un texto largo partido en varias entradas. Ninguna queda obsoleta. |
relates_to | relates_to | Asociación libre, simétrica. |
Cada relación se guarda una vez; la inversa se calcula al leer. Aceptas cualquiera de los dos nombres al crearla.
Referencias externas
Una entrada puede apuntar a: commit (hash de 7 a 64 caracteres), pull_request, issue (número o clave, como PROY-123), branch y url. Cada referencia admite repo y title opcionales. mem4dev solo guarda el puntero: no consulta tu repositorio.
Cómo crearlas
- Al guardar:
relationsyrefsen cada entrada deadd_entries_bulk(MCP) o dePOST /entries/bulk(API). Una relación apunta a una entrada existente contargeto a otra entrada del mismo paquete contarget_index(posición desde 0). - Al editar:
add_relations,remove_relations,add_refsyremove_refsenupdate_entryo enPUT /entries. - Sin tocar el texto:
link_entries(MCP) oPOST /entries/links(API). - Una relación o referencia que falla no impide guardar la entrada: el error va en
link_errors.
Cómo leerlas
get_entryyGET /entriesdevuelvenrelations(tipo → ids) yrefsde cada entrada.get_related_entriesyGET /entries/relatedrecorren las relaciones:types,direction(out,inoboth),depth(1 a 3),limit(25 por defecto, máximo 50),include_obsoleteywith_refs. Devuelven por entrada solo id, fecha, título,obsolete, la relación vista desde la entrada por la que se llegó (relation), esa entrada (via) y la profundidad; el texto completo se pide conget_entry.query_entriesyPOST /entries/searchaceptanrelated_toyrefpara buscar solo entre entradas relacionadas o que apuntan a un commit, pull request o issue.
Límites y permisos
- Hasta 50 relaciones y 20 referencias por entrada, y hasta 20 de cada una por llamada.
- Necesitas permiso de escritura. En un ámbito compartido, quien escribe debe ser autor de al menos una de las dos entradas (en un reemplazo, de la que queda obsoleta); el dueño puede con todas.
- Una llamada que cambia algo cuenta una interacción del plan; con el tope alcanzado responde
402 plan_limit.
Límites públicos
| Concepto | Límite |
|---|---|
| Texto de una entrada | 5.000 caracteres |
| Entradas por llamada bulk | 20 |
| Relaciones y referencias por entrada | 50 relaciones, 20 referencias |
| Adjuntos | 10 MB por archivo, 5 por entrada (solo se suben desde la web; por MCP se pueden consultar y descargar) |
| Tipos de adjunto | pdf, jpg, jpeg, png, webp, docx, xlsx, pptx, txt, md, zip, rar, skill |
| API REST | 120 solicitudes por hora, por API key y endpoint (GET /scopes, GET /tags y GET /plan: sin límite propio) |
| MCP | por tool y por hora: query_entries 20, get_related_entries 60, add_entries_bulk, update_entry, delete_entry y link_entries 30 cada una |
| Resultados de búsqueda | 20 por página |
| Interacciones | Cada llamada a la API, cada llamada al MCP y cada pregunta en Consultar cuentan 1, contra el plan del dueño de los datos. Lo que haces desde la web no cuenta. |
Planes
| Plan | Ámbitos propios | Entradas | Interacciones al mes | Adjuntos | Personas por ámbito compartido | Ámbitos de otras cuentas que puedes aceptar |
|---|---|---|---|---|---|---|
| Free | 1 | 1.000 | 1.000 | 100 MB | 1 | 1 |
| Individual (desde USD 7,99 al mes) | 10 | 10.000 | 10.000 | 1 GB | 10 | 10 |
El plan Free no pide tarjeta y no restringe funcionalidades (MCP y API incluidos); sus límites son de volumen. Individual tiene escalones superiores dentro del mismo plan. Individual ya está disponible; Teams llega próximamente. Compartir ámbitos existe en todos los planes y los límites los define el plan del dueño del ámbito. Al tope de entradas solo se bloquea crear más; al de interacciones, la API, el MCP y Consultar se pausan hasta que se renueve. Nunca se borra nada y la web sigue disponible para leer. Puedes ver tu consumo con la tool MCP get_plan_usage o GET /api/v1/plan.