scratchpad-mcp
scratchpad-mcp
Постоянное и эффективное с точки зрения токенов хранилище для AI-агентов. MCP-сервер, который предотвращает повторное чтение одних и тех же файлов и повторную загрузку одного и того же контекста агентами при каждом обращении.
agent: "what changed in this file since I last read it?"
server: { diff: [...], current_version: 14 } ← not the whole fileЗачем это нужно
Агенты тратят токены впустую. Они повторно читают уже просмотренные файлы, пересказывают документы, которые уже обработали, и заново находят состояние, которое уже вычислили. Этот сервер предоставляет им место для сохранения этой работы, чтобы они могли вернуться к ней позже способом, который модель может дешево интерпретировать.
Конкретно:
Версионируемая запись, чтобы агент мог сохранить рабочий документ и спросить: «Что изменилось с тех пор, как я видел его в последний раз?» — сервер вернет структурированный diff вместо полного содержимого.
Журналы только для добавления с постраничной навигацией на основе курсора, чтобы агент мог записывать историю своих действий и эффективно воспроизводить её.
Создание сводок по запросу для длинных файлов (>2000 оценочных токенов), генерируемых Claude Haiku и кэшируемых для каждой версии файла, поэтому повторные вызовы сводок бесплатны.
Пространство имен для каждого агента, чтобы один экземпляр сервера мог обслуживать множество агентов без утечки состояния между ними.
Инструменты
Все инструменты принимают agent_id в качестве первого аргумента. Операции ограничены этим агентом — агенты не могут читать файлы или журналы друг друга.
Инструмент | Что он делает |
| Сохраняет содержимое по пути. Автоматически создает версию при каждой записи. Хранит 10 последних версий. |
| Читает полное содержимое или JSON-diff относительно предыдущей версии. Если |
| Добавляет одну запись в журнал только для добавления. Возвращает ID новой записи. |
| Читает записи журнала с постраничной навигацией по курсору. 100 записей на страницу, флаг |
| Список файлов (только метаданные), опционально отфильтрованный по префиксу пути. |
| Удаляет файл, все его версии и любые кэшированные сводки. |
| LLM-сводка длинного файла (>8000 символов). Кэшируется для каждой версии, поэтому повторные вызовы для неизмененного файла ничего не стоят. |
| Возвращает общее количество байтов, файлов, записей в журнале и общее количество операций для агента. |
Формат Diff
read_file с параметром since_version возвращает JSON-массив фрагментов:
{
"diff": [
{ "op": "equal", "lines": ["line that didn't change"] },
{ "op": "remove", "lines": ["line that was deleted"] },
{ "op": "add", "lines": ["line that was added"] }
]
}Построчное сравнение выбрано намеренно — это формат, с которым агенты работают наиболее надежно, и он позволяет агенту анализировать что именно изменилось, а не переобрабатывать весь файл целиком.
Правила путей
Пути должны соответствовать [a-zA-Z0-9/_.-]+, максимум 255 символов, без ведущего /, без последовательностей ... Ошибки указывают на нарушенное правило.
Ограничения
1 МБ на запись файла
64 КБ на запись в журнале
10 хранимых версий на файл (старые удаляются автоматически)
100 записей журнала на страницу
read_log
Установка
Требуется Node 20+ и API-ключ Anthropic (только для summarize_file).
git clone <this repo>
cd scratchpad-mcp
npm install
npm run buildЭто создаст dist/index.js, исполняемый сервер.
Настройка в Claude Desktop
Добавьте в %APPDATA%\Claude\claude_desktop_config.json (Windows) или ~/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 требуется только в том случае, если вы планируете вызывать summarize_file. Остальные семь инструментов работают без него.
Опционально: установите SCRATCHPAD_DB_PATH, чтобы переопределить расположение SQLite. По умолчанию используется scratchpad.db в корне проекта.
Перезапустите Claude Desktop. Сервер должен появиться в списке MCP-серверов с 8 инструментами.
Модель безопасности — прочитайте перед хостингом
agent_id — это параметр инструмента в открытом виде. Аутентификации нет: вызывающий может представиться любым agent_id, и сервер доверится ему. Это сделано намеренно для V1 и хорошо работает для предполагаемой формы развертывания, а именно:
Один пользователь на процесс сервера. Агент и файл SQLite разделяют границу доверия. Примеры: установка Claude Desktop, локальная установка Smithery, запуск Apify Actor для каждого пользователя (Apify по умолчанию создает новый контейнер со свежим файлом базы данных для каждого запуска).
Это небезопасно для:
Мультиарендного режима ожидания, где один процесс сервера обслуживает нескольких недоверенных вызывающих, читающих и записывающих один и тот же файл SQLite. Любой может передать
agent_idдругого вызывающего и прочитать или перезаписать его данные.
Если вам нужна мультиарендность, выводите agent_id из API-ключа вызывающего в слое-обертке (это план V2) или запускайте по одному процессу на арендатора.
Эшелонированная защита, которая уже реализована
Весь SQL параметризован — инъекции через путь, agent_id или префикс невозможны.
Валидация путей отклоняет
.., ведущий/, пробелы и любые символы вне[a-zA-Z0-9/_.-].Сопоставление префикса в
list_filesиспользует равенствоSUBSTR(неLIKE), поэтому SQL-шаблоны_и%никогда не применяются, а сопоставление чувствительно к регистру.Ограничения размера на вызов (1 МБ / файл, 64 КБ / запись журнала).
Квоты на агента (1000 файлов, 100 тыс. записей журнала, 100 МБ всего), чтобы вышедший из-под контроля агент не исчерпал общее дисковое пространство при хостинге.
Ошибки возвращают только
err.message— никаких трассировок стека, путей SQLite или API-ключей.
Кто платит за summarize_file?
Вызывающий. Всегда.
Локальная установка (Smithery, Claude Desktop, mcp.so): пользователь предоставляет свой собственный
ANTHROPIC_API_KEYв конфигурации. Его машина, его ключ, его счет.Хостинг Apify: каждый запуск Actor считывает
anthropicApiKeyиз входных данных запуска. Загрузчик.actor/entrypoint.shотображает его в переменные окружения перед запуском сервера. Каждый вызывающий платит Anthropic за свои сводки; издатель Actor получает только комиссию Apify за вызов.
Если вы делаете форк и планируете хостинг, не вшивайте API-ключ в Dockerfile, среду Apify Actor или любую конфигурацию, которая распространяется публично. Остальные семь инструментов работают без ключа, поэтому оставить его не заданным — безопасный вариант по умолчанию.
Как работает хранилище
Один файл SQLite содержит всё:
files— одна строка на(agent_id, path), отслеживает текущую версию.file_versions— полное содержимое для каждой версии, ограничено 10 последними на файл. Очистка происходит при каждомwrite_file.log_entries— записи только для добавления, никогда не изменяются.summaries— кэш сводок для каждого файла, аннулируется при несовпадении версий.agent_usage— счетчик операций для каждого агента дляget_usage_stats.
Версионирование хранит полное содержимое для каждой версии (не дельты), потому что запись должна быть быстрой, а чтение — однозначным. Diff-сравнения вычисляются при чтении путем сравнения двух версий на уровне строк — стоимость оплачивается вызывающим, запрашивающим diff, а не каждым пишущим.
Дорожная карта
[ ] Упаковка для Apify для биллинга за вызов.
[ ] Вывод
agent_idиз API-ключа вместо получения его в качестве параметра.[ ] Бэкенд Postgres (схема SQLite переносима; это замена подключения, а не переписывание).
[ ] Ограничение частоты запросов для каждого агента.
[ ] Структурированное логирование для видимости операций.
Лицензия
MIT — см. LICENSE.
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