Отличный вопрос — да, на macOS правильное место для токена именно Keychain (системный keyring), а не открытым текстом в .zshrc. Схема такая: токен лежит зашифрованным в Keychain, а шелл при старте достаёт его командой security. Сейчас посмотрю ваш .zshrc и настрою.
Лукап из Keychain добавлен в .zshrc. Остался один шаг, который должны сделать вы сами (чтобы токен не попал ни в историю шелла, ни в наш диалог) — положить токен в Keychain. Выполните в терминале:
security add-generic-password -s sonarqube -a "$USER" -U -wКоманда интерактивно спросит пароль (это и есть ваш токен — вставьте его; ввод не отображается и не сохраняется в истории). Флаг -U позволит потом обновить токен той же командой при ротации.
Как это работает:
- Токен хранится зашифрованным в login-keychain, разблокируется вместе с вашим входом в систему.
- При старте каждого нового шелла
.zshrcдостаёт его:security find-generic-password -s sonarqube -wи экспортирует вSONARQUBE_TOKEN. .mcp.jsonв репозитории движка подставляет${SONARQUBE_TOKEN}из окружения в Docker-контейнер MCP-сервера.
Пара замечаний:
- Почему так, а не токен прямо в
.zshrc: файл профиля — открытый текст, попадает в бэкапы, может случайно засветиться при шаринге дотфайлов. Keychain эти риски снимает, а строка в.zshrcостаётся несекретной. - Проверка без вывода значения: после сохранения откройте новый терминал и выполните
echo ${SONARQUBE_TOKEN:+OK}— должно напечататьOK. - Нюанс с desktop-приложением: если запускаете Claude Code не из терминала, а как GUI-приложение из Dock, оно может не прочитать
.zshrc(тот выполняется только в интерактивных шеллах). Если MCP не увидит переменную — перенесём экспорт в~/.zshenv, он срабатывает для всех запусков zsh.
Когда положите токен в Keychain и перезапустите сессию Claude Code в каталоге движка — MCP-сервер SonarQube подхватится автоматически, и можно будет проверить его в бою: спросить список открытых issue по rabestro_dicechess-engine-scala.