MAX

Справочник настроек

Справочник настроек CLI для MAX: типы, значения по умолчанию, области действия, переменные окружения и назначения моделей.

Полный перечень ключей, значений по умолчанию, областей действия и переменных окружения. Для обычной настройки начните с руководства; правила запуска и вывода — в контракте CLI.

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

Порядок, в котором решается настройка

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

Внутри файла побеждает самая точная запись. Для команды личного аккаунта на профиле work: personal.profiles.work → profiles.work → personal.defaults → defaults. Для команды max work bot … — то же, но с bot вместо personal. Профиль старше раздела: запись про один аккаунт важнее записи про все.

max chats list --limit 5          # флаг: 5
MAX_PROFILE=personal max chats list   # переменная выбирает профиль
# "limit": 50 у профиля в файле — когда флага нет
# "limit": 30 в "defaults" — когда и у профиля нет
# 20 — когда нет ничего

Два исключения, которые старше этого порядка. Они не забыты, а записаны:

  • MAX_TOKEN старше ключницы. Если переменная задана, берётся она — так это работает в CI.
  • MAX_CONFIG_DIR, MAX_STATE_DIR переносят настройки и вход max, включая то, какая запись в ключнице соответствует профилю.

Что действует сейчас

max config show            # профиль, какие профили есть, файл и каждая настройка
max work config show       # то же для профиля work
max config show --json     # то же одним объектом

Против каждой настройки — откуда она: flag, default или config file: с ключом, из которого она прочитана, например config file: bot.profiles.test. Против профиля — first word, MAX_PROFILE, MAX_PROFILE_LOCK, config file: defaultProfile или default.

С --json в ответе есть и storeSettings — настройки общего архива (searchStemmers.*) и откуда они взяты: store или default.

max test config show --bot показывает настройки так, как их получит max test bot …: у бота свой раздел и свой лимит отправок. Если файла нет, загрузка настроек сначала создаёт его с обычными значениями по умолчанию. Существующий файл не перезаписывается. Если задана одна из переменных MAX_*_DIR, команда скажет об этом в stderr: с ними у профиля другая запись в ключнице, и вход, сделанный без них, выглядит как «нет сессии».

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

Права доступа

deny запрещает и чтение, и запись; readonly разрешает чтение; ask требует подтверждения; allow выполняет действие без вопроса. В терминале ask показывает вопрос с ответом по умолчанию «нет». В JSON-режиме вопроса нет: нужен --yes, а для удаления сообщений — --allow-dangerous. В MCP формы подтверждения отсутствуют: ask разрешает вызванную запись, deny и readonly по-прежнему запрещают её. --permission ключ=уровень временно переопределяет права процесса. Старые флаги подтверждения больше не определяют доступ; для CLI уровни ask по-прежнему требуют ответа или явного флага. Подключение описано в MCP.

Более точный ключ переопределяет ресурс. Этот пример разрешает чтение сообщений и удаление без подтверждения, запрещая остальные записи в сообщения:

{ "profiles": { "work": { "permissions": { "messages": "readonly", "messages.delete": "allow" } } } }

Контакты, чаты, реакции и другие ресурсы этим примером не ограничиваются. У бота ключи начинаются с bot, например bot.messages.send. config show показывает эффективные права и их источник. config set отклоняет неизвестный ключ команды, в том числе внутри целого объекта permissions, с кодом 2. config unset позволяет удалить старый неизвестный ключ. Чтение уже существующего файла с таким ключом предупреждает в stderr и продолжает работу.

Права из разных разделов файла складываются, но сначала решает ближайший раздел, потом длина ключа. Ключ, заданный у профиля, закрывает такой же ключ и все ключи под ним в personal.defaults и defaults. Профиль agent здесь не удаляет сообщения: его messages закрывает messages.delete из defaults.

{
  "defaults": { "permissions": { "messages.delete": "allow" } },
  "profiles": { "agent": { "permissions": { "messages": "readonly" } } }
}

Это работает в обе стороны: messages: allow у профиля закрывает и messages.delete: deny из defaults, и тогда удаление снова спрашивает, как по умолчанию. Старые readOnly и allow действуют в том разделе, где записаны.

Перед переводом старого файла можно посмотреть изменения:

max config migrate --dry-run
max config migrate

Миграция сохраняет действовавшие права, настройки MAX и отметки модерации; старые уровни правил forbid/flag/confirm становятся deny/ask/ask. --dry-run ничего не пишет. После появления permissions команды изменения readOnly, allow и mcpTools отказывают с указанием новой настройки. Под MAX_PROFILE_LOCK миграция всего файла запрещена; предпросмотр доступен.

Файл

~/.config/max-cli/config.json, режим 0644. Его пишет max config set (ниже) или вы сами.

{
  "defaultProfile": "personal",
  "defaults": { "keepRunsForDays": 14 },
  "profiles": {
    "personal": { "limit": 50, "timeoutMs": 20000, "color": true },
    "work": { "limit": 10 }
  },
  "personal": {
    "defaults": { "sendsPerHour": 30 }
  },
  "bot": {
    "defaults": { "permissions": { "bot": "readonly", "bot.messages.send": "allow" } },
    "profiles": { "shop": { "sendsPerHour": 200 } }
  }
}
  • defaults — всем профилям, и личным аккаунтам, и ботам.
  • profiles.<имя> — одному профилю, в какой бы роли он ни работал.
  • personal.defaults, personal.profiles.<имя> — только командам личного аккаунта.
  • bot.defaults, bot.profiles.<имя> — только командам max <имя> bot ….
ПолеЧто делаетЧто перекрывает на один запускПо умолчанию
defaultProfileкакой профиль, если первым словом ничего не названо и MAX_PROFILE не заданпервое слово (max work …), MAX_PROFILEdefault
embeddingProviderлокальная модель (local, по умолчанию) или openai--providerlocal
embeddingModelмодель векторов--modelпо сервису
embeddingBaseUrlадрес API векторов--base-urlпо сервису
embeddingDimsразмер вектора, целое 1–65 536--dimsпо модели
analysisProviderагент (agent), openai или anthropicbuild --provideragent
analysisModelмодель анализаbuild --modelнет; для --analyze задайте явно
analysisBaseUrlадрес API анализаbuild --base-urlпо сервису
limitсколько записей показывать, когда --limit не передан--limit20
timeoutMsсколько ждать ответа на один запрос— (--timeout — другое, см. ниже)берётся из транспорта
colorцвет в терминале; без поля решается по тому, терминал ли это—; без поля цвет выключает NO_COLORпо терминалу
senderColorsв max messages свой цвет у каждого автора; вы — всегда голубым. Без color не действует. Только для личного аккаунта—false
searchCatchUpПосле store fetch или ремонта разрывов подготавливает граф и установленные локальные векторы этого чата в заданных пределах. Модели не скачиваются, удалённые провайдеры не вызываются--catch-up, --no-catch-upfalse
catchUpMarksReadmax inbox и max review отмечают прочитанным каждый показанный чат — до последнего показанного сообщения. Собеседник видит отметку. Только для личного аккаунта--mark-read, --no-mark-readfalse
recordзаписывать ли каждый запуск, как будто передан --record--record, --no-recordfalse
permissionsуровни прав по ресурсам и командам: deny, readonly, ask, allow; более точный ключ имеет приоритет—; --yes и --allow-dangerous только отвечают на ask, deny они не снимаютпочти всё allow; удаление сообщений и завершение других сессий — ask, автоответы replies.send — deny
serveзапускать ли max serve в фоне, когда команде нужен MAX, а сервера нет. С MAX_TOKEN сервер не запускается. Только для личного аккаунта--serve, --no-servetrue
keepRunsForDaysсколько дней хранятся записи запусков—30
readOnly, allow, mcpToolsстарые настройки, читаются для совместимости; config migrate переводит их в permissions—после миграции изменять их нельзя
sendsPerHourсколько сообщений профиль может отправить за час — вместе с пересылками, правками, закреплениями с уведомлением, удалёнными сообщениями и добавленными в группы людьми; сверх — отказ с кодом 8. Боту лимит задаётся только в разделе bot; без него бот не ограничен—30, у бота — нет
requestsPerMinuteсколько запросов в минуту профиль делает к MAX — после первых 10 подряд, вместе во всех процессах этого профиля; 0 — без ограничения. Переменная MAX_REQUESTS_PER_MINUTE действует сильнее файла (limits.md)MAX_REQUESTS_PER_MINUTE20
readOtherBotsможет ли бот читать копии других ботов, когда команда просит это --all-bots или --bots: false, true — всех, или список профилей ботов. Только в разделе bot—; --all-bots и --bots просят, поле разрешаетfalse
updateCheckраз в сутки спрашивать npm, нет ли новой версии, и сказать об этом в терминале. Только в defaults: версия у программы одна на все профили—; выключают MAX_NO_UPDATE_CHECK, NO_UPDATE_NOTIFIER, CItrue
skillHintраз в сутки говорить агенту в stderr, что навыка max у него нет или он старше программы и что его ставит max skill install. Агента узнаём по переменной AI_AGENT или CLAUDECODE. Только в defaults—true
transcribeModelкакой моделью max messages transcribe распознаёт речь. Только в defaults--model у messages transcribe и рядом с --transcribegigaam-v3

⚠ timeoutMs и --timeout — разные вещи, и перепутать их дорого. timeoutMs — это сколько ждать один ответ от MAX. --timeout — сколько отведено команде целиком. Одно чтение это подключение, INIT, LOGIN, разбор имени чата и сам запрос, поэтому время работы кратно timeoutMs и никогда ему не равно.

Записываются они по-разному нарочно, чтобы их нельзя было спутать: timeoutMs — число миллисекунд в файле, --timeout — длительность с единицей на командной строке (30s, 2m, 500ms). Единица обязательна: --timeout 30 отвергается, потому что рядом лежит поле в миллисекундах, а все остальные программы пишут так секунды — ошибиться можно в тридцать раз в любую сторону.

Поля для --timeout в файле нет: бюджет на команду — это про конкретный запуск, а не про привычку.

--page и --all поля не имеют, и это намеренно. Номер страницы, записанный в файл, нужен ровно один раз и потом мешает каждому следующему запуску. То же про --order у max contacts list: настройка contactOrder была бы вторым написанием того же самого. --limit поле имеет, потому что «сколько показывать» — это привычка, а не разовый выбор.

Секрет в этот файл положить некуда. В схеме нет ни поля для токена, ни для телефона, ни для идентификатора чата: схема, в которой нет места секрету, надёжнее правила «не кладите сюда секрет».

Изменить, не открывая файл

max config set limit 50                 # профилю по умолчанию
max work config set record true         # профилю work
max config set keepRunsForDays 7 --defaults   # всем профилям сразу
max work config unset limit             # убрать; снова решает defaults или встроенное
max agent config set permissions.messages readonly  # чтение сообщений без записи
max shop config set --bot sendsPerHour 200    # только боту shop
max config set --personal --defaults limit 30 # всем личным аккаунтам
max config set defaultProfile work      # какой профиль без первого слова

Значение проверяется той же схемой, что и при чтении, до записи: max config set limit 0 откажет, и файл останется прежним. serve, senderColors, catchUpMarksRead, searchCatchUp и mcpTools с --bot не принимаются: у бота нет ни сервера, ни цветов авторов, ни непрочитанного, а старое mcpTools относится только к личному аккаунту.

searchStemmers.cyrillic (russian или none) и searchStemmers.latin (spanish, english или none) хранятся не в файле настроек, а в общем архиве сообщений: они одни на все профили и на оба мессенджера. Поэтому --defaults, --personal и --bot с ними не принимаются, а под MAX_PROFILE_LOCK их менять нельзя. config unset возвращает встроенное значение. После смены выполните max store reindex — см. Обслуживание архива.

Опечатка — это ошибка, а не умолчание

Неизвестное поле отвергается с именем поля и кодом configuration_error (возврат 3):

{"error":{"code":"configuration_error","message":"/home/you/.config/max-cli/config.json is not a valid config:\n  profiles.default.limitt: unknown setting — the known ones are limit, timeoutMs, color, record, keepRunsForDays, readOnly, allow, permissions, sendsPerHour, senderColors, serve, mcpTools"}}

Значение не того вида называет поле и то, что допустимо: profiles.default.limit: has to be a whole number, 1 or more, not "20".

Так сделано намеренно. Схема, которая молча выбрасывает непонятное поле, превращает опечатку в полдня недоумения: настройка «не работает», и никто не говорит почему.

Отсутствующий файл — не ошибка: это программа, которую не настраивали.

Посмотреть, что получилось

Настройки решаются в несколько слоёв, и разобрать по файлу, какой из них победил, трудно. Поэтому есть команда, которая говорит это прямо:

max config show
max config show --json

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

⚠ В списке профилей — все, что есть на машине: названные в файле, со входом личным аккаунтом и с ботом, и у каждого — личный он, бот или оба.

⚠ Это не проверка здоровья. Она читает файлы: не открывает кеш, не трогает ключницу и не связывается с MAX. Вопрос «жива ли сессия» стоит одного входа и относится к другой команде.

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

ПеременнаяЧто делает
MAX_PROFILEпрофиль на всю сессию оболочки; то же, что первое слово
MAX_PROFILE_LOCKзапирает процесс на одном профиле: другой профиль — первым словом или через MAX_PROFILE — и config set --defaults получают отказ. Держит только там, где агент не может сам поменять окружение: в настройках MCP-клиента или в скрипте-обёртке. Агент с доступом к оболочке снимет переменную сам
MAX_TIMEOUTограничение на команду целиком, на всю сессию оболочки; то же, что --timeout
MAX_TOKENтокен напрямую, в обход ключницы — для CI и разовых запусков
MAX_BOT_TOKENтокен бота для max bot, в обход ключницы
MAX_CONFIG_DIRгде лежат config.json и, при отсутствии ключницы, файл с токеном
MESSAGING_STOREфайл общей локальной копии чатов, сообщений и расшифровок
MAX_STATE_DIRгде лежат состояние профилей и каталог runs/
NO_COLORвыключает цвет, как и в любой другой программе
MAX_NO_UPDATE_CHECK, NO_UPDATE_NOTIFIERне спрашивать npm о новой версии; CI действует так же

Пустая строка — это не значение, а несуществующая переменная: MAX_PROFILE= то же самое, что MAX_PROFILE не задана.

Переменные есть только у профиля и у таймаута. Это две вещи, которые выставляют один раз на процесс. Переменной для --json или для цвета не будет: забытая в оболочке, она меняет вывод команды, которая об этом не просила, — а найти такое потом труднее, чем набрать флаг.

Отдельный набор настроек на время

Переменные каталогов дают отдельные настройки и состояние входа — это удобно для пробы, для второго аккаунта и для тестов. Общая локальная копия сообщений, та же, что у tg, от них не зависит: её отдельный файл задаёт MESSAGING_STORE. Модели речи остаются общими.

export MAX_CONFIG_DIR=/tmp/max-try/config
export MAX_STATE_DIR=/tmp/max-try/state
export MESSAGING_STORE=/tmp/max-try/messages.db

max setup            # этот токен не виден обычной установке
max chats list

⚠ И обратно тоже: обычная установка не видит эту сессию. Именно на этом однажды был потерян час — «нет сессии» при живом токене, потому что переменные остались в одном окне терминала и не были заданы в другом.

Дальше

  • commands.md — каждая команда и опция, и полная таблица кодов возврата
  • sessions.md — как устроены профили и где лежит токен
  • troubleshooting.md — что делать, когда не работает

MAX_CACHE_DIR относится только к прежнему кэшу: max doctor ищет там оставшийся файл. Для совместимости эта переменная всё ещё меняет запись в ключнице; для новой общей копии используйте MESSAGING_STORE.

Настройки векторов и анализа независимы и могут различаться по профилям. Переменные MAX_EMBEDDING_PROVIDER, MAX_EMBEDDING_MODEL, MAX_EMBEDDING_BASE_URL, MAX_EMBEDDING_DIMS, MAX_ANALYSIS_PROVIDER, MAX_ANALYSIS_MODEL, MAX_ANALYSIS_BASE_URL перекрывают конфиг; флаги перекрывают настройки. Адрес — HTTP/S без встроенного пароля, query и fragment. Внешний сервис векторов получает и вопрос из MCP-поиска. Ключи задаются через models text key set openai|anthropic и не записываются в config.json. Обычный build внешнего анализа не запускает: нужен явный --analyze.

Типы и области действия ключей

Область «профиль» включает defaults, profiles.<имя>, personal.defaults, personal.profiles.<имя>, bot.defaults и bot.profiles.<имя>, если строка не сужает её. Неизвестные ключи и значения неверного типа отклоняются. Значения по умолчанию приведены выше.

КлючДопустимый тип или значениеОбласть
defaultProfileстрока с именем профилякорень файла
limit, timeoutMs, keepRunsForDays, sendsPerHourцелое число ≥ 1профиль
requestsPerMinuteцелое число ≥ 0профиль
color, record, readOnlybooleanпрофиль
senderColors, catchUpMarksRead, searchCatchUp, servebooleanличный аккаунт
permissionsобъект путей команд и уровней deny, readonly, ask, allowпрофиль
allowмассив разрешённых действий; старый форматпрофиль
mcpToolsмассив contacts, polls, groups, profile; старый форматличный аккаунт
readOtherBotsboolean или массив имён профилейтолько bot
updateCheck, skillHintbooleanтолько defaults
transcribeModelстроковый id из max models audio listтолько defaults
embeddingProviderlocal или openaiпрофиль
embeddingModel, analysisModelнепустая строка, не более 200 символовпрофиль
embeddingBaseUrl, analysisBaseUrlURL HTTP(S) без credentials, query и fragmentпрофиль
embeddingDimsцелое 1–65 536профиль
analysisProvideragent, openai, anthropicпрофиль
modelsобъект назначений моделей; поля описаны нижепрофиль

Модели по назначению

models.<назначение> содержит только provider, model, baseUrl. Назначение — строчные латинские буквы, цифры и дефисы, с буквы в начале. default задаёт общие значения; analysis и replies переопределяют их по полям. Другие корректные имена можно сохранить заранее: это не включает отсутствующий use case. Без провайдера, либо с off, внешний вызов выключен.

КлючДопустимое значениеПо умолчанию
models.<назначение>.provideroff, openai, anthropicне задан; внешнего вызова нет
models.<назначение>.modelнепустая строка, не более 200 символовне задан; включённому провайдеру нужен явный id
models.<назначение>.baseUrlURL HTTP(S) без credentials, query и fragmentадрес провайдера

В каждом поле сначала действует MAX_MODELS_<НАЗНАЧЕНИЕ>_PROVIDER, _MODEL или _BASE_URL, затем ближайшая запись файла для назначения, затем явные старые analysis* для analysis, затем переменные и записи models.default. Дефисы в имени назначения превращаются в _ для переменной окружения. Токены провайдера не входят в этот объект.

Переменные для настроек моделей

Семь старых полей поддерживают MAX_EMBEDDING_PROVIDER, MAX_EMBEDDING_MODEL, MAX_EMBEDDING_BASE_URL, MAX_EMBEDDING_DIMS, MAX_ANALYSIS_PROVIDER, MAX_ANALYSIS_MODEL, MAX_ANALYSIS_BASE_URL. Они действуют перед значениями файла. MAX_MODELS_DEFAULT_PROVIDER, MAX_MODELS_DEFAULT_MODEL, MAX_MODELS_DEFAULT_BASE_URL задают общие поля нового формата; вместо DEFAULT можно указать назначение, например ANALYSIS. Пустая переменная не переопределяет настройку. Неверное значение возвращает configuration_error.