Skip to main content
Glama
Surf-Team

FileManager MCP Server

by Surf-Team

FileManager MCP Server

MCP-сервер (Streamable HTTP) для read-only доступа ИИ-клиентов к файлам проектов. Проекты, разрешённые каталоги, расширения файлов и ключи доступа описываются в YAML-конфиге — всё, что не указано в конфиге явно, сервер прочитать не может.

Инструменты

Инструмент

Описание

list_projects

Проекты, доступные предъявленному API-ключу: id, название, описание, корневые папки, читаемые расширения, лимиты

list_files

Содержимое папки проекта; без path — список корней, с recursive: true — рекурсивный обход (только файлы)

read_file

Чтение текстового файла в UTF-8, с постраничной выдачей по строкам (offset / limit)

find_files

Поиск файлов по имени: glob (*, ?, **) или подстрока

search_content

Поиск по содержимому файлов (grep) с номерами строк и опциональным контекстом

file_info

Метаданные файла/папки: тип, размер, даты, расширение, доступность для чтения, число строк

Инструментов записи нет — сервер физически не умеет изменять файлы.

Related MCP server: TimeVerse Code Reader

Требования

  • Node.js 18+

  • Доступ на чтение к каталогам, указанным в конфиге

Установка

npm install
cp .env.example .env                       # порт, лимиты, значения ключей
cp projects.example.yaml projects.yaml     # описание проектов
# отредактировать оба файла

Конфигурация проектов (projects.yaml)

Путь к файлу задаётся переменной PROJECTS_CONFIG (по умолчанию ./projects.yaml).

defaults:                        # необязательно, лимиты по умолчанию для всех проектов
  max_file_size: 1048576
  max_entries: 1000
  max_depth: 5

projects:
  - id: gve-server-data                     # ^[a-z0-9][a-z0-9_-]*$, уникален
    name: Данные игрового сервера
    description: |
      Конфиги, html-диалоги NPC и csv/yaml-таблицы игрового сервера GVE.
    paths:                                  # абсолютные пути, подпапки доступны автоматически
      - /root/Gve-Server-Data/data
    extensions: [.yaml, .yml, .xml, .html, .htm, .md, .json, .txt]
    exclude:                                # необязательно, glob по виртуальному пути
      - "**/secrets/**"
    list_unreadable: false                  # показывать ли файлы с чужими расширениями
    max_file_size: 2097152                  # необязательный override
    api_keys:
      - "${FM_KEY_GVE_DATA}"                # подстановка из окружения (рекомендуется)

Поле

Обязательное

Назначение

id

да

Идентификатор проекта, передаётся в аргументе project

name

нет

Человекочитаемое название (по умолчанию id)

description

нет

Описание для ИИ: что за данные и зачем они нужны

paths

да

Абсолютные пути к разрешённым корням; должны существовать и не быть вложены друг в друга

extensions

да

Расширения, доступные для чтения и поиска (yml нормализуется в .yml)

exclude

нет

Дополнительные исключения (glob по виртуальному пути)

list_unreadable

нет

Показывать в листингах файлы с неразрешёнными расширениями (readable: false)

max_file_size / max_entries / max_depth

нет

Переопределение лимитов проекта

api_keys

да

Ключи доступа к этому проекту, минимум 24 символа; ${VAR} берётся из окружения

Конфиг читается один раз при старте. Любая ошибка валидации (несуществующий путь, короткий ключ, дублирующийся id, вложенные корни) останавливает запуск — сервер никогда не поднимается с частично корректным списком разрешений. После изменения YAML нужен рестарт.

Переменные окружения (.env)

Переменная

По умолчанию

Назначение

PORT

3200

Порт MCP-сервера

PROJECTS_CONFIG

./projects.yaml

Путь к конфигу проектов

MAX_FILE_SIZE

1048576

Максимальный размер читаемого файла, байт

MAX_ENTRIES

1000

Максимум записей в одном листинге

MAX_DEPTH

5

Максимальная глубина рекурсивного обхода

MAX_LINE_LENGTH

2000

Длинные строки обрезаются до этой длины

SEARCH_MAX_FILES

2000

Максимум файлов, просматриваемых в search_content

SEARCH_MAX_MATCHES

200

Максимум совпадений в ответе search_content

SEARCH_TIMEOUT_MS

5000

Бюджет времени на один поиск

SEARCH_ALLOW_REGEX

true

Разрешать ли режим regex: true в search_content

Запуск

npm start        # прод
npm run dev      # с автоперезапуском (--watch)
npm test         # тесты модели безопасности (node --test)
  • MCP endpoint: POST http://<host>:<PORT>/mcp (требует API-ключ)

  • Health check: GET http://<host>:<PORT>/health — статус и доступность всех корней

Подключение MCP-клиента

{
  "mcpServers": {
    "filemanager": {
      "url": "http://<host>:<PORT>/mcp",
      "headers": { "Authorization": "Bearer <API_KEY>" }
    }
  }
}

Ключ можно передавать и в заголовке X-API-Key.

Модель безопасности

Клиент никогда не видит и не передаёт реальные пути файловой системы. Файлы адресуются виртуальным путём <корень>/<подпапка>/<файл>, где <корень> — имя (basename) одного из каталогов в paths.

  1. Валидация ввода. Отклоняются пути с \0, обратным слэшем, двоеточием, сегментами ./.., длиной больше 1024 символов.

  2. Канонизация и проверка вложенности. Путь разрешается через fs.realpath, и результат обязан находиться внутри канонизированного корня. Это закрывает и ../-обход, и побег по симлинку/junction — в том числе созданному уже после старта сервера. Каждая запись каталога при обходе тоже проходит realpath; всё, что указывает наружу, молча скрывается.

  3. Allowlist расширений. Читать и искать можно только в файлах с расширениями из extensions.

  4. Неотключаемый deny-list поверх allowlist: любые файлы и папки, начинающиеся с точки (.env, .git, .ssh), node_modules, ключевой материал (*.pem, *.key, id_rsa*, *.jks, …), shadow/passwd/authorized_keys, а также имена с credentials, api_key, private_key, access_token. Плюс пользовательские exclude-глобы.

  5. Никаких exec/spawn. Поиск реализован на Node fs API, а не через grep/rg, поэтому командной инъекции нет в принципе.

  6. Лимиты на размер файла, число записей, глубину обхода, число просматриваемых файлов, количество совпадений, время поиска, длину строки и размер тела HTTP-запроса (256 КБ). Бинарные файлы (NUL в первых 8 КБ) не отдаются.

  7. Изоляция ключей. Ключ привязан к проектам; чужой проект не виден в list_projects и сообщает Unknown project во всех остальных инструментах. Сравнение ключей — timingSafeEqual по sha256, с полным проходом по индексу (без утечки по времени).

  8. Без утечки путей. В ответах и ошибках фигурируют только виртуальные пути. «Вне корня», «запрещено» и «не существует» дают одинаковое сообщение Path not found, поэтому API нельзя использовать как оракул для разведки файловой системы. Неожиданные ошибки ФС логируются на сервере, а клиенту отдаётся обобщённое сообщение.

  9. Аудит-лог в stdout: ключ (первые 6 символов хеша), инструмент, проект, виртуальный путь, статус, время. Содержимое файлов не логируется.

Рекомендации по эксплуатации: запускать под отдельным пользователем с правами только на чтение нужных каталогов, в Docker монтировать данные как :ro, ключи хранить в .env (в YAML — только ${VAR}).

Тесты

npm test (node --test) поднимает временное дерево-песочницу и проверяет модель безопасности: обход каталогов, абсолютные пути, симлинк наружу, dotfile/ключевой материал, неразрешённое расширение, превышение размера, бинарный файл, глубину обхода, изоляцию ключей и трансляцию glob.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    A read-only MCP server for code reading with intelligent caching, line-range selection, and language detection, enabling AI assistants to efficiently and safely explore file systems.
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    A read-only MCP server that enables AI assistants to search files, list directories, retrieve system info, and get file metadata on the local file system.
    4
    -