Claude научили локально искать по заметкам через MCP-сервер
Если у вас есть папка с конспектами встреч и расшифровками созвонов, обычный поиск по словам быстро начинает подводить: в тексте может быть «собеседование» вместо «найм», и нужный файл не найдётся. В этой заметке показан локальный семантический поиск для Claude Code, который работает без платных API и не отправляет заметки наружу.
Что именно собрали и зачем
Автор собрал небольшой MCP-сервер на Python и подключил его к Claude Code. В паре с движком поиска он умеет находить не только точное совпадение слова, а смысловые совпадения прямо на компьютере пользователя.
Внутри решения всего два файла: search_index.py отвечает за нарезку текста, эмбеддинги, кэш и сам поиск, а server.py — за MCP-интерфейс. Плюс создаётся папка .index, куда складывается кэш; в репозиторий она не попадает.
Какие инструменты получает Claude
Сервер отдаёт три инструмента: search_notes ищет по смыслу и возвращает подходящие фрагменты с именем файла и оценкой близости, list_notes показывает список заметок с размером и датой изменения, а read_note отдаёт файл целиком.
Все три инструмента только читают данные. Это важно для безопасности и удобства: Claude может сам выбрать нужный способ работы с заметками, не спрашивая лишнего у пользователя. MCP здесь выступает как протокол, по которому программа запускает маленький сервер и общается с ним через стандартный ввод и вывод, без отдельного сетевого порта.
Почему пришлось внимательно делить текст
Одна из главных ловушек оказалась в том, что модель для эмбеддингов молча обрезает слишком длинный вход. У paraphrase-multilingual-MiniLM-L12-v2 лимит 128 токенов, и всё, что длиннее, просто не участвует в поиске без ошибки и предупреждения.
Поэтому текст режут не только по символам, но и по токенам. Сначала заметка разбивается на смысловые куски по строкам и предложениям, а затем каждый кусок проверяется по лимиту модели. Если он всё равно слишком длинный, его дополнительно режут уже точно по токенам. В результате хвосты заметок не теряются, а соседние фрагменты чуть перекрываются, чтобы не рвать мысль посередине.
Кэш, версия Python и что это даёт на практике
Чтобы не пересчитывать эмбеддинги каждый раз, автор сохраняет их в кэш .index/cache.pkl. Ключ строится не только по имени файла, но и по времени его изменения, поэтому кэш сам понимает, когда заметка устарела. Это полезно, если вы постоянно дополняете конспекты встреч и не хотите ждать повторной индексации.
Для запуска зафиксированы и зависимости: нужен Python 3.11, а сама модель берётся в облегчённом варианте, который умеет работать с русским и английским и после первого скачивания не требует интернета. Для нескольких десятков заметок этого достаточно, а более тяжёлая модель оставлена как запасной вариант на случай, если точности не хватит.