Skip to content

Repository files navigation

NotCode 🛠️

Локальный MCP-сервер для Notion AI и других MCP-клиентов, который даёт агенту полноценные руки на твоём ПК: работу с файлами, точечные патчи, живые персистентные терминалы и Git.

Bun TypeScript License


by Claude & KilDoom

✨ Ключевые фичи

  • 💻 Изолированные персистентные терминалы — агент параллельно держит dev-сервер, сборку и тесты в разных сессиях, сохраняя cwd и состояние.
  • 🛡️ Снапшоты и аудит — перед каждым изменением файла создаётся бэкап, каждое действие пишется в журнал.
  • 📁 Файлы и Grep — чтение срезами, безопасные патчи (oldStr → newStr), поиск по содержимому и glob-поиск файлов.
  • 🔀 Управление Git — структурированные status, diff, commit, log, branch без парсинга сырого вывода моделью.
  • 📂 Профили воркспейсов — переключение между проектами «на лету» без перезапуска сервера.
  • ⚡ Транспорт Streamable HTTP (stateless) — один POST = запрос и ответ в том же соединении. Нет висящих каналов и сессий — отваливаться и утекать нечему. Старый SSE-эндпоинт оставлен как fallback для legacy-клиентов.

🚀 Быстрый старт

Требуется Bun v1.1+.

# 1. Клонируем и устанавливаем зависимости
git clone https://github.com/KilDoomWise/notcode
cd notcode
bun install

# 2. Первичная настройка (сгенерит токен и выведет конфиг клиента)
bun run setup

# 3. Запуск сервера
bun run start

💡 bun run setup выдаст готовый URL и Bearer-токен — вставь их в настройки MCP-клиента.

Проверить, что всё работает:

bun run check   # typecheck + smoke (тулы) + e2e (живой коннект: /mcp и legacy /sse)

⚙️ Режимы безопасности

Режим Описание
paranoic Доступ строго в пределах корня воркспейса.
auto (по умолчанию) Корень + явно разрешённые папки (workspace_allow).
bypass Полная автономность агента без подтверждений.

В любом режиме ты защищён постфактум:

  • Снапшоты — автосохранение файла перед записью (fs_restore для отката; сам откат тоже делает бэкап).
  • Аудит-лог — история всех действий в ~/.notcode/audit.jsonl, включая отклонённые попытки.

Почему агент не может сам снять с себя ограничения

Раньше модель могла одним вызовом notcode_set_mode перевести себя в bypass, а workspace_allow — разрешить любую папку на диске. Теперь эти тулы закрыты флагами и по умолчанию отключены. Управляет только человек из CLI:

bun run src/index.ts mode bypass                  # сменить режим
bun run src/index.ts security                     # посмотреть флаги
bun run src/index.ts security runtime-mode on     # разрешить агенту менять режим
bun run src/index.ts security runtime-workspace on # разрешить агенту расширять доступ

🛠 Набор инструментов (31 tool)

Файлы

  • fs_read_file — чтение со срезами строк, UTF-8/UTF-16, защита от бинарников.
  • fs_write_file — атомарная запись со снапшотом.
  • fs_patch_file — точечный патч (oldStrnewStr) с dry-run и терпимостью к CRLF.
  • fs_list_dir — дерево каталога с размерами.
  • fs_search_content — grep по коду с контекстными строками.
  • fs_find_files — поиск файлов по glob.
  • fs_snapshots / fs_restore — список бэкапов и откат.
  • fs_watch_start / fs_watch_poll / fs_watch_list / fs_watch_stop — отслеживание внешних изменений.

Терминал

  • terminal_exec — быстрая одноразовая команда.
  • terminal_open / terminal_run / terminal_read / terminal_write / terminal_list / terminal_close — персистентные сессии с сохранённым cwd, фоновыми процессами и вводом в stdin.

Git: git_status, git_diff, git_commit, git_log, git_branch.

Система: notcode_status, notcode_audit, notcode_set_mode.

Воркспейсы: workspace_list, workspace_use, workspace_add, workspace_allow.

MCP-аннотации (readOnlyHint, destructiveHint) намеренно не отдаются клиенту: из-за их смены Notion AI блокировал тулы с ошибкой «tool has changed its operation type» и не показывал кнопку повторного одобрения. Если клиент всё равно заклинил — bun run src/index.ts fix.


📜 Команды CLI

Команда Описание
bun run setup Первичная настройка и параметры подключения
bun run start Запуск MCP-сервера (Streamable HTTP + Bearer)
bun run dev Запуск в режиме разработки (watch)
bun run status Статус, текущий режим и лимиты
bun run token Посмотреть или пересоздать токен (--reset)
bun run audit 30 Последние 30 записей журнала
bun run typecheck Строгая проверка типов
bun run smoke Проверка всех тулов без сервера
bun run e2e Живой коннект: POST /mcp, tools/call, legacy SSE + heartbeat
bun run check Всё вышеперечисленное одной командой

Переменные окружения

Переменная Назначение
NOTCODE_PORT Порт сервера (перекрывает конфиг)
NOTCODE_HOST Адрес прослушивания, по умолчанию 127.0.0.1
NOTCODE_LOG_LEVEL debug / info / warn / error / silent
WORKSPACE_ROOT Корень воркспейса при первом setup
E2E_PORT Порт для bun run e2e (по умолчанию 3999)

🏗 Архитектура

src/
├─ index.ts              # HTTP-транспорт (/mcp + legacy /sse), авторизация, CLI
├─ mcp.ts                # регистрация тулов в MCP-сервере
├─ config.ts             # конфиг, профили, токен, флаги безопасности
├─ tools/                # сами тулы (fs / terminal / git / meta)
└─ utils/
   ├─ sandbox.ts         # проверка путей по режиму безопасности
   ├─ fs-atomic.ts       # атомарная запись (tmp + rename)
   ├─ snapshot.ts        # бэкапы и откаты
   ├─ audit.ts           # журнал действий
   ├─ terminal-manager.ts# сессии терминала
   ├─ watch-manager.ts   # наблюдатели ФС
   ├─ proc.ts            # корректное убийство дерева процессов
   ├─ lock.ts            # Mutex для гонок по файлам
   └─ logger.ts          # логи только в stderr

Важное правило: stdout никогда не используется под логи — он зарезервирован под протокол.

🔌 Транспорт: как клиент общается с сервером

Эндпоинт Назначение
POST /mcp Основной. Stateless Streamable HTTP: один запрос — один JSON-ответ.
GET /mcp Отвечает 405: серверных пушей нет, висящий стрим не нужен.
GET /sse + POST /messages Legacy-транспорт (спека 2024-11-05) для старых клиентов.
GET /health Проверка живости, единственный эндпоинт без токена.
GET /status Режим, тулы, алиасы, активные сессии и пути эндпоинтов.

Почему stateless. Раньше единственным транспортом был SSE: клиент держал открытым GET /sse, а вызовы шли отдельными POST /messages?sessionId=…. Каждое такое соединение — сессия со своим экземпляром MCP-сервера и heartbeat-таймером. Если клиент отваливался молча (обычная история для облачных клиентов вроде Notion AI), сессия оставалась «живой» до таймаута простоя, упиралась в лимит и провоцировала цикл переподключений и спам в логах.

Теперь каждый POST /mcp самодостаточен: сервер собирается, отвечает и закрывается в рамках одного запроса. Сессий не существует — значит, нечему утекать, зависать и вытесняться. Конфиг перечитывается на каждый запрос, поэтому смена режима, алиасов и воркспейса подхватывается без перезапуска.

Пути эндпоинтов меняются в ~/.notcode/config.json: sse.mcpPath, sse.ssePath, sse.messagesPath.


🩺 Если клиент пишет «Failed to connect to MCP server»

  1. Проверь, что сервер жив: curl http://127.0.0.1:3000/health{"ok":true}.
  2. Проверь токен: bun run token и сравни с настройками клиента.
  3. Проверь URL в клиенте: основной путь — /mcp, а не /sse. Точный адрес печатается при старте сервера.
  4. Прогони bun run e2e — он воспроизводит и новый handshake, и legacy-SSE с heartbeat.
  5. Если между клиентом и сервером есть nginx/Cloudflare: для /mcp достаточно обычного проксирования; для legacy /sse выключи буферизацию и подними proxy_read_timeout выше интервала heartbeat.
  6. Логи: NOTCODE_LOG_LEVEL=debug bun run start.

📂 Структура данных

~/.notcode/
├── config.json       # Настройки, токены и профили
├── audit.jsonl       # Журнал выполненных действий
└── snapshots/        # Автоматические бэкапы файлов

Если config.json окажется битым, сервер не молча создаст новый токен, а отложит файл в config.json.broken-<время> и скажет об этом явно.


📄 Лицензия

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages