Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Local Mcp Easy

FreeNot checked

Local developer MCP server with Streamable HTTP, OAuth 2.1, filesystem tools, commands and Git repository context.

GitHubEmbed

About

Local developer MCP server with Streamable HTTP, OAuth 2.1, filesystem tools, commands and Git repository context.

README

CI Release License: MIT Python Tests

Локальные файловые инструменты, команды и Git через MCP — по Streamable HTTP с OAuth 2.1.

One-click MCP-сервер для Windows: агент получает безопасные инструменты для чтения, поиска и изменения файлов в выбранной рабочей папке. Отдельно включается доверенный developer-режим (Python, Git, Node) с защитным git setup-flow. Стабильный публичный адрес — через зарезервированный Serveo hostname, собственный домен за обратным прокси или self-hosted sish-туннель (см. SISH_SETUP.md и REVERSE_PROXY.md). На Linux/macOS вместо .bat используйте .sh-обёртки (./setup.sh, ./start.sh, …).

Совместим с Hyperagent, Notion и другими MCP-клиентами.

Режимы авторизации

  • dual — Bearer token и OAuth 2.1 одновременно на одном /mcp (по умолчанию с 2.1.0);
  • oauth — только OAuth 2.1 с Dynamic Client Registration и PKCE (S256) для любых OAuth MCP-клиентов;
  • legacy — только статический Bearer token (классическое поведение 1.x).
Клиент со статическим токеном ── Bearer ─┐
                                         ├─ /mcp → общий набор MCP-инструментов
OAuth-клиент ────────── OAuth 2.1 ───────┘

Проект предназначен для собственного компьютера и доверенного агента. Это не многопользовательский публичный сервис.

Запуск за несколько минут

  1. Распакуйте архив в любую папку.
  2. Дважды кликните START.bat.
  3. При первом запуске выберите рабочую папку.
  4. Оставьте trusted developer mode выключенным, если нужны только файловые инструменты. Для написания и запуска кода его можно включить ответом y.
  5. Подключите клиента: для статического токена (например, Notion Custom MCP) скопируйте показанные URL и Bearer token; для OAuth-клиента (например, Hyperagent) запустите OAUTH_SETUP.bat, выберите dual или oauth и добавьте URL сервера в клиент — дальше DCR и страница /consent с owner-кодом.
  6. Не закрывайте окно запуска во время работы.

При последующих запусках повторная настройка не требуется. Конфигурация хранится в %LOCALAPPDATA%\LocalMcpEasy и не входит в архив проекта (настройки из старого каталога NotionMcpEasy переносятся автоматически при первом запуске 2.0). Начиная с 1.4.2 список быстрых переключений между рабочими областями хранится в %LOCALAPPDATA%\LocalMcpEasy\connections.cfg: при MENU = on сервер показывает сохранённые пути и меняет только текущий workspace в config.json, не пересоздавая токен. При stable Serveo hostname адрес MCP сохраняется; в temporary mode после перезапуска URL меняется и его нужно обновить в клиенте.

Управление

  • START.bat — создать локальное .venv, установить зависимости и запустить сервер с туннелем. Если connections.cfg содержит MENU = on, перед стартом появится меню сохранённых рабочих областей.
  • STOP.bat — остановить только процессы этого MCP после проверки их идентичности.
  • SETUP.bat — заново пройти мастер настройки; токен при повторном setup сохраняется, а выбранная рабочая область попадает в connections.cfg.
  • SHOW_CONNECTION.bat — показать текущие URL, workspace и режимы; токен и OAuth owner code маскируются, --full показывает их полностью.
  • OAUTH_SETUP.bat — выбрать режим авторизации legacy / oauth / dual и сгенерировать OAuth owner code.
  • REGISTER_OAUTH_CLIENT.bat — заранее зарегистрировать OAuth-клиент для режима «Bring my own OAuth app».
  • DOCTOR.bat / ./doctor.sh (2.4.0) — диагностика сломанной установки одной командой: версия Python, зависимости, config, токен, workspace, режим авторизации, owner code, tunnel backend, наличие ssh и git, занят ли порт. Возвращает ненулевой код, если что-то сломано.
  • launcher.py --add-command ИМЯ / --remove-command ИМЯ — безопасно изменить список разрешённых команд без ручной правки JSON (ручная правка с BOM/лишней запятой раньше сбрасывала настройку — теперь launcher останавливается с понятной ошибкой и ничего не перезаписывает).

connections.cfg

Пользовательский файл %LOCALAPPDATA%\LocalMcpEasy\connections.cfg создаётся автоматически и содержит:

  • MENU = on/off — показывать ли меню выбора рабочей области при старте;
  • PATH[1] ... PATH[9] — стартовые слоты для сохранённых путей;
  • дополнительные слоты PATH[10], PATH[11] и дальше можно добавлять вручную или через меню, если базовые места заняты.

Когда меню включено, запуск показывает только занятые слоты и предлагает:

  • выбрать сохранённую рабочую область по номеру;
  • нажать 0, чтобы задать новую папку и сохранить её в свободный слот;
  • нажать q, чтобы отключить меню и оставить последнюю выбранную область в config.json.

Все подсказки во время запуска сообщают точные пути к connections.cfg и config.json. Файл connections.example.cfg в архиве служит только шаблоном и не содержит пользовательских путей.

Режимы

File-only mode — по умолчанию

Файловые инструменты разрешены только внутри выбранного workspace. Пути нормализуются, а выход через .., абсолютные пути и ссылки наружу отклоняется.

Trusted developer mode — опционально

Добавляет запуск разрешённых программ без cmd.exe и PowerShell:

python, py, pip, git, node, npm, npx, pytest, ruff, make, uv

Это не песочница. Python, Node, Git hooks, npm scripts и другие инструменты могут обращаться ко всей системе и сети с правами текущего пользователя Windows. Включайте режим только для личного доверенного агента.

С 2.4.0 аргументы к .cmd/.bat-программам (на Windows это npm и npx) отклоняются, если содержат метасимволы & | < > ^ " % !: Windows запускает batch-файлы через cmd.exe, который заново разбирает командную строку, поэтому npm с аргументом --version&whoami выполнял whoami в обход allow-list — при shell=False и argv списком (BatBadBut, тот же класс, что CVE-2024-24576).

Read-only mode — опционально (2.4.0)

MCP_READ_ONLY=1 вообще не регистрирует изменяющие инструменты: их нет в list_tools(), и до них не может дойти ни один запрос. Гарантия структурная, а не «проверка scope сработает». Подходит, чтобы дать агенту посмотреть рабочую папку через туннель, ничего не рискуя.

Аудит вызовов (2.4.0)

MCP_AUDIT_LOG=<путь> пишет по одной JSON-строке на каждый вызов инструмента — время, OAuth client_id, имя инструмента, именованные аргументы (обрезанные) и результат ok/error. Сервер, доступный из интернета и умеющий запускать команды, обязан оставлять след; больше это нигде не фиксировалось. Секреты в лог не попадают, а сбой записи никогда не ломает сам вызов.

{"ts":"2026-07-26T14:02:11+00:00","client":"mcp_client_a1b2","tool":"run_command","outcome":"ok","args":{"args":"['test']","cwd":".","program":"pytest"}}

Скилы и память (2.5.0)

Две вещи, которые обычно есть у автономного агента, но не у MCP-сервера: библиотека многоразовых процедур и память, переживающая сессию. Здесь их получает любой подключённый MCP-клиент, а не один конкретный агент.

Обе подсистемы едут в клиент через поле instructions MCP-ответа на initialize — единственный штатный канал сервера в системный промпт модели. Всё остальное клиенту пришлось бы вытягивать вызовом инструмента, о котором он должен догадаться.

Скилы

Скил — папка с SKILL.md: YAML-frontmatter плюс markdown-инструкции. Формат — переносимое ядро спецификации agentskills.io (name, description, license, compatibility, metadata), без расширений, специфичных для конкретного клиента, так что тот же скил читается и в Claude Code.

%LOCALAPPDATA%\LocalMcpEasy\skills\<имя>\SKILL.md   ← личные, доступны в любой рабочей папке
<workspace>\.mcp-skills\<имя>\SKILL.md              ← скилы проекта, только здесь
---
name: release-notes
description: >
  Собирает changelog из git diff, группируя по типу изменения.
  Использовать, когда просят release notes или саммари PR для пользователей.
license: MIT
---

# Release notes

1. `git diff <base>..<head>`
2. Разложить на Added / Changed / Fixed / Removed.
3. Один пункт на логическое изменение, языком пользователя.

Полная спецификация — в [references/format.md](references/format.md).

Раскрытие трёхуровневое, чтобы большая библиотека не съедала контекст:

  1. Всегда — только имя: описание, одна строка на скил, в instructions и в skills_list().
  2. По требованию — тело SKILL.md, через skill_view(name).
  3. Отдельноreferences/, scripts/, assets/ не инлайнятся даже на втором уровне: в конце тела появляется их список и подсказка skill_view(name, file_path=...).

Скил — это инструкции, которым модель следует, то есть граница доверия, а не данные. Отсюда два следствия, оба проверяются тестами: личный скил всегда побеждает одноимённый скил из рабочей папки (рабочую папку может писать любой клиент с mcp:files:write, так что обратный приоритет был бы повышением привилегий), а скил из рабочей папки помечается [workspace] везде, где отображается. Скил ничего не исполняет: он может попросить модель что-то запустить, и это пойдёт через run_command с его allow-list, как любая другая команда.

Память

Два плоских файла в %LOCALAPPDATA%\LocalMcpEasy\memory\: MEMORY.md — что агент узнал про окружение и работу, USER.md — что узнал про человека. Записи разделены строкой §. Ни базы, ни эмбеддингов: recall здесь означает «весь стор целиком показан модели», так что ранжировать нечего — индекс добавил бы зависимость, шаг сборки и точку отказа ради запроса, которого никогда не будет.

Ограничение — в символах, не в записях (2200 для MEMORY.md, 1375 для USER.md). Лимит на количество позволил бы одной пространной записи вытеснить десять полезных, а символьный управляет тем, что реально дефицитно, — местом в контексте. Запись сверх бюджета отклоняется и возвращает текущее содержимое, чтобы модель сократила и повторила; молча обрезать нельзя — так теряются записи.

Стор лежит вне рабочей папки, поэтому до него не дотягивается ни один файловый инструмент: изменить память можно только через memory_write, а значит каждое изменение проходит проверку scope.

Инструмент Scope Что делает
skills_list() mcp:files:read индекс скилов
skill_view(name, file_path="") mcp:files:read тело скила или его вспомогательный файл
memory_read(target="all") mcp:files:read текущая память с указанием бюджета
memory_write(action, content, target, old_text) mcp:files:write add / replace / remove

Новых OAuth-scope не появилось намеренно: уже выданные токены продолжают работать, а в MCP_READ_ONLY=1 инструмент memory_write просто не регистрируется.

Переменные окружения (выборочно)

Переменная По умолчанию Назначение
MCP_READ_ONLY 0 1 — изменяющие инструменты не регистрируются вовсе
MCP_AUDIT_LOG (пусто) путь к append-only JSONL-журналу вызовов
MCP_SKILLS_DIR <config>\skills папка личных скилов
MCP_MEMORY_DIR <config>\memory папка стора памяти
MCP_MEMORY 1 0 — выключить память целиком
MCP_MEMORY_CHAR_LIMIT 2200 бюджет MEMORY.md в символах
MCP_USER_CHAR_LIMIT 1375 бюджет USER.md в символах
MCP_ALLOW_COMMANDS 0 1 — включить trusted developer mode
MCP_ALLOWED_COMMANDS см. список выше allow-list программ через запятую
MCP_MAX_COMMAND_JOBS 4 сколько фоновых команд может идти параллельно
MCP_MAX_COPY_MOVE_BYTES 100 МБ потолок для copy_file / move_file
MCP_TEMP_FILE_TTL 86400 сколько живут временные файлы @temp/

Архитектура

Notion ─────── static Bearer ─┐
                              ├─ /mcp → общий набор MCP-инструментов
Hyperagent ── OAuth 2.1 ──────┘
    -> HTTPS (Serveo SSH reverse tunnel)
    -> 127.0.0.1:8765
FastMCP server
    -> выбранный workspace

Сервер слушает только localhost. В режиме legacy все HTTP-маршруты, включая /health, требуют токен — поведение линии 1.x без изменений. В режимах oauth/dual endpoint /mcp защищён проверкой токена per-request (legacy и/или OAuth), discovery-маршруты OAuth публичны по спецификации, а /health принимает операторский токен запуска. FastMCP Host-проверка отключена намеренно: Serveo выдаёт случайное публичное имя, которое иначе приводило бы к HTTP 421; вместо неё работает собственный Host-allowlist.

Serveo — сторонний туннель. В быстром анонимном режиме URL меняется после перезапуска. Если в Serveo зарезервировать hostname и добавить SSH-ключ, мастер включает stable mode: адрес вида https://my-name.serveousercontent.com/mcp сохраняется после перезапусков и добавляется в клиент один раз. Для OAuth-режимов обязателен стабильный адрес: зарезервированный hostname или собственный домен через public_url (тогда Serveo не используется — маршрутизацию делает ваш reverse proxy).

Universal OAuth (Hyperagent и другие MCP-клиенты)

Режимы авторизации

dual    — Bearer token И OAuth одновременно на одном /mcp (по умолчанию с 2.1.0)
oauth   — только OAuth 2.1 (Hyperagent); Bearer-токен работает лишь на /health
legacy  — только статический Bearer token (например Notion, как в линии 1.x)

Режим выбирается через OAUTH_SETUP.bat и хранится в config.json. Новые установки по умолчанию используют dual, и SETUP.bat сам генерирует и печатает OAuth owner code — открытая DCR и подтверждение на /consent работают «из коробки» (регистрация сама по себе ничего не даёт: каждую авторизацию нужно одобрить owner-кодом). Апгрейд не меняет существующий конфиг: конфиг без auth_mode остаётся legacy. Набор MCP-инструментов, границы workspace, chunking и git-политика общие для всех режимов — меняется только слой авторизации.

Быстрое подключение Hyperagent

  1. В SETUP.bat настройте зарезервированный Serveo hostname (обязателен для чистого oauth; для dual — крайне желателен: без него OAuth-часть нестабильна, но сервер стартует с предупреждением).
  2. Запустите OAUTH_SETUP.bat, выберите dual (статический токен и OAuth одновременно) или oauth. Мастер сгенерирует OAuth owner code — код владельца для подтверждения подключений.
  3. Запустите START.bat.
  4. В Hyperagent: Add MCP server → Streamable HTTP → URL https://<hostname>.serveousercontent.com/mcp. Поле Advanced заполнять не нужно — сервер публикует discovery metadata.
  5. Если Bring my own OAuth app выключен, Hyperagent зарегистрируется сам через Dynamic Client Registration и откроет страницу подтверждения /consent.
  6. На странице /consent проверьте имя клиента и запрошенные права, введите OAuth owner code (показывается в окне запуска и через SHOW_CONNECTION.bat --full) и нажмите Approve.
  7. Если Bring my own OAuth app включен, сначала выполните REGISTER_OAUTH_CLIENT.bat: введите redirect URL из Hyperagent, получите client_id (для public PKCE-клиента secret не нужен) и внесите значения в Hyperagent. Дальше тот же /consent-флоу.

Интерстициал Serveo (бесплатный аккаунт). При первом заходе в браузере Serveo показывает одноразовую страницу «you are about to visit…» и при этом теряет query-параметры у ссылки /authorize. Если вместо /consent вы увидели ошибку вида client_id: Field required — это не сбой сервера: нажмите в браузере «Назад» и откройте ссылку авторизации ещё раз (или повторите Connect в клиенте) — предупреждение уже снято на эту сессию браузера, и откроется страница /consent. Сервер с 2.1.0 показывает на этот случай понятную страницу-подсказку вместо сырого JSON. Чтобы интерстициал не появлялся вовсе — используйте свой домен (public_url) или платный аккаунт Serveo с зарезервированным hostname.

Что реализовано

  • OAuth 2.1 Authorization Code Flow + PKCE (S256, единственный поддерживаемый метод);
  • Dynamic Client Registration (POST /register) и заранее зарегистрированные клиенты;
  • строгая проверка redirect_uri (https или локальный loopback) и передача state;
  • короткоживущие access-токены (1 час по умолчанию) с audience-привязкой к /mcp (RFC 8707);
  • refresh-токены с ротацией: старый refresh и связанные access-токены гаснут при каждом обновлении;
  • одноразовые authorization codes: повторное использование кода отзывает выданные по нему токены;
  • POST /revoke для отзыва токенов;
  • discovery: /.well-known/oauth-authorization-server (RFC 8414), /.well-known/oauth-protected-resource/mcp (RFC 9728, плюс root-алиас) и WWW-Authenticate с resource_metadata при 401.

Scopes

Scope Инструменты
mcp:files:read workspace_info, list_dir, file_info, read_file, tail_file, glob_files, grep_files, skills_list, skill_view, memory_read
mcp:files:write write_file, append_file, edit_file, create_dir, delete_file, copy_file, move_file, memory_write
mcp:commands:run run_command, start_command, get_command_status, cancel_command, list_commands (дополнительно требуется trusted developer mode)
mcp:git repo_context_status, inspect_git_repository, configure_repo_context, setup_git_context

Проверка scope выполняется перед каждым вызовом инструмента (deny-by-default: инструмент без известного scope не регистрируется). Токен только с mcp:files:read не может изменять файлы, запускать команды или трогать git.

Least-privilege по умолчанию. Клиент, который регистрируется без запроса конкретных scopes (в т.ч. через DCR без поля scope), получает только mcp:files:read + mcp:files:write. Мощные scopes нужно запрашивать явно.

⚠️ mcp:commands:run — это доступ уровня «почти вся система», а не workspace-scoped право. В trusted developer mode run_command запускает Python/Git/Node с правами пользователя ОС, и эти программы могут читать и менять файлы и ходить в сеть за пределами workspace, фактически обходя ограничения mcp:files:read/write/git. Выдавайте этот scope только полностью доверенному клиенту.

Легаси Bearer-токен остаётся мастер-токеном с полным доступом — это осознанное решение для личного сервера, учитывайте его при передаче токена.

Ограниченный (или, наоборот, расширенный) клиент создаётся через REGISTER_OAUTH_CLIENT.bat (укажите нужный поднабор scopes) или когда клиент сам запрашивает конкретный scope при регистрации/авторизации.

Стабильный URL для OAuth

При смене публичного URL меняются issuer, discovery-ссылки, redirect-конфигурация и audience уже выданных токенов, поэтому OAuth-часть требует стабильного адреса. С 2.1.0 политика такая: чистый oauth на нестабильном URL launcher блокирует (иначе рабочего способа авторизации не останется), а dual стартует с предупреждением — Bearer-токен работает сразу, а OAuth-часть станет стабильной, когда появится постоянный адрес. Разрешённые варианты дать стабильный URL:

  • зарезервированный Serveo hostname — launcher сам поднимает стабильный туннель;
  • свой стабильный домен / reverse proxy — задайте его в OAUTH_SETUP.bat (сохраняется как public_url). В этом режиме launcher НЕ поднимает Serveo: вы сами маршрутизируете https://ваш-домен/mcp на http://127.0.0.1:<port> своим прокси/туннелем. START.bat в этом случае просто запускает сервер и публикует ваш URL.

Для локальных экспериментов существует переменная MCP_OAUTH_ALLOW_TEMPORARY_URL=1 — с ней сервер работает на http://127.0.0.1:<port> без туннеля.

Защита от злоупотреблений

  • Consent без DoS на владельца. Правильный owner code принимается всегда, поэтому неверные попытки не могут «залочить» настоящего владельца. Неверные попытки ограничиваются per-transaction (после нескольких — транзакция сгорает, клиент начинает заново) и общим самозаживающим rolling-window rate limit, без глухой блокировки всей страницы.
  • DCR не переполняет диск. Реестр клиентов ограничен (MCP_OAUTH_MAX_CLIENTS, по умолчанию 100); зарегистрированные, но не завершившие авторизацию DCR-клиенты удаляются через MCP_OAUTH_UNUSED_CLIENT_TTL (по умолчанию 1 час); клиенты с живыми токенами и вручную зарегистрированные (BYO) не вытесняются.

Хранение OAuth-состояния

Файл %LOCALAPPDATA%\LocalMcpEasy\oauth_state.json содержит зарегистрированных клиентов и SHA-256 хеши access/refresh-токенов — сырые значения токенов на диск не пишутся. Файл не входит ни в git, ни в release-архив. Битый или отредактированный вручную файл (null-секции, мусор, неизвестная будущая версия схемы) не роняет запуск — сервер стартует с чистым состоянием. Благодаря этому файлу клиенты и refresh-токены переживают перезапуск сервера: при stable hostname Hyperagent переподключается без повторного подтверждения.

Переменные тонкой настройки: MCP_OAUTH_ACCESS_TTL (сек, по умолчанию 3600), MCP_OAUTH_REFRESH_TTL (по умолчанию 30 дней), MCP_OAUTH_MAX_CLIENTS (100), MCP_OAUTH_UNUSED_CLIENT_TTL (3600), MCP_OAUTH_CONSENT_MAX_ATTEMPTS (на транзакцию, 5), MCP_OAUTH_CONSENT_FAILURE_WINDOW_SECONDS (60), MCP_OAUTH_CONSENT_MAX_FAILURES (10), MCP_OAUTH_OWNER_GRANT_SCOPES (single-owner override, по умолчанию пуст), MCP_OAUTH_MAX_CLIENTS (100), MCP_OAUTH_UNUSED_CLIENT_TTL (3600).

Инструменты

  • workspace_info — workspace, активный режим, root repo и краткий обзор nested repo;
  • repo_context_status, inspect_git_repository — диагностика git и следующего безопасного шага;
  • setup_git_context, configure_repo_context — инициализация, привязка, перепривязка или отключение git для конкретной папки с обязательным выбором branch policy;
  • list_dir, file_info, read_file, tail_file;
  • write_file, append_file, edit_file;
  • create_dir, безопасное нерекурсивное delete_file;
  • copy_file, move_file — только отдельные файлы;
  • glob_files, ограниченный текстовый grep_files;
  • skills_list, skill_view — библиотека многоразовых процедур (см. «Скилы и память»);
  • memory_read, memory_write — память, переживающая сессию;
  • run_command — только в trusted developer mode.

read_file() теперь читает длинные файлы частями: показывает диапазон строк, общее число строк и next offset для продолжения. Если run_command(), grep_files() или list_dir() возвращают слишком большой результат, MCP сохраняет полный вывод во временный файл и отдаёт первую безопасную часть с путём вида @temp/... для продолжения через read_file().

tail_file(path, lines) (2.4.0) отдаёт последние N строк — для логов и длинных транскриптов, где read_file() пришлось бы каждый раз пересчитывать offset от начала файла.

Regex-поиск отключён, чтобы исключить зависание на патологических выражениях. Обычный регистронезависимый поиск остаётся доступен: клиентский regex — это готовый DoS-примитив (катастрофический бэктрекинг) против сервера без бюджета на запрос.

Аннотации инструментов (2.4.0)

Все инструменты объявляют MCP-аннотации readOnlyHint / destructiveHint / idempotentHint / openWorldHint, поэтому клиент видит, что можно выполнять без подтверждения, а что требует спросить пользователя. readOnlyHint выводится из scope инструмента, а не задаётся вручную, — так он не может разойтись с реальностью.

Ограничения

  • текстовый файл для чтения и итогового append/edit: до 5 МБ;
  • один write/append: до 2 МБ;
  • read_file() по умолчанию выдаёт до 400 строк, но в первую очередь ограничивается безопасным бюджетом около 9 500 символов, сохраняя целые строки;
  • небольшие результаты команд отдаются напрямую, а большие автоматически сохраняются во временный файл и продолжаются через read_file();
  • git через MCP запрещён, пока не завершён local setup-flow: при отсутствии .git агент должен спросить пользователя, создаём новый репозиторий, подключаемся к существующему или временно отключаем git;
  • при настройке repo context пользователь теперь должен явно выбрать branch policy: коммит в ветку по умолчанию (default_branch) или в явно заданную ветку (commit_branch);
  • после настройки MCP сверяет remote.origin.url с сохранённой локальной привязкой и блокирует git при несовпадении, а commit/push/merge/rebase блокирует вне выбранной ветки;
  • если настройка git уже сохранена, её нельзя молча менять: для default-значений и для перепривязки требуются отдельные явные подтверждения пользователя;
  • обычные mutating git-команды вроде reset, checkout -B, tag, config и remote set-url теперь дополнительно фильтруются политикой MCP и не должны обходить setup-flow.
  • временные MCP-файлы используют путь вида @temp/..., лежат в temp/ рядом с server.py, удаляются после финального чтения и дополнительно очищаются при старте;
  • timeout команды по-прежнему останавливает дерево процесса;
  • рекурсивное удаление и перемещение каталогов через MCP отсутствуют;
  • node_modules, .venv, .git и кэши пропускаются при рекурсивном просмотре.

Длинные операции и таймаут туннеля

run_command поддерживает timeout до 300 с, и сервер это уважает, но у связки Streamable HTTP + Serveo есть практический потолок: одиночный синхронный POST длиннее ~20–30 с туннель нередко обрывает (Streamable HTTP error: Error POSTing to endpoint). Это свойство рекомендуемого туннеля, а не логики сервера. Что делать с тяжёлыми задачами (сборка, pip install, полный прогон тестов):

  • Фоновые команды (рекомендуется, с 2.2.0): start_command(program, args, cwd, timeout) запускает allow-list-программу в фоне и сразу возвращает job_id; get_command_status(job_id) отдаёт статус, а после завершения — полный вывод в формате run_command; cancel_command(job_id) убивает дерево процессов; list_commands() показывает отслеживаемые задачи. Ограничения те же (allow-list, проверка cwd, git-context guard); число параллельных задач задаётся MCP_MAX_COMMAND_JOBS (по умолчанию 4), завершённые задачи и их файлы вывода подчищаются автоматически (хранение ~10 минут). Так сборку, pip install или полный прогон тестов можно пережить дольше таймаута туннеля и гонять команды параллельно.
  • Демонизировать вручную и опрашивать: запустить процесс в фоне и писать результат в файл (например, > out.txt 2>&1 и отдельный sentinel-файл о завершении), затем читать файл через read_file(). Короткие интерактивные вызовы идут напрямую и стабильно.
  • Свой reverse proxy вместо Serveo: задать стабильный домен через public_url (тогда Serveo не используется) и настроить keep-alive/таймауты на своей стороне — так потолок длительности снимается. Конфиги для nginx/Caddy/Traefik — в REVERSE_PROXY.md.

Требования

  • Windows 10/11;
  • Python 3.11+ с опцией Add Python to PATH;
  • встроенный OpenSSH Client (ssh.exe);
  • интернет при первой установке и для Serveo.

Проверка

.venv\Scripts\python -m unittest discover -s tests -v
.venv\Scripts\ruff check .

Набор из 370 тестов покрывает path traversal, allowlist, занятый порт, PID-проверку, правильный и неправильный токены, Serveo Host без HTTP 421, chunked-выдачу, repo bootstrap / disable / mismatch guard и timeout процесса. С 2.4.0 добавлены: guard на метасимволы cmd.exe для .cmd/.bat-программ (с живой проверкой на Windows, что cmd действительно переразбирает командную строку), побеги через Windows junction, резолвер виртуальных путей @temp/, владение фоновыми задачами по OAuth-клиенту, read-only mode, аудит-лог, редакция секретов, аннотации инструментов, --doctor, защита argv для ssh и default-deny для неклассифицированных git-подкоманд. OAuth-набор дополнительно проверяет discovery, DCR, PKCE (включая неверный verifier), state, consent с owner-кодом и троттлингом (правильный код всегда проходит), scope-ограничения per tool, лимиты клиентского реестра, ротацию refresh-токенов, replay authorization code, отзыв токенов, dual-режим (Bearer + X-API-Key + OAuth параллельно), переживание перезапуска сервера выданными токенами, а также устойчивость config.json и oauth_state.json к повреждению.

Что улучшено относительно оригинала

  • автоматический setup без ручного редактирования BAT-файлов;
  • токен и runtime вне проекта;
  • localhost-only bind и обязательная Bearer-авторизация;
  • правильная проверка границ workspace;
  • файловый режим безопаснее и включён по умолчанию;
  • команды вынесены в явно доверенный режим;
  • нет shell, фоновых команд, HTTP downloader и чтения env через MCP;
  • автоматический перевод больших результатов в temp-файлы с продолжением через read_file() вместо попытки отправить всё модели одним ответом;
  • обязательный setup-flow для git: bind existing / init new / attach existing remote / disable git with persisted local policy;
  • локальная repo-привязка для Git с проверкой origin после перезапуска MCP;
  • проверка занятого порта до создания туннеля;
  • проверка идентичности PID перед остановкой;
  • фиксированные зависимости, тесты, changelog и security model.

Подробная модель безопасности: SECURITY.md. История версий: CHANGELOG.md.

Git setup-flow для агента

Если обычная git-команда вызывается впервые для этой папки, MCP больше не пытается угадывать репозиторий. Вместо этого агент должен сначала вызвать repo_context_status() и, при необходимости, предложить пользователю выбор:

  1. setup_git_context(mode="init_new_repo", repository_url="...", fork_status="fork|not_fork", branch_mode="default_branch|specified_branch", default_branch="main", commit_branch="stablefix")
  2. setup_git_context(mode="attach_to_remote", repository_url="...", fork_status="fork|not_fork", branch_mode="default_branch|specified_branch", default_branch="main", commit_branch="stablefix")
  3. setup_git_context(mode="bind_existing_repo", repository_url="...", fork_status="fork|not_fork", branch_mode="default_branch|specified_branch", default_branch="main", commit_branch="stablefix")
  4. setup_git_context(mode="disable_git")

Это состояние сохраняется в agent-repo-config.local.json в корне workspace и переживает перезапуск MCP. Вместе с repo URL там хранится branch policy: либо коммиты разрешены только в ветку по умолчанию, либо только в явно заданную ветку. Файл intentionally local-only: он исключён из Git и release-архивов.

Сборка архива для отправки

Запустите BUILD_RELEASE.bat. Архив local-mcp-easy-<версия>.zip появится в папке release/ внутри проекта. Эта папка создаётся автоматически, исключена из Git и не попадает в сам release-архив. Сборщик автоматически исключает .venv, кэши, логи, ZIP-файлы, временную папку temp/, папку release/, локальные repo-файлы и файлы конфигурации/токенов.

Полный гайд Serveo

Подробная инструкция по временному и постоянному URL, созданию аккаунта, SSH-ключа, резервированию hostname, настройке Notion и устранению ошибок находится в SERVEO_SETUP.md. Если у вас свой домен и reverse proxy (вместо Serveo) — см. REVERSE_PROXY.md.

Совместимые клиенты

  • Hyperagent — OAuth 2.1, Streamable HTTP;
  • Notion Custom MCP — статический Bearer token;
  • другие Streamable HTTP MCP-клиенты — OAuth 2.1 или статический токен.

История проекта

Local MCP Easy вырос из проекта notion-local-mcp-easy.

Universal-версия включает работу из трёх источников:

  • оригинальный проект notion-local-mcp-easy (GitHub: oleg494);
  • форк LEADBERG и его стабилизационные доработки;
  • OAuth- и совместимостный слой, разработанный вместе с командой Opus/Fable.

Старая Notion-линия 1.x сохранена в ветке legacy.

Лицензия

MIT

English overview: README.en.md

from github.com/oleg494/local-mcp-easy

Installing Local Mcp Easy

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/oleg494/local-mcp-easy

FAQ

Is Local Mcp Easy MCP free?

Yes, Local Mcp Easy MCP is free — one-click install via Unyly at no cost.

Does Local Mcp Easy need an API key?

No, Local Mcp Easy runs without API keys or environment variables.

Is Local Mcp Easy hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Local Mcp Easy in Claude Desktop, Claude Code or Cursor?

Open Local Mcp Easy on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Local Mcp Easy with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All development MCPs