Skip to main content
Glama

scratchpad-mcp

License: MIT Node MCP

Almacenamiento persistente y eficiente en tokens para agentes de IA. Un servidor MCP que evita que tus agentes vuelvan a leer los mismos archivos y a cargar el mismo contexto en cada turno.

agent: "what changed in this file since I last read it?"
server: { diff: [...], current_version: 14 }   ← not the whole file

Por qué

Los agentes desperdician tokens. Vuelven a leer archivos que ya han visto, vuelven a resumir documentos que ya han procesado y vuelven a descubrir estados que ya han calculado. Este servidor les da un lugar donde poner ese trabajo y recuperarlo más tarde de una manera que el modelo puede razonar de forma económica.

Concretamente:

  • Escrituras versionadas para que un agente pueda almacenar un documento de trabajo y preguntar "¿qué ha cambiado desde la última vez que vi esto?": el servidor devuelve una diferencia estructurada en lugar del contenido completo.

  • Registros de solo anexado con paginación basada en cursor, para que un agente pueda registrar su propio historial de acciones y reproducirlo de manera eficiente.

  • Resúmenes bajo demanda para archivos largos (>2000 tokens estimados), generados por Claude Haiku y almacenados en caché por versión de archivo, por lo que las llamadas de resumen repetidas son gratuitas.

  • Espacios de nombres por agente para que una instancia de servidor pueda servir a muchos agentes sin filtrar el estado entre ellos.

Herramientas

Todas las herramientas toman agent_id como su primer argumento. Las operaciones están limitadas a ese agente: los agentes no pueden leer los archivos o registros de otros.

Herramienta

Qué hace

write_file(agent_id, path, content)

Almacena contenido en una ruta. Se versiona automáticamente en cada escritura. Mantiene las 10 versiones más recientes.

read_file(agent_id, path, since_version?)

Lee el contenido completo o una diferencia de líneas JSON respecto a una versión anterior. Si since_version ha sido eliminado, devuelve el contenido completo con version_too_old: true.

append_log(agent_id, path, entry)

Anexa una entrada a un registro de solo anexado. Devuelve el ID de la nueva entrada.

read_log(agent_id, path, since_entry?)

Lee entradas de registro con paginación por cursor. 100 entradas por página, indicador has_more más cursor last_entry_id.

list_files(agent_id, prefix?)

Lista archivos (solo metadatos) filtrados opcionalmente por prefijo de ruta.

delete_file(agent_id, path)

Elimina un archivo y todas sus versiones y cualquier resumen almacenado en caché.

summarize_file(agent_id, path)

Resume un archivo largo (>8000 caracteres) mediante LLM. Almacenado en caché por versión, por lo que las llamadas repetidas en un archivo sin cambios no tienen coste.

get_usage_stats(agent_id)

Devuelve el total de bytes, recuento de archivos, recuento de registros y operaciones totales para un agente.

Formato de diferencia

read_file con since_version devuelve una matriz JSON de fragmentos:

{
  "diff": [
    { "op": "equal",  "lines": ["line that didn't change"] },
    { "op": "remove", "lines": ["line that was deleted"] },
    { "op": "add",    "lines": ["line that was added"] }
  ]
}

La diferencia a nivel de línea es intencional: es el formato que los agentes manejan de manera más fiable y permite al agente razonar sobre qué cambió en lugar de volver a procesar todo el archivo.

Reglas de ruta

Las rutas deben coincidir con [a-zA-Z0-9/_.-]+, máximo 255 caracteres, sin / inicial, sin secuencias ... Los errores nombran la regla violada.

Límites

  • 1 MB por escritura de archivo

  • 64 KB por entrada de registro

  • 10 versiones retenidas por archivo (las más antiguas se eliminan automáticamente)

  • 100 entradas de registro por página de read_log

Instalación

Requiere Node 20+ y una clave API de Anthropic (solo para summarize_file).

git clone <this repo>
cd scratchpad-mcp
npm install
npm run build

Eso produce dist/index.js, el servidor ejecutable.

Configuración con Claude Desktop

Añadir a %APPDATA%\Claude\claude_desktop_config.json (Windows) o ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "scratchpad": {
      "command": "node",
      "args": ["C:\\path\\to\\scratchpad-mcp\\dist\\index.js"],
      "env": {
        "ANTHROPIC_API_KEY": "sk-ant-..."
      }
    }
  }
}

ANTHROPIC_API_KEY solo es necesaria si tienes la intención de llamar a summarize_file. Las otras siete herramientas funcionan sin ella.

Opcional: establece SCRATCHPAD_DB_PATH para anular la ubicación de SQLite. Por defecto es scratchpad.db en la raíz del proyecto.

Reinicia Claude Desktop. El servidor debería aparecer en la lista de servidores MCP con 8 herramientas.

Modelo de seguridad: lee esto antes de alojar

agent_id es un parámetro de herramienta en texto plano. No hay autenticación: un llamador puede afirmar ser cualquier agent_id y el servidor confiará en él. Esto es deliberado para la V1 y funciona bien para la forma de despliegue prevista, que es:

  • Un usuario por proceso de servidor. El agente y el archivo SQLite comparten un límite de confianza. Ejemplos: instalación de Claude Desktop, instalación local de Smithery, ejecución de Apify Actor por usuario (Apify genera un contenedor nuevo con un archivo de base de datos nuevo por ejecución de forma predeterminada).

No es seguro para:

  • Modo de espera multiinquilino donde un proceso de servidor sirve a múltiples llamadores no confiables que leen y escriben en el mismo archivo SQLite. Cualquiera puede pasar el agent_id de otro llamador y leer o sobrescribir sus datos.

Si deseas multiinquilino, deriva el agent_id de la clave API del llamador en una capa contenedora (este es el plan para la V2) o ejecuta un proceso por inquilino.

Defensa en profundidad que está implementada

  • Todo SQL está parametrizado: no es posible la inyección a través de ruta, agent_id o prefijo.

  • La validación de ruta rechaza .., / inicial, espacios y cualquier carácter fuera de [a-zA-Z0-9/_.-].

  • La coincidencia de prefijo de list_files utiliza igualdad SUBSTR (no LIKE), por lo que los comodines SQL _ y % nunca se aplican, y la coincidencia distingue entre mayúsculas y minúsculas.

  • Límites de tamaño por llamada (1 MB / archivo, 64 KB / entrada de registro).

  • Cuotas por agente (1000 archivos, 100k entradas de registro, 100 MB en total) para que un agente desbocado no pueda agotar el disco compartido en un despliegue alojado.

  • Los errores devuelven solo err.message: sin seguimientos de pila, sin rutas de SQLite, sin claves API.

¿Quién paga por summarize_file?

El llamador. Siempre.

  • Instalación local (Smithery, Claude Desktop, mcp.so): el usuario proporciona su propia ANTHROPIC_API_KEY en su configuración. Su máquina, su clave, su factura.

  • Alojado en Apify: cada ejecución de Actor lee anthropicApiKey de su entrada por ejecución. Un lanzador .actor/entrypoint.sh lo asigna al entorno antes de iniciar el servidor. Cada llamador paga a Anthropic por sus propios resúmenes; el editor del Actor solo cobra la tarifa por llamada de Apify.

Si haces un fork de esto y tienes la intención de alojarlo, no codifiques una clave API en el Dockerfile, el entorno de Apify Actor o cualquier configuración que se envíe públicamente. Las otras siete herramientas funcionan sin una clave, por lo que dejarla sin configurar es un valor predeterminado seguro.

Cómo funciona el almacenamiento

Un único archivo SQLite contiene todo:

  • files: una fila por (agent_id, path), rastrea la versión actual.

  • file_versions: contenido completo por versión, limitado a las 10 más recientes por archivo. La poda ocurre en cada write_file.

  • log_entries: entradas de solo anexado, nunca modificadas.

  • summaries: caché de resumen por archivo, invalidado por falta de coincidencia de versión.

  • agent_usage: contador de operaciones por agente para get_usage_stats.

El versionado almacena el contenido completo por versión (no deltas) porque las escrituras deben ser rápidas y las lecturas deben ser inequívocas. Las diferencias se calculan en la lectura ejecutando las dos versiones a través de una diferencia a nivel de línea: el coste lo paga el llamador que solicita la diferencia, no cada escritor.

Hoja de ruta

  • [ ] Empaquetado de Apify para facturación por llamada.

  • [ ] Derivar agent_id de la clave API en lugar de tomarlo como parámetro.

  • [ ] Backend de Postgres (el esquema de SQLite es portátil; esto es un intercambio de conexión, no una reescritura).

  • [ ] Limitación de tasa por agente.

  • [ ] Registro estructurado para visibilidad de operaciones.

Licencia

MIT: ver LICENSE.

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

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/MikePressure/scratchpad-mcp'

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