5.9 KiB
5.9 KiB
Notion PC Bridge (notion-mcp) — deploy + verify
Repo hytthynn/notion-mcp → C:/Users/User/tmp/notion-mcp. Суть: Notion AI (Custom MCP server) управляет Windows-ПК через desktop-commander (26 тулов: файлы/терминал/процессы/поиск) поверх ngrok-туннеля. Cookie Notion не нужны — только MCP api_key + ngrok authtoken.
Процедура (проверена end-to-end)
- Зависимости: Node 22+;
npm ciв репо (mcp-proxy 6.7.19 + @wonderwhy-er/desktop-commander 0.2.52, ~660 пакетов, ~3 мин). НЕ запускатьnpm audit fix --force(ломает версии). - ngrok: один exe — скачать
https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-windows-amd64.zip, распаковать вhermes/tools/ngrok/. Authtoken:ngrok config add-authtoken "$NGROK_AUTHTOKEN"→ сохранится в%LOCALAPPDATA%/ngrok/ngrok.yml. - config.json писать вручную Python-скриптом (configure_notion.py = интерактивный визард с getpass — не пайпится). База config.example.json; обязательные поля:
api_key≥32 симв (secrets.token_urlsafe(48)) — bridge.py exit'ит при коротком;secret_path='mcp-'+secrets.token_hex(24)— часть capability-URL;desktop_commander.allowedDirectories— НЕ пустой (пустой = вся ФС, bridge отказывается стартовать); задавать выделенную test-папку;ngrok_bin= полный путь к ngrok.exe (иначе ищет только winget Packages);ngrok.config_path= путь к ngrok.yml со строкойauthtoken:(bridge парсит из yml ТОЛЬКО authtoken+domain и всегда驱动 ngrok CLI-флагами; env NGROK_AUTHTOKEN сам не читает);port— проверить занятость:netstat -ano | grep ':PORT .*LISTENING'. 8888 на этой машине держит Docker (com.docker.backend) — использовать 8890; Docker не убивать, менять порт в config.json.
- Запуск bridge.py (background=true, долгоживущий сервер, без notify):
USERPROFILE передавать ИНЛАЙН аргументом env — bash
cd C:/Users/User/tmp/notion-mcp && env -u PYTHONPATH USERPROFILE='C:\Users\User' PATH="/c/Users/User/AppData/Local/hermes/tools/ngrok:$PATH" <Python311>/python.exe bridge.py > bridge.log 2>&1exportв background-вызове до ребёнка не доходит,Path.home()падаетRuntimeError: Could not determine home directory(bridge.py читает home на строке ~38, до всего). - Public URL:
curl -s http://127.0.0.1:4040/api/tunnels(локальный ngrok API) →public_url. Полный MCP URL =public_url + '/' + secret_path. Домен на free-тарифе рандомный при каждом старте — всегда перечитывать, CONNECTION.txt обновлять. - Верификация перед отдачей (три пробы):
- GET на MCP endpoint → 405 = норма (MCP говорит POST, 405 доказывает что путь живой);
- POST с неверным
X-API-Key→ 401 (auth enforcement работает); - JSON-RPC
initializePOST ({"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{...}}}) с хедерамиX-API-Key,Content-Type: application/json,Accept: application/json, text/event-stream,ngrok-skip-browser-warning: 1(обязателен — ngrok-free отдаёт browser-interstitial) → 200 SSE cserverInfo: desktop-commander.
- Handoff: полный URL + api_key + шаги Notion AI записать в локальный
CONNECTION.txtв репо — секреты в чат НЕ paste'ить (правило Влада). Notion AI: Connections → Add custom MCP server → URL, Name (например windows), Auth = API Key, header nameX-API-Key, value = api_key → Connect.
Safety — ВСЕГДА предупреждать юзера перед подключением
- File-операции ограничены allowedDirectories, но терминал desktop-commander НЕ sandboxed (README прямо говорит) — Notion AI через терминальные тулы читает/ранит ЛЮБОЙ файл машины, минуя folder-рестрикт. blockedCommands в config.json — базовый блок-лист, не изоляция.
- На машине с прод-инфрой (ключи/сессии/гейтвеи): рекомендовать выделенную машину/VM (демо автора юзало отдельные "Notion PC") или ручные аппрувы; «Skip all approvals + With internet» на основной машине = облачный LLM с полным шеллом + prompt-injection-риск.
- Держать bridge остановленным когда не используется (публичный endpoint, защищён только api_key+secret path).
Питфолы
- Идентификация PID на порту:
tasklist //FI "PID eq N"молча пуст →powershell -NoProfile -Command "Get-Process -Id N; (Get-CimInstance Win32_Process -Filter 'ProcessId=N').CommandLine". - «port N is already in use» в bridge.log = живой посторонний процесс (Docker), а не орфан прошлого запуска — netstat + PowerShell-идентификация до смены порта.
- Краш на старте без лога = смотреть bridge.log: bridge.py падает быстро (конфиг-валидация, home dir), ngrok API при этом не поднимается.