Mantengo desde hace años un archivo de notas personales donde acaba todo lo que pienso. El objetivo era que un asistente pudiera leerlas y escribir en ellas de verdad: operar sobre el archivo, no recibir fragmentos copiados en un chat.
La vía rápida era una conexión a medida para el asistente que uso hoy. Un par de tardes de trabajo y funcionando. Se descartó por un motivo que no es técnico: dentro de un año el asistente será otro y esa conexión no serviría para nada. En su lugar se implementó el protocolo que ya existe para esto, el Model Context Protocol, la forma estándar de que un modelo hable con herramientas externas.
La diferencia aparece en el momento de conectar. Un cliente nuevo no necesita que se le abra nada ni que se le entreguen credenciales por un canal aparte: llega, se registra por su cuenta y solicita permiso. Lo permite una parte del estándar, el registro dinámico de cliente, y es la razón de que hoy Claude y ChatGPT se conecten al mismo servidor sin que el segundo exigiera una sola línea adicional.
La diferencia entre construir una integración y construir una interfaz.
Conceder permiso de escritura sobre años de notas personales a un modelo de lenguaje impone cierto respeto, y la puerta de entrada acabó llevando más trabajo que las funciones. Para autorizarse, el cliente demuestra —con un secreto generado en el momento— que quien pide el permiso y quien recoge la llave son el mismo, y no alguien que se ha colado por medio. Es un mecanismo estándar, PKCE, y aquí no es opcional.
Lo que no existe es una contraseña de aplicación compartida con esos clientes: un secreto que viaja a programas que no controlas deja de ser un secreto en cuanto sale de tu máquina. La frontera real de acceso es una clave que solo conoce el propietario y que se solicita en el momento de autorizar.
Alrededor hay detalles pequeños que sostienen el conjunto. Las llaves se comparan en un tiempo que no depende de cuánto acierta quien lo intenta, porque medir esa diferencia es una forma conocida de adivinarlas a ciegas. Tras varios intentos fallidos, esa dirección queda bloqueada temporalmente. Y si el servidor arranca sin secreto configurado, no arranca.
Expone ocho herramientas: listar, leer, escribir, mover, añadir al final, borrar, buscar por texto y buscar por significado. El borrado es reversible —mueve a una papelera en lugar de destruir— y cualquier ruta recibida del exterior se resuelve contra la carpeta raíz antes de tocar el disco, para que una ruta manipulada no pueda salirse de ahí y leer el resto del servidor.
La última herramienta es la que tiene más miga. Buscar por significado —encontrar la nota que trata de un tema aunque no emplee esas palabras— consiste en convertir cada nota en una lista de números que representa su contenido. Lo habitual es guardar esos números en una base de datos especializada. Aquí se guardan en un fichero y se comparan todos, uno por uno, en cada búsqueda.
Suena a atajo hasta que se mira la escala: son cientos de notas cortas y recorrerlas enteras cuesta microsegundos. La base de datos vectorial habría añadido una pieza más que mantener, actualizar y compilar para la arquitectura concreta de este servidor, a cambio de una mejora imperceptible. Esa pregunta —si algo hace falta de verdad o se está incorporando por costumbre— es la que ahorra la mitad del trabajo en cualquier proyecto.
El modelo que convierte las notas en números se ejecuta en el propio servidor. No sale ni una nota hacia terceros, no hay clave que gestionar y no hay coste por documento. Para un archivo personal, era la única opción defendible.