Skip to main content
Glama
BigTolly

mcp-local-access

by BigTolly

Languages: Русский | English

MCP (Local Access)

MCP-сервер позволяет облачным сервисам с поддержкой MCP, например Notion AI. Предоставлять доступ к одной папке на вашем компьютере: читать файлы, искать по ним, править, создавать и удалять, а также запускать разрешённые команды.

MCP сервер — это «руки», облачный сервис — «мозг». Вместо копирования кода в чат и обратно, MCP позволяет работать с файлами на ПК.

Зачем это нужно

  • Чат с ИИ видит реальный проект, а не пересказ: точные файлы, точные строки.

  • Правки применяются сразу в файлы, с диффом в ответе.

  • Рамки задаёте вы: одна корневая папка, список запрещённых путей, белый список команд, при желании — режим «только чтение».

Статус. Версия разработана для Windows и MacOS, но реально протестирована только на Windows; ветки для macOS/Linux написаны, но не проверены.

Popup


Содержание

  1. Как это работает

  2. Структура проекта

  3. Требования

  4. Установка

  5. Настройка

  6. Запуск и публикация

  7. Подключение клиента

  8. Инструменты

  9. Rules.md — путеводитель по проекту

  10. Права доступа

  11. Лимиты

  12. Безопасность

  13. Диагностика

  14. FAQ


Related MCP server: mcp-local-files

1. Как это работает

Notion AI / claude.ai / chatgpt
        │  HTTPS + Bearer-токен
        ▼
cloudflared-туннель  или  свой web сервер с TLS
        │  HTTP внутри локальной сети
        ▼
server.py  (слушает host:port, отдаёт /mcp)
        │  все пути проверяются: песочница + права
        ▼
rootDir — единственная папка, к которой есть доступ

Стек: Python + MCP SDK для Python (FastMCP) + uvicorn, транспорт Streamable HTTP на пути /mcp, авторизация Bearer-токеном. Сервер ничего не знает о способе публикации: он просто слушает host:port, а как этот порт оказался в интернете — дело туннеля или прокси.

2. Структура проекта

Путь

Что это

server.py

весь сервер: конфиг, песочница путей, права, инструменты, авторизация

config.json

файл настроек, создайте его из config.example.json

config.example.json

шаблон настроек

.env

файл хранит токен MCP_TOKEN, который генерируется при первом запуске server.py

requirements.txt

три зависимости: mcp, uvicorn, python-dotenv

README.md

этот файл

Rules.md

базовые инструкции для ИИ, чтобы ИИ знал минимальный контекст по вашему проекту

logs/ (внутри rootDir)

cmd-NNN.log — вывод команд, audit.log — журнал действий, processes.json — реестр процессов

3. Требования

  • Python 3.10 или новее (python --version).

  • Способ отдать локальный порт наружу по HTTPS — одно из двух:

    • cloudflared, если своего веб сервера нет:

      • Windows: winget install Cloudflare.cloudflared

      • macOS: brew install cloudflared

    • свой обратный прокси с TLS (на базе Nginx, Caddy, Traefik) перед этим портом.

При первом запуске server.py, сам генерирует токен, установка для cloudflare для этой задачи не нужна, он сам сам cloudflared.

4. Установка

cd local-access
python -m venv .venv

# Windows
.venv\Scripts\activate

# macOS / Linux
source .venv/bin/activate

pip install -r requirements.txt

5. Настройка

Все настройки лежат в config.json. Скопируйте шаблон и поправьте:


# Windows
copy config.example.json config.json

# macOS / Linux
cp config.example.json config.json
{
  "rootDir": "C:/usr/mcp/local-access",
  "host": "0.0.0.0",
  "port": 8000,
  "readOnly": false,
  "jsonResponse": false,
  "rulesFile": "Rules.md",
  "logDir": "logs",
  "audit": true,
  "maxCommandTimeout": 600,
  "permissions": { "...": "см. раздел 11" }
}

Ключ

Значение

rootDir

Единственная папка, к которой сервер имеет доступ. Всё вне неё отклоняется. Обязательный параметр.

host

Интерфейс для прослушивания. По умолчанию 0.0.0.0 — годится и для туннеля на этой машине, и для прокси на другом хосте. 127.0.0.1 — принимать только локальные подключения.

port

Локальный порт; туннель или прокси смотрит сюда. По умолчанию 8000.

readOnly

true отключает edit_file, multi_edit, create, delete, move и run_command.

jsonResponse

true нужен только клиенту, который не умеет SSE-ответы.

rulesFile

Путь к файлу-путеводителю для модели. Необязательный, см. раздел 10.

logDir

Папка внутри rootDir для логов команд и журнала действий. По умолчанию logs.

audit

false выключает logs/audit.log. По умолчанию true.

maxCommandTimeout

Верхняя граница timeout для run_command, в секундах. По умолчанию 600.

permissions

Правила по путям и командам, см. раздел 11.

В .env — только секретный токен:

# Windows
copy .env.example .env

# macOS / Linux
cp .env.example .env

Оставьте MCP_TOKEN пустым: при первом запуске сервер сгенерирует токен и запишет его в эту же строку. Чтобы сменить токен, очистите значение и перезапустите сервер.

6. Запуск и публикация

Нужны два терминала.

Терминал 1 — сервер:

python server.py

Он печатает эндпоинт, токен и действующие правила:

  local-mcp v0.1
  root      : C:\usr\mcp\my-project
  endpoint  : http://0.0.0.0:8000/mcp
  token     : 3f8c1d...
  read-only : no
  rules     : C:\usr\mcp\local-mcp-v0.1\Rules.md
  logs      : C:\usr\mcp\my-project\logs (audit.log: last 300 lines)
  processes : adopted 1, cleaned 4 old log(s)
  config    : C:\usr\mcp\local-mcp-v0.1\config.json
  perms     : defaultMode allow
    allow : List(**), Read(**), Edit(**), Create(**), Delete(**)
    deny  : *(**/.env), *(**/.env.*), *(**/config.json), *(**/secrets/**)
    run   : Run(npm run dev), Run(npm run build), Run(git status)

  WARNING: the server is listening on the whole local network.
  For a tighter setup set "host": "127.0.0.1" in config.json.

Вариант A — быстрый туннель cloudflared

Терминал 2:

cloudflared tunnel --url http://localhost:8000 --protocol http2

После запуска в терминале можно увидеть публичный адрес:

Requesting new quick Tunnel on trycloudflare.com... +--------------------------------------------------------------------------------------------+ | Your quick Tunnel has been created! Visit it at (it may take some time to be reachable): | | https://verbal-univ-silent-bracelet.trycloudflare.com | +--------------------------------------------------------------------------------------------+

В данном случае это https://verbal-univ-silent-bracelet.trycloudflare.com. Обратите внимание, что после каждого запуска url адрес меняется.

  • --protocol http2 заставляет туннель работать по TCP вместо QUIC/UDP. Без этого флага соединение может отваливаться с timeout: no recent network activity, а запросы — падать с ошибкой Cloudflare 1033.

  • Туннель не нужно перезапускать вместе с сервером: он пробрасывает localhost:8000, и пока порт тот же, публичный адрес продолжает работать. Перезапуск нужен, только если вы поменяли port или туннель сам умер.

  • Адрес быстрого туннеля меняется при каждом старте cloudflared — значит, URL в клиенте придётся обновлять.

Вариант B — использование веб сервер перед сервером (постоянный адрес)

Для этого варианта нужно иметь:

  • статический внешний IP-адрес

  • веб сервер с TLS, на котором можно настроить обратный прокси

  • домен, при этом для mcp можно использовать домен третьего уровня

  • получить сертификат для работы https

В config.json:

  • "host": "0.0.0.0" — значение по умолчанию и то, что нужно прокси: на 127.0.0.1 сервер доступен только с этой машины.

  • "port": 8000 — или любой свободный порт, на который смотрит прокси.

  • После правки файла перезапустите server.py и проверьте строку endpoint.

На хосте с прокси нужен только location /mcp — публичный путь это дело прокси, сервер всегда отдаёт /mcp. Пример настройки обратного прокси на Nginx:

server {
    listen 443 ssl;
    server_name mcp.example.com;

    location /mcp {
        proxy_pass http://192.168.1.50:8000/mcp;   # машина, где запущен server.py
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_buffering off;              # SSE должен стримиться, а не буферизоваться
        proxy_request_buffering off;
        proxy_read_timeout 3600s;
        chunked_transfer_encoding on;
    }
}
  • Ключевые строки — proxy_buffering off и proxy_request_buffering off: транспорт стримит SSE, и буферизующий прокси подвешивает каждый ответ до таймаута.

  • Заголовок Authorization проходит без изменений, токен доезжает как есть.

  • Сервер сам переписывает заголовок Host, так что защита SDK от DNS-rebinding не требует дополнительных заголовков (ошибки 421 не будет).

  • TLS терминируется на прокси, до сервера идёт обычный HTTP внутри локальной сети.

Адрес после этого постоянный: https://mcp.example.com/mcp вводится в клиент один раз и переживает перезапуски и сервера, и прокси.

7. Подключение клиента

Notion (Settings → Connections → добавить MCP-сервер):

  • URL: https://ваш-адрес/mcp — суффикс /mcp обязателен

  • Аутентификация: Bearer-токен, префикс Bearer, сам токен — из терминала 1

8. Инструменты

Все пути в аргументах — относительные, от rootDir. Абсолютные пути отклоняются, как и симлинки, ведущие за пределы корня.

Путеводитель

Инструмент

Что делает

project_guide()

Возвращает Rules.md: контекст проекта и правила работы

Тот же текст автоматически дописывается к первому результату инструмента в диалоге, так что обычно вызывать его не нужно.

Файлы

Инструмент

Что делает

list_files(path, recursive, max_depth)

Листинг папки; recursive включает вложенные

read_file(path, offset, limit)

Файл с номерами строк, постранично для больших файлов

search_text(pattern, path, glob, regex, case_sensitive, context, max_results)

Поиск по проекту, отдаёт путь:строка: текст

file_info(path)

Размер, число строк, время изменения, текст или бинарник

edit_file(path, old_string, new_string, replace_all)

Точная замена, возвращает дифф

multi_edit(path, edits, regex)

Несколько замен в одном файле, всё или ничего

create(path, type, content, overwrite)

Новый файл или папка

move(source, destination, overwrite)

Переименование или перемещение

delete(path, recursive)

Безвозвратное удаление файла или папки

  • Шумные папки (node_modules, .git, dist, build, .venv, venv, __pycache__, .next, .idea) при листинге и поиске пропускаются всегда.

  • У delete нет корзины: непустая папка требует recursive=true, сам корень удалить нельзя, а папка, внутри которой лежит запрещённый правилами файл, не удаляется целиком.

  • move требует прав Delete на источник и Create на приёмник, поэтому защищённый файл нельзя вынести из-под защиты переносом.

  • Один файл не стоит править двумя вызовами одновременно: edit_file и multi_edit читают и пишут файл целиком, параллельные вызовы затирают друг друга.

Команды

Инструмент

Что делает

run_command(command, cwd, timeout, background, wait_for, idle_timeout, restart)

Запускает команду внутри rootDir

list_processes()

Всё, что запущено в этой сессии: живое и завершённое

check_process(id, lines, wait, wait_for)

Состояние и свежий вывод одного процесса

stop_process(id, stop_all)

Убивает процесс вместе с детьми

  • Команды идут через системный шелл, поэтому &&, ||, | и ; работают. Каждое звено цепочки проверяется по правилам Run(...) отдельно, команда без подходящего правила отклоняется.

  • Команда должна быть одной строкой: перевод строки — разделитель команд, так что многострочная строка выполнилась бы лишь частично. Склеивайте шаги через && или положите их в скрипт.

  • background=false (по умолчанию) — для команд, которые завершаются: вызов возвращает код выхода и вывод, процесс после этого гарантированно мёртв. По таймауту убивается всё дерево процессов.

  • background=true — для долгоживущих команд вроде npm run dev. Процесс живёт после вызова; когда вернуть управление, решают wait_for (регулярное выражение) или idle_timeout, например wait_for: "ready in|listening on".

  • Вывод стримится в logs/cmd-NNN.log, а не держится в памяти, так что шумная сборка не разорвёт ответ. Длинный вывод возвращается началом и хвостом.

  • Каждый запущенный процесс отслеживается, и короткий блок [processes] дописывается к любому результату инструмента, пока что-то работает или только что завершилось:

[processes]
  #1 running   npm run dev  (pid 24188, 96s, log logs/cmd-001.log)
  #2 exited (exit 0)  npm run build  (log logs/cmd-002.log)

Так модель остаётся в курсе терминала: MCP-сервер не может сам прислать уведомление внутрь хода модели, поэтому состояние заново подкладывается контекстом при следующем вызове.

  • Запуск команды, которая уже работает, отклоняется со ссылкой на её номер; restart=true сначала останавливает старый процесс.

  • Вывод принудительно переводится в UTF-8 (chcp 65001 на Windows, PYTHONIOENCODING, NO_COLOR), чтобы логи не превращались в кракозябры.

  • Процессы убиваются деревом (taskkill /T на Windows, целая группа процессов на macOS/Linux, сначала SIGTERM, потом SIGKILL), потому что порт держит не npm, а его дочерний node.

  • При выходе сервера все запущенные процессы останавливаются, так что Ctrl+C не оставляет висящих dev-серверов.

  • Реестр процессов дублируется в logs/processes.json. Жёсткое убийство сервера (закрытая консоль, диспетчер задач) не выполняет очистку и оставляет детей живыми, поэтому при старте каждая запись сверяется с ОС: живой pid подхватывается обратно в реестр и показывается как running (adopted), остальное считается завершённым, а их cmd-NNN.log удаляются. Номера продолжают расти, поэтому имена логов не конфликтуют. Подхваченный процесс можно смотреть и останавливать как обычно — теряется только точный код выхода, потому что сервер больше не владеет его хэндлом.

Журнал действий

При "audit": true каждая команда, перемещение и multi_edit дописываются в logs/audit.log:

2026-09-15 03:40:12 ok  run_command: #1 npm run dev (cwd .)
2026-09-15 03:41:02 ok  move: src/old.ts -> src/new.ts

Это ответ на вопрос «что модель на самом деле сделала» — полезно после долгой сессии или когда что-то сломалось, а диффа недостаточно. Добавьте logs/ в .gitignore.

Журнал — скользящий хвост, а не архив: он обрезается до последних 300 строк (AUDIT_KEEP_LINES в server.py) при старте и каждые 100 записей, поэтому расти бесконечно не может. Логи команд чистятся отдельно: при старте удаляется каждый logs/cmd-NNN.log, чей процесс не жив и не подхвачен.

9. Rules.md — краткое описание вашего проекта

Rules.md — (опционально) необязательный файл, кратко опишите свой проект, или можете указать путь к файлам документации по вашему проекту. Смысл простой — не объяснять модели детали о проекте в каждом новом диалоге.

  • Название файла и путь к этому файлу, можно изменить в переменной rulesFile в config.json. Если переменная не задана, то берется файл Rules.md, расположенный в папке указанной в rootDir.

  • Файл перечитывается при изменении, перезапуск не нужен: новый текст приходит со следующим результатом инструмента и в следующей сессии клиента.

11. Права доступа

Правила живут в блоке permissions файла config.json и записываются в стиле Claude Code: Инструмент(glob-путь).

{
  "permissions": {
    "defaultMode": "allow",
    "allow": ["List(**)", "Read(**)", "Edit(**)", "Create(**)", "Delete(**)"],
    "deny": [
      "*(**/.env)",
      "*(**/.env.*)",
      "*(**/config.json)",
      "*(**/secrets/**)",
      "*(**/*.pem)",
      "*(**/*.key)",
      "Edit(**/.git/**)",
      "Create(**/.git/**)",
      "Delete(**/.git/**)"
    ]
  }
}
  • Глаголы: List, Read, Edit, Create, Delete, Run или * для всех путевых глаголов. Соответствие инструментам: List и Read вместе определяют, что показывает list_files; Read покрывает ещё search_text и file_info; Edit покрывает multi_edit; Createcreate и приёмник move; Deletedelete и источник move.

  • Run стоит особняком: его аргумент — шаблон команды, а не путь, поэтому *(**) его никогда не выдаёт. См. «Правила для команд» ниже.

  • defaultMode: "allow" — разрешено всё, что не запрещено (чёрный список).

  • defaultMode: "deny" — работают только пути из allow (белый список).

  • deny всегда сильнее allow.

  • Шаблоны задаются относительно rootDir, разделитель — /, поддерживаются * (один сегмент), ** (любая глубина) и ? (один символ).

  • Шаблоны привязаны к корню, поэтому .env совпадает только с файлом в корне. Чтобы накрыть все подпапки, нужен префикс **/**/.env.

  • secrets/** скрывает и саму папку secrets.

  • Запрещённые элементы не показываются в list_files, вместо них выводится число скрытых записей.

  • Если блока permissions нет, действуют встроенные значения: разрешено всё, кроме **/.env, **/.env.*, **/secrets/**, **/*.pem, **/*.key, плюс запрет записи и удаления внутри **/.git/**.

  • Правила читаются при старте — после правки перезапустите сервер.

  • *(**/config.json) доступ к файлу закрыт для модели, чтобы не переписала собственные права.

Правила для команд

Команды — всегда белый список. Run(...) принимает шаблон команды, где * означает любой текст; всё остальное сравнивается буквально, пробелы сжимаются, регистр игнорируется. Если ни одного правила Run нет, run_command отказывает во всём.

{
  "permissions": {
    "allow": [
      "Run(npm run dev)",
      "Run(npm run build)",
      "Run(npm install)",
      "Run(git status)",
      "Run(git diff*)",
      "Run(python *)",
      "Run(pytest*)"
    ],
    "deny": ["Run(*rm -rf*)"]
  }
}
  • Цепочка разбивается по &&, ||, |, ; и переводам строк, и каждый сегмент должен сам совпасть с правилом из allow. Для npm run build && git status нужны оба правила; npm run build && rm -rf / упадёт на втором сегменте.

  • Разбиение учитывает кавычки, поэтому git commit -m "fix | bug" — один сегмент.

  • deny и здесь сильнее, а defaultMode: "allow" на команды не распространяется.

Насколько это обеспечивает безопасность. Не сильно, и это осознанный компромисс. Белый список спасает от случайностей и опечаток, а не от целенаправленной атаки: одного разрешённого python * или npm run * достаточно, чтобы сделать всё, что может обычная программа, включая выход за rootDir — песочница путей ограничивает только файловые инструменты, но никогда не дочерний процесс. Держите список коротким и конкретным и относитесь к запуску команд как к «я доверяю этому клиенту свою учётную запись», а не как к песочнице.

Пример белого списка: читать только src и Markdown, писать только в src/generated:

{
  "permissions": {
    "defaultMode": "deny",
    "allow": ["List(src/**)", "Read(src/**)", "Read(*.md)", "Create(src/generated/**)", "Edit(src/generated/**)"]
  }
}

11. Лимиты

Зашиты в server.py (константы в начале файла), меняются правкой кода:

Лимит

Значение

Размер одного ответа

100 000 символов, дальше обрезка

Чтение/запись содержимого файла

1 МБ

Записей в листинге

1000

Таймаут синхронной команды

60 с по умолчанию, максимум — maxCommandTimeout (600 с)

Ожидание фоновой команды

idle_timeout 15 с по умолчанию

Одновременно фоновых процессов

8

Вывод команды в одном ответе

20 000 символов

Завершённый процесс в реестре

10 минут

audit.log

последние 300 строк

Rules.md

20 000 символов

12. Безопасность

  • Любой, у кого есть публичный URL и токен, может читать, менять и удалять внутри rootDir — всё, что не закрыто правилами deny.

  • run_command — самая широкая дыра: дочерний процесс не связан песочницей путей, поэтому разрешённые python *, node * или npm run * могут добраться до всего, до чего дотягивается ваша учётная запись. Держите список Run коротким.

  • Останавливайте фоновые процессы, когда закончили (stop_process(stop_all=true)); остановка сервера по Ctrl+C убивает их тоже. Жёсткое убийство — нет, но при следующем старте живые процессы подхватываются обратно.

  • Выключайте туннель, когда он не нужен.

  • Токен меняется так: очистить MCP_TOKEN в .env и перезапустить сервер.

  • rootDir держите настолько узким, насколько позволяет задача: родительская папка втягивает в песочницу и сам этот проект вместе с его .env.

Если нужно строже: включите подтверждение вызовов на стороне клиента, сузьте rootDir, поставьте "readOnly": true или уберите все правила Run.

13. Диагностика

Симптом

Причина

rootDir is not set

Нет config.json или в нём не задан rootDir

401 от клиента

Токен не совпадает или заголовок называется не Authorization

421 Invalid Host header

Старый server.py без перезаписи Host

406 Not Acceptable

Клиент не отправил заголовок Accept, показанный в разделе 8

Cloudflare 1033

Туннель потерял соединение; перезапустите с --protocol http2

Клиент не видит инструментов

В URL нет суффикса /mcp

Новый инструмент не появился

Клиент закэшировал старый список; переподключите коннектор

Ответы подвешиваются до таймаута

Прокси буферизует SSE: proxy_buffering off

Permission denied

Путь совпал с правилом deny в config.json

Permission denied: Run(...)

Ни одно правило Run не подошло команде или звену цепочки

Already running as #N

Та же команда ещё жива: посмотрите её, остановите или передайте restart=true

Timed out after Ns

Долгоживущая команда запущена без background=true

command must be a single line

Переводы строк разделяют команды; склейте шаги через &&

Absolute paths are not allowed

Так и задумано: пути относительны rootDir

14. FAQ

А что если я хочу несколько rootDir?

Один процесс — один корень, это основа песочницы. Варианты:

  • Указать общую родительскую папку и сузить доступ правами, например List(project-a/**), Read(project-a/**), Edit(project-a/**) и то же для project-b. Просто и работает, но всё лежит в одной песочнице.

  • Запустить второй экземпляр сервера со своим конфигом и портом: путь к конфигу берётся из переменной CONFIG_FILE, а порт — из самого конфига.

    CONFIG_FILE=/path/to/config-b.json python server.py     # macOS / Linux
    set CONFIG_FILE=C:\path\to\config-b.json && python server.py   # Windows

    Каждому экземпляру нужен свой публичный адрес (второй туннель или второй location в Nginx) и своё подключение в клиенте. Токен берётся из .env рядом с server.py, так что для разных токенов нужны разные копии проекта.

Обязателен ли cloudflared?

Нет. Нужен любой способ отдать порт наружу по HTTPS: свой Nginx/Caddy/Traefik, именованный туннель Cloudflare, любой другой туннель. Сервер о нём ничего не знает.

Можно ли обойтись без публикации наружу?

Notion и claude.ai работают через интернет, им нужен публичный HTTPS-адрес. Локальные клиенты (Cursor и другие, запущенные на этой же машине) могут подключаться прямо к http://127.0.0.1:8000/mcp — тогда поставьте "host": "127.0.0.1".

Может ли модель выйти за пределы rootDir?

Файловыми инструментами — нет: абсолютные пути отклоняются, .. разворачивается, симлинки наружу отбрасываются. Через run_command — да: дочерний процесс песочницей не ограничен. Если это неприемлемо, не давайте правил Run или включите readOnly.

Как вообще запретить любые изменения?

"readOnly": true — остаются только чтение, поиск и листинг. Промежуточный вариант: оставить Edit/Create на рабочую папку и запретить остальное через deny.

Нужен ли Rules.md?

Нет, сервер работает и без него. Но с ним не приходится в каждом новом диалоге объяснять, что это за проект и как в нём принято работать. См. раздел 9.

Работает ли это на macOS и Linux?

Код есть (/bin/sh, start_new_session, убийство группы процессов), но проверен он только на Windows. Считайте первый запуск на macOS/Linux тестовым.

Модель удалила нужный файл — как откатить?

Никак средствами сервера: корзины нет, удаление безвозвратное. Держите проект под git, а в logs/audit.log можно посмотреть, что именно произошло. Рекомендуется настроить запуск бекапа проекта перед каждой новой задачей.

Почему клиент спрашивает подтверждение на каждый вызов?

Это поведение клиента, сервер на него не влияет. В Notion подтверждения настраиваются в свойствах подключения; права сервера работают независимо от того, что вы нажали.

Токен утёк. Что делать?

Очистить значение MCP_TOKEN в .env, перезапустить сервер (он сгенерирует новый токен), вписать новый токен в клиента. Старый перестаёт работать сразу.

Почему logs/ внутри rootDir, а не рядом с сервером?

Чтобы модель могла сама прочитать вывод команды через read_file. Побочный эффект: добавьте logs/ в .gitignore.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables secure remote access to your computer's filesystem and terminal through MCP, allowing AI assistants to manage files, run commands, and automate tasks from anywhere via a hosted relay.
    37
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables Claude Desktop or other MCP clients to execute shell commands, read/write files, and list directories on the local machine. Includes basic safety guardrails to block obviously destructive operations.
    -