# Установка iskron (исполняется агентом) Ты — кодинг-агент, устанавливающий **iskron** для своего пользователя. Выполни шаги ниже автономно, по порядку, и доложи результат каждого. Жди запросов на одобрение. Твой харнесс может загейтить или отклонить любую команду ниже — это решение о правах, а не сломанный шаг, и ничто в этом файле его не переопределяет. Спросить и подождать — часть нормального прогона, не тупик; см. **Разбор проблем**. iskron — это две части: 1. **Скиллы** — методические бандлы в plain-markdown из этого репозитория (читаются до установки). 2. **Граф-сервер MCP** — удалённый граф рассуждений NKS на `https://mcp.iskron.ru/`, доступный как тулы `iskron_*`. ## 0. Определи свой харнесс Пойми, каким агентом ты запущен — Claude Code в терминале, Claude Desktop, Cursor, Codex, OpenCode, pi или другой — и иди по соответствующей ветке ниже. Если понять не можешь — спроси пользователя. ## 1. Установи скиллы У каждого харнесса свой канал, и ни один не главный — иди по своей ветке. **Claude Code, Claude Desktop, claude.ai** — плагин. Он неймспейсит каждый скилл под `iskron`, так что ничего не конфликтует, и приносит запись MCP до удалённого граф-сервера — какую и как в неё войти, сказано в шаге 2. ```sh claude plugin marketplace add iskron-ai/skills claude plugin install iskron@iskron ``` (В интерактивной сессии: `/plugin marketplace add iskron-ai/skills`, затем `/plugin install iskron@iskron`.) **Cursor / Codex / Pi / любой другой агент** (плоская установка, десятки харнессов): ```sh npx skills add iskron-ai/skills --all --global ``` `--all` уже значит «все скиллы всем харнессам» (`--skill '*' --agent '*' -y`), так что сужать его через `--agent` не нужно — этим его только отменяют. `--global` обязателен: без него скиллы ставятся **в текущий репозиторий**, а не пользователю. Содержимое ляжет однажды в `~/.agents/skills/`, каталоги харнессов получат симлинки на него; обновление — `npx skills update --global`. **Pi — своя одна команда, и она же ставит расширение:** ```sh pi install git:github.com/iskron-ai/skills ``` Ставит скиллы и расширение `iskron` разом. С ним шаг 2 для pi не нужен: расширение само поднимает мост `iskron-bridge` из этого же пакета и регистрирует тулы `iskron_*` в сессии (первый вызов уводит человека в браузер на обычный OAuth), а сокет живого канала держит сама сессия — отдельного сторожа заводить не надо. Стояние агент занимает сам, своими же тулами: `iskron_channel(action="connect")`, сразу за ним `register` — адрес сокета из ответа расширение берёт само, и слушание включается без единого действия человека. Обновление — `pi update git:github.com/iskron-ai/skills` (или `pi update --extensions` — все установленные пакеты разом). **OpenCode** — скиллы плоской установкой выше (OpenCode читает `~/.agents/skills/` и `~/.claude/skills/`), а тулы и канал приносит **плагин из поставки** — шаг 2, ветка OpenCode. ## 2. Подключи граф-сервер **Claude Code + плагин из шага 1: сервер приходит с мостом внутри, логин — первым вызовом.** Плагин несёт запись MCP (`.mcp.json` в корне плагина) под именем **`plugin:iskron:iskron`**, и это не удалённый сервер, а **мост из самой поставки**: stdio-процесс `node …/iskron.mjs`, который Claude Code поднимает на старте сессии из установленной копии плагина. Копировать и регистрировать ничего не нужно; обновление плагина приносит новый мост в следующую сессию (или по `/reload-plugins`). **Логин стартует первый же вызов.** Пока гранта нет, любой тул `iskron_*` отвечает ошибкой, в тексте которой стоит адрес авторизации — мост печатает его и на stderr. Открой адрес в браузере (мост пытается сам), кликни — и следующий вызов проходит. Грант ложится в `~/.iskron-bridge/` и дальше обновляется мостом сам, в простое тоже. Проверь: ```sh claude mcp list # plugin:iskron:iskron: node …/iskron.mjs (stdio) - ✔ Connected claude -p "Call iskron_me and print its result." --allowedTools "mcp__plugin_iskron_iskron__iskron_me" ``` (Имя тула — имя сервера с каждым `:`, заменённым на `_`, с префиксом `mcp__`.) Что стоит и работает ли, одной командой скажет сам мост — подкоманда `doctor` того же файла, путь к которому печатает `claude mcp list`. **Claude Desktop и claude.ai: плагин добавляет сервер, но оставляет его неавторизованным.** Кнопка авторизации находится не в настройках коннекторов самого приложения, и вставлять никуда ничего не нужно: она живёт на **вкладке Connectors на странице самого плагина iskron** и появляется только после установки плагина. Проведи пользователя: > Открой **Customize → Plugins** и найди плагин **iskron**. Нажми **Install**, если ещё > не ставил, затем открой его вкладку **Connectors** и нажми там кнопку авторизации — > **Connect** появляется только после установки. На **claude.ai** этот путь надёжнее, чем в десктопном приложении, а плагин, установленный на claude.ai, не подхватится десктопом до перезапуска приложения. После этого тулы `iskron_*` приходят уже авторизованными — продолжай с шага 3. **Codex** — своя поставка; две команды ставят скиллы: ```sh codex plugin marketplace add https://github.com/iskron-ai/skills codex plugin add iskron@iskron ``` Плагин приводит с собой **мост из самой поставки**: `codex mcp list` показывает `iskron` с `command node …/iskron.mjs` и `Auth: Unsupported` — логинить нечем и незачем, грант мост держит свой, в `~/.iskron-bridge/`. Первый вызов любого тула `iskron_*` без гранта отвечает адресом авторизации (мост печатает его и пытается открыть браузер); после клика следующий вызов проходит. Копировать файлы и править конфиг не нужно; обновление плагина приносит новый мост. **Без плагина** мост регистрируется одной командой после «Как поднять мост»: ```sh codex mcp add iskron-bridge -- node "$HOME/.iskron-bridge/iskron-bridge.mjs" ``` **Нативную http-запись** плагин Codex больше не несёт: её OAuth не держит грант и привязку стояния. Нужна всё же — `codex mcp add iskron --url https://mcp.iskron.ru/` и `codex mcp login iskron`, с ценой, названной в скилле establish-mcp. **Неинтерактивный прогон.** `codex exec` по умолчанию запрещает подтверждения, а вызовы MCP их требуют, и отбиваются они словами `MCP tool call requires approval, but approval policy is never`: тулы видны и не зовутся. Добавь `--approve-for-me` — подтверждения пойдут через автоматический разбор в песочнице записи по рабочей директории. Соседний `--dangerously-bypass-approvals-and-sandbox` снимает заодно и песочницу — для этого он не нужен. **OpenCode** — не запись `mcp` в конфиге, а **плагин из поставки**: запись `mcp` переименовала бы каждый тул в `iskron_iskron_*`, и скиллы, зовущие `iskron_orient`, звали бы имя, которого в сессии нет. Плагин регистрирует тулы под их именами, поднимает мост дочерним процессом на каждую сессию и вкладывает кадры живого канала в ту сессию, чей мост их принёс, — стояние у каждой сессии своё, держит его мост, сторож не нужен. Два файла, оба из установленного скилла `establish-mcp` (шаг «Как поднять мост» кладёт первый): ```sh mkdir -p ~/.iskron-bridge ~/.config/opencode/plugins src=$(dirname "$(find -L ~/.agents/skills ~/.claude -path '*establish-mcp/scripts/opencode-plugin.js' 2>/dev/null | head -1)") [ -n "$src" ] && [ -f "$src/iskron.mjs" ] || { echo "в установленных скиллах нет плагина OpenCode — обнови поставку (npx skills update --global или плагин) и повтори"; false; } cp "$src/iskron.mjs" ~/.iskron-bridge/iskron-bridge.mjs cp "$src/opencode-plugin.js" ~/.config/opencode/plugins/iskron.js ``` Ищем именно `opencode-plugin.js`: у поставок до него мост звался `iskron-bridge.mjs`, и поиск по одному мосту нашёл бы старую копию без плагина — а пустой `src` без проверки заставил бы `cp` тихо копировать из текущего каталога. Плагин лежит именно в `~/.config/opencode/plugins/`: там, и только там, OpenCode сам держит зависимость `@opencode-ai/plugin`, которую файл импортирует. Мост плагин берёт из `~/.iskron-bridge/iskron-bridge.mjs` (или из `ISKRON_BRIDGE_PATH`) и запускает его на Bun самого OpenCode — Node на машине не нужен. После обновления поставки повтори обе копии — `node "$src/iskron.mjs" doctor` (из поставки, не из домашней копии: сверять копии может только файл, рядом с которым лежит эталон) скажет, отстала ли какая. Первый вызов тула без гранта уводит человека в браузер, как везде; для безголовой машины — токен, ниже. Проверь: ```sh opencode run --format json "Позови тул iskron_me и напечатай имя человека" ``` **Codex слышит канал через дверь app-server.** Кадр стояния входит в идущий тред, если тред живёт под локальным демоном app-server. Демон стартует из managed-установки Codex — `$CODEX_HOME/packages/standalone/current/codex`, её кладут установщик (`curl -fsSL https://chatgpt.com/codex/install.sh | sh`) и приложение ChatGPT; голый бинарь внутри ChatGPT.app без неё отказывает. Держи `CODEX_HOME` коротким (путь unix-сокета ограничен; дом внутри `~/Library/Application Support/…` слишком длинный — заведи короткий дом, смотрящий на настоящий) и подними демон: ```sh H="$HOME/Library/Application Support/orca/codex-runtime-home/home" # настоящий дом, если он длинный mkdir -p /tmp/cxh && ln -sfn "$H/packages" /tmp/cxh/packages && ln -sfn "$H/auth.json" /tmp/cxh/auth.json cp "$H/config.toml" /tmp/cxh/config.toml CODEX_HOME=/tmp/cxh codex plugin marketplace add https://github.com/iskron-ai/skills CODEX_HOME=/tmp/cxh codex plugin add iskron@iskron CODEX_HOME=/tmp/cxh codex app-server daemon start ``` Плагин ставится в короткий дом отдельно: `config.toml` записи моста не несёт (её приносит плагин), а каталог `plugins` настоящего дома в рецепт не входит — без этого шага сессии под демоном придут без тулов `iskron_*` (поймано холодным прогоном). Сессии Codex, запущенные с тем же `CODEX_HOME`, прицепляются к демону сами; сессия, запущенная с другим домом, двери не имеет — агент изнутри этого не поправит, это делаешь ты до запуска. `node ~/.iskron-bridge/iskron-bridge.mjs doctor` под тем же `CODEX_HOME` говорит, открыта ли дверь. Дальше — скилл `standing`: `node "<мост>" watchdog-codex <ключ>` из оболочки сессии долгоживущим процессом. Без демона остаётся сторож выхода-на-кадре. **Порядок один, и он без условий: сперва мост `iskron-bridge`** (как — ниже, в разделе «Как поднять мост»). Нативную запись можно не заводить вовсе. Заводишь обе записи — **дай им разные имена**, иначе вторая перетрёт первую в одном конфиге, а скиллы учат агента ждать два различимых набора тулов. **Claude Code без плагина** (`--scope user`: граф следует за пользователем, не за одним проектом — скоуп по умолчанию зарегистрировал бы его проектно-локально): ```sh claude mcp add --scope user --transport http iskron https://mcp.iskron.ru/ ``` **Cursor** — вмёржи в `~/.cursor/mcp.json` (глобальный — граф следует за пользователем; проектный `.cursor/mcp.json` — только если пользователь явно хочет скоупить): ```json { "mcpServers": { "iskron": { "url": "https://mcp.iskron.ru/" } } } ``` В Cursor OAuth-логин откроется при первом обращении. В Claude Code — нет: неавторизованный сервер не публикует тулов, так что «первого обращения» не случится; запусти логин явно, под pty, как выше. **Как поднять мост.** Он нужен всякому пишущему агенту, а для харнесса без нативного https+OAuth MCP он вообще единственный путь — конфиг такого берёт только `command` + `args`, либо поле URL есть, а команды или кнопки логина нет нигде. Не тянись к `mcp-remote`: поставка несёт собственный мост, **iskron-bridge** (внутри скилла `establish-mcp`, установленного шагом 1). Скопируй его из версионированного пути установки и зарегистрируй обычным stdio-сервером: ```sh mkdir -p ~/.iskron-bridge src=$(find -L ~/.agents/skills ~/.claude -path '*establish-mcp/scripts/iskron.mjs' 2>/dev/null | head -1) cp "$src" ~/.iskron-bridge/iskron-bridge.mjs && echo "скопирован из $src" ``` `-L` здесь несущий, а не украшение: при глобальной установке через `npx skills` содержимое лежит в `~/.agents/skills/`, а каталог скиллов каждого харнесса — симлинк на него, и `find` без `-L` внутрь симлинка не заходит и не находит ничего. Плагинный канал кладёт настоящие файлы под `~/.claude/plugins/cache/`, поэтому ищем в обоих местах и берём первое попавшееся. ```json { "mcpServers": { "iskron-bridge": { "command": "node", "args": ["/абс/путь/до/.iskron-bridge/iskron-bridge.mjs"] } } } ``` Клади эту запись в **пользовательский** конфиг харнесса (домашняя директория), не в проектный — граф следует за пользователем. Имя `iskron-bridge` здесь несущее, а не украшение: если рядом уже стоит нативная запись под именем `iskron`, одинаковые имена перетрут друг друга, и человек получит один набор тулов там, где ожидал два. Без аргумента-URL мост целит в `https://mcp.iskron.ru`; на первом вызове он проводит полный OAuth-флоу в браузере, держит токены свежими в `~/.iskron-bridge/` (и в простое тоже) и превращает любой отказ сервера в видимую ошибку вместо тихого зависания. Агентов на машине может быть много — хранилище токенов у них одно, браузерный флоу ведёт ровно один мост, и остальные тем временем показывают тот же самый authorize-URL: один клик лечит всю машину, и ни один вызов не висит в ожидании человека. Нужен Node 22+. Подробности и лестница выбора — в скилле `establish-mcp`; там же сказано, что делать, когда в сессии оказались оба подключения разом: пишущие вызовы ведут через мост. **Путь токена — когда OAuth отсутствует, не может до тебя дотянуться или не проходит.** Сюда ведут два случая. Первый — структурный: браузера нет вовсе — CI, автономные VM; на интерактивной машине сначала мост iskron-bridge выше. Второй — обычная поломка: логин не открывается, не завершается, или каждый вызов `iskron_*` продолжает возвращать 401. Не упирайся ни в один и не перебирай варианты. Личный токен доступа — заголовок, а не сессия: он аутентифицирует из любого процесса на любом хосте — и потому это единственный путь, который ведёт себя одинаково везде. Токен пользователь создаёт в веб-интерфейсе и передаёт тебе — никогда не выдумывай, не угадывай и не переиспользуй его. **Отдай его мосту**, и всё остальное — запись, плагин, стояние, канал — остаётся как было: с токеном мост не ходит ни в discovery, ни в браузер, ни за обновлением, а 401 читает как «токен отвергнут» и говорит это словами, без адреса авторизации. ```sh mkdir -p ~/.iskron-bridge && (umask 077; printf '%s\n' "$ISKRON_TOKEN" > ~/.iskron-bridge/token) node ~/.iskron-bridge/iskron-bridge.mjs doctor # «грант: личный токен (PAT) … токен принят сервером» ``` Переменная `ISKRON_BRIDGE_TOKEN` в окружении процесса моста старше файла — для CI, где файла нет. Файл `~/.iskron-bridge/token` (0600) — для машины, где мост поднимают харнесы с разным окружением. Хранилище OAuth-гранта при этом не читается и не пишется; убери токен — мост вернётся к OAuth. Без моста — только нативная запись с заголовком, где харнесс его берёт: ```sh npx add-mcp https://mcp.iskron.ru/ --header "Authorization: Bearer ${ISKRON_TOKEN}" ``` ```toml # Codex ~/.codex/config.toml [mcp_servers.iskron] url = "https://mcp.iskron.ru/" bearer_token_env_var = "ISKRON_TOKEN" ``` Не зашивай токен в файлы, попадающие в коммиты. В URL токен не попадает никогда. ## 3. Обновление Мост обновляет себя сам: при каждом старте он сверяет свою версию с домашней копией `~/.iskron-bridge/iskron-bridge.mjs` — своя новее ложится в дом, домашняя новее запускается вместо него; раз в шесть часов он спрашивает релизы этого репозитория и, если есть свежее, скачивает мост, плагин OpenCode и этот файл в дом, а агенту говорит строкой `ПОСТАВКА ОТСТАЛА` в ответе тула. По требованию то же делает одна команда: ```sh node ~/.iskron-bridge/iskron-bridge.mjs update ``` Скиллы мост не обновляет — их кладёт канал харнесса, и после `update` пройди шаг 1 своей ветки заново (`/plugin marketplace update iskron` и `/reload-plugins` в Claude Code; `npx skills update --global`; `pi update git:github.com/iskron-ai/skills`; `codex plugin marketplace upgrade iskron`, затем `codex plugin remove iskron@iskron` и `codex plugin add iskron@iskron`), затем перезапусти сессию: мост прежней сборки живёт до её конца. Человеку достаточно сказать агенту «обнови» — дверь `iskron` исполняет этот раздел из свежей копии файла, которую `update` кладёт рядом с грантом. ## 4. Перезапуск Скажи пользователю, что установка закончена, и попроси перезапустить сессию, чтобы подхватились новые скиллы и подключение, и начать новую сессию с двери `iskron` (`/iskron:iskron` с плагином Claude Code) — дальше его ведёт раздел 5. Здесь твоя часть работы заканчивается. ## 5. Первая сессия: до первой записи В свежей сессии пользователь зовёт дверь `iskron` (`/iskron:iskron` с плагином Claude Code) и говорит своими словами. Агент проверяет соединение: `iskron_realm(action="list")` отвечает списком графов. Дальше ведёт дверь: проектного графа нет — заведёт без вопросов личную память `@handle/mind` (граф и роль человека в нём), если её нет, спросит, позвали ли работать в чей-то граф, иначе заведёт проектный и доведёт исходную просьбу до первой записи; репозиторий без `AGENTS.md` — предложит `iskronify`, который приведёт репозиторий к стандарту iskron (`AGENTS.md` + ритуалы сессии) и засеет граф структурой, которую кодовая база уже показывает. Первая сессия кончается первой записью в граф пользователя, а не подключением. ## Разбор проблем - **Команда отклонена или ждёт одобрения** → решение о правах, не сбой установки. Не перефразируй команду и не переключайся на другой путь установки — плоская установка это другой продукт, не обход. Назови шаг, точную команду и что даст одобрение; затем остановись и жди. По одобрении перегони ту же команду и продолжай — уже удавшиеся шаги не повторяются. - **Claude Desktop / claude.ai: тулы `iskron_*` видны, но не авторизованы** → это ожидаемо; плагин не авторизует собственный сервер. Авторизуй на вкладке **Connectors** самого плагина, как в шаге 2, — не в настройках коннекторов приложения, и никакой URL никуда не вставляется. - **Плагин установлен на claude.ai, но невидим в десктопном приложении** → перезапусти приложение. - **401 / ошибка авторизации, или OAuth-логин не завершается** → попробуй логин ещё раз (`/mcp` → authenticate, или перезапусти сессию); на Claude Desktop — шаг с вкладкой Connectors выше. Если повторяется — вычисти сохранённый кред, а не логинься поверх: `claude mcp logout plugin:iskron:iskron`; если заодно переустанавливаешь — сделай это *до* удаления плагина, иначе имя перестанет резолвиться. Если всё ещё не проходит — прекрати перебирать и иди путём токена из шага 2 (`~/.iskron-bridge/token` или `ISKRON_BRIDGE_TOKEN` для моста): личный токен аутентифицирует там, где OAuth не может, и попросить его у пользователя короче, чем дебажить его браузер. Если токен уже используется и всё равно 401 — он неверен или истёк: попроси свежий, не перебирай варианты. - **`claude mcp login iskron` → no such server** → с плагином сервер называется `plugin:iskron:iskron`. Прогони `claude mcp list` и скопируй имя оттуда. - **`stdin isn't a terminal, so authentication can't be completed here`** → у твоего шелла нет TTY, логин не сломан. Перегони под `script`, как в шаге 2; localhost-колбэк завершает флоу без всякого ввода. - **Тулы `iskron_*` не видны** → конфиг MCP загружается на старте сессии: перезапусти сессию и проверь снова. В той сессии, которая авторизовала сервер, тулы остаются невидимыми — это ожидаемо, а не проваленный логин. - **OAuth нативного коннектора раз за разом подводит пользователя** (повторная авторизация после простоя, зависшие вызовы при живом на других поверхностях сервере) → переведи этот харнесс на встроенный мост (шаг 2, «Как поднять мост»): его хранилище токенов — собственное (`~/.iskron-bridge/`), изолированное от общих кред-записей, обновление бежит в фоне и в простое, а отказы всплывают ошибками, никогда не зависаниями. - **Конфликт имён скиллов при плоской установке** → другой скилл-пак уже занял голое имя вроде `design`. Переименуй ту директорию — или используй плагинный канал Claude Code, который неймспейсит всё под `iskron`.