ktalk-cli
CLI ktalk — интерфейс командной строки для тех, кто работает с записями видеовстреч
Контур.Толк (KTalk) программно: читает записи, транскрипты и саммари,
управляет расписанием, ведёт локальный реестр обработки записей на SQLite. Годится и как
самостоятельный инструмент, и как предусловие плагина Claude Code ktalk — подробнее в
разделе «Пакет и плагин Claude Code» ниже.
Раньше пакет назывался
ktalk-mcpи, помимо CLI, поднимал MCP-сервер для Claude Code (инструменты видаktalk_list_recordings). Этот слой снят целиком — MCP в пакете больше нет, единственная точка входа — командаktalk. Пришли по старой ссылке или ищетеktalk-mcp— это тот же проект под новым именем, старый пакет дальше не развивается (о конфликте имени команды при апгрейде — ниже, в «Установке»).
Умеет:
- Список записей конференций и детали одной записи.
- Транскрипты (речь по спикерам с таймкодами, с чанкингом для длинных).
- Саммари и протоколы встреч.
- Полный состав участников записи (обходит лимит в 6 из списковых ответов).
- Скачивание видеофайла записи.
- Историю чата встречи.
- Конфигурацию комнаты и календарь запланированных встреч.
- Предпросмотр и создание новой встречи — создание требует интерактивного терминала и явного подтверждения, см. «Планирование встречи» ниже.
- Диагностику авторизации — жив ли токен и почему запрос не проходит.
- Операционный реестр обработки записей на SQLite — синхронизация, статусы, markdown-зеркало для git, см. «Реестр записей» ниже.
Установка
Требуется Python 3.12+ и uv.
uv tool install ktalk-cli
Или через pip:
pip install ktalk-cli
Если на машине уже стоит старый ktalk-mcp (он тоже владел командой
ktalk), uv tool install ktalk-cli откажет: uv не отдаёт занятое имя
команды второму пакету молча. Сначала освободите имя:
uv tool uninstall ktalk-mcp
uv tool install ktalk-cli
Проверка версии — после установки или обновления:
ktalk --version # печатает, например: ktalk-cli 2.1.0
Обновление до последней версии — та же команда install, только upgrade:
uv tool upgrade ktalk-cli
Авторизация
С версии 4.0.0 конфигурация каждого значения имеет ровно один источник
(ADR-027): session token — только файл, записанный ktalk token set; адрес
стенда — только config.toml, записанный ktalk config set base-url. Ни одна
переменная KTALK_* и ни один .env в рабочем каталоге больше не читаются как
источник значения — их присутствие не проходит молча: ktalk auth-status,
ktalk doctor и тексты отказов называют обнаруженную снятую переменную по
имени (значение не печатается никогда) и советуют её убрать.
С версии 3.0.0 CLI работает только через session token (кука браузера) — режим
персонального API-ключа (KTALK_PERSONAL_API_KEY) снят целиком (ADR-025): он
конкурировал с сессией молча (при обеих заданных переменных побеждал ключ без
объяснения в тексте отказа) и диагностика auth-status объявляла заведомо
невалидный ключ «валидным» на 403.
Цена снятия для тех, кто держал постоянный ключ: персональный ключ не протухал
без предупреждения, session token — протухает. Постоянная работа теперь требует
ручного обновления токена по мере его протухания (ktalk token set -, см. ниже) —
это не восстанавливается автоматически снятием ключа.
Переменные KTALK_PERSONAL_API_KEY, KTALK_SESSION_TOKEN и остальные
KTALK_*, если они всё ещё заданы в окружении (частая причина — блок env в
~/.claude/settings.json), не читаются ни на одном шаге — CLI печатает об этом
одно предупреждение на stderr при каждом вызове и продолжает работу на файле
токена/config.toml.
Session token
Session token — токен вашей браузерной сессии Толка. Единственный поддерживаемый источник credential (ADR-025). Живёт недолго и протухает без предупреждения — при регулярной работе повторяйте те же два шага ниже, когда команда начнёт отказывать кодом авторизации.
Два шага. На вкладке, где вы залогинены в https://your-domain.ktalk.ru, откройте
DevTools (F12, или Cmd+Option+I на Mac) → Console и выполните:
copy(JSON.parse(localStorage.session).data.token)
Токен — в буфере обмена. Положите его в файл одной командой:
pbpaste | ktalk token set - # macOS
xclip -o | ktalk token set - # Linux (X11)
Команда сама создаёт ~/.config/ktalk-mcp/token с правами 0600 (каталог — 0700),
отвергает значение, не похожее на токен, и никогда не печатает его в вывод. Проверка:
ktalk token status # есть ли файл, права, маска значения
ktalk auth-status # жива ли авторизация — реальный запрос, не имитация
Путь файла — ${XDG_CONFIG_HOME:-~/.config}/ktalk-mcp/token; переменной-
переопределения нет (снятая KTALK_TOKEN_FILE не читается, ADR-027).
Единственный источник токена — этот файл (ADR-027). Переменная
KTALK_SESSION_TOKEN и .env в рабочем каталоге не читаются вовсе: заданная
переменная больше не перекрывает файл ни молча, ни с предупреждением — она
просто не участвует в разрешении credential, а CLI называет её в выводе
auth-status/doctor как снятую.
Ротация больше не может «застрять» на невидимой переменной:
ktalk token set -перезаписывает файл, и следующий же вызов читает новое значение. Разводка источников из старых установок (переменная против файла, рунбук OPS-003) снята самим устройством 4.0.0 — переменную достаточно убрать из окружения.
Ни один запрос не несёт заголовок X-Auth-Token — единственный транспорт credential
теперь query-параметр sessionToken.
Путь
~/.config/ktalk-mcp/tokenне переименован вместе с пакетом и остаётся таким намеренно: он выбран независимо от имени дистрибутива (каталогktalk/уже занят другим — санкцией на запись, у неё свой жизненный цикл), а смена пути молча лишила бы уже настроенные машины третьего источника авторизации.
Токен из файла обслуживает и чтение, и запись: создание и отмена встречи шлют то же
значение другим транспортом (заголовок Authorization: Session, а не query-параметр) —
источник значения транспорт не меняет. Санкция на запись при этом остаётся обязательной,
она к токену отношения не имеет.
Файл с правами шире 0600 читается так, будто его нет (ktalk token status покажет
usable: False) — секрет не должен молча читаться с диска, доступного другим
пользователям машины.
Важно: session token имеет ограниченный срок жизни. Если команда возвращает ошибку авторизации, повторите те же два шага —
ktalk token set -перезаписывает файл, права переставлять не нужно.
Конфигурация: адрес стенда (config.toml)
Адрес контура задаётся один раз, машинной командой:
ktalk config set base-url https://your-domain.ktalk.ru
Команда пишет ${XDG_CONFIG_HOME:-~/.config}/ktalk-mcp/config.toml (рядом с
файлом токена, права 0644 — адрес не секрет) и отвергает значение без схемы
http(s) или без хоста до записи. Проверка — ktalk config show: секция
## Толк называет адрес, путь config.toml и статус файла токена.
Переменные окружения и .env больше не читаются вовсе (4.0.0, ADR-027).
KTALK_BASE_URL, KTALK_SESSION_TOKEN, KTALK_PERSONAL_API_KEY,
KTALK_REGISTRY_DB, KTALK_TOKEN_FILE и .env в рабочем каталоге не
участвуют в разрешении ни одного значения. Если какая-то из них всё ещё задана,
ktalk auth-status и ktalk doctor называют её по имени и советуют убрать —
значение при этом не печатается никогда.
Диагностика авторизации
Проверьте авторизацию без запроса записей:
ktalk auth-status
Диагностика различает два случая, которые снаружи выглядят одинаково — просто ошибка, — но чинятся по-разному:
- 401 — токен невалиден либо истёк. Вердикт
alive: false, код возврата1. Обновите токен:ktalk token set -— файл перезаписывается, права переставлять не нужно. - 403 — токен рабочий, но у текущей сессии нет прав на эту операцию. Вердикт
alive: true, код возврата0: нехватка прав не является отказом токена, и перевыпускать его не нужно.
У session token понятия scope и срока действия нет — диагностика выполняет реальный пробный запрос (список записей), а не имитацию без сети.
--json-ответ — {"alive": bool, "note": str | None}. Отказ пробного запроса виден
по обоим каналам сразу: поле alive: false в теле ответа И ненулевой код возврата
процесса — полагаться только на один из двух нельзя.
Команды чтения записей и справочников
Все команды поддерживают --json (валидный JSON в stdout; ошибки — в stderr с
ненулевым кодом возврата).
Коды возврата
| Код | Значение |
|---|---|
0 |
Успех. |
1 |
Отказ вызова — сеть, сервер, конфигурация. |
2 |
Usage error — неверные аргументы CLI (argparse). |
3 |
Только ktalk get-transcript. Данные получены и напечатаны полностью, но независимая сверка идентичности не сошлась (identity_check.result == "mismatch") — состав участников транскрипта разошёлся с составом записи. Это не сбой команды: код 3 отличает «данные есть, но сверка не сошлась» от 0 (сошлось или не проверялось) и от 1/2 (данных нет вовсе). Подробности — в самом теле ответа, поле identity_check (ADR-024 §Д1). |
| Команда | Назначение |
|---|---|
ktalk list-recordings [--query Q] [--start-from ISO] [--start-to ISO] [--top N] [--order O] [--page-token T] |
Список записей. --top 1–1000 (по умолчанию 30); --order: byTimeNewFirst (умолчание), byTimeOldFirst, byTitle, bySizeBigFirst, bySizeSmallFirst. |
ktalk get-recording <recording_key> |
Детали записи — автор, дата, длительность, участники (список ограничен 6, полный состав — get-participants). |
ktalk get-transcript <recording_key> [--chunk N] [--chunk-size N] |
Транскрипт по спикерам с таймкодами. Длинный транскрипт режется на чанки по границам реплик: --chunk 0 (умолчание) — целиком или первый чанк; --chunk-size — макс. символов в чанке (умолчание 30000, ~7500 токенов). Независимая сверка идентичности включена по умолчанию (--no-verify-identity отключает); --chunk вне диапазона сверку по сети не запускает вовсе, identity_check.result == "not_checked"/reason: "chunk_out_of_range". |
ktalk get-summary <recording_key> |
Полное саммари (краткое резюме + протокол). |
ktalk get-summary-type <recording_key> --type shortSummary|protocol |
Саммари одного типа. |
ktalk get-participants <recording_key> |
Полный состав участников, включая анонимных — обходит лимит в 6, который отдают get-recording/list-recordings. |
ktalk download-recording <recording_key> --target PATH [--quality Q] |
Скачивает видеофайл потоково, без буферизации в памяти. Существующий файл не перезаписывается; --quality не указано — берётся дефолт для записи (например 900p). |
ktalk list-archive --from ISO --to ISO [--room-name N] |
Архив встреч за период. Недоступна — архив никогда не имел рабочего пути под session token; команда отказывает до сети с явным сообщением на каждый вызов (ADR-025). |
ktalk get-chat-messages [--recording-key K | --conference-key K] [--channel C] |
Сообщения чата встречи; один из двух ключей обязателен. Канал не указан — определяется автоматически. |
ktalk get-room <room_name> |
Конфигурация комнаты — политики аудио/видео/демонстрации, модераторы, SIP, чат, маскирование. Побочный эффект: если комнаты с таким именем ещё нет, она создаётся. |
ktalk list-calendar --start ISO --end ISO [--room-name N] |
Встречи за окно дат, видимые активной авторизации — это не «ваш личный календарь», а всё, что видит текущая авторизация, включая чужие встречи. Сервер лимитирует один запрос семью днями и сотней встреч на сегмент — команда сама режет произвольное окно на сегменты; при упоре в потолок ответ предупреждает о возможно неполной выдаче. |
Планирование встречи
Создание встречи — единственная операция пакета, которая что-то меняет вне вашего компьютера: она рассылает приглашения реальным людям. Удаление созданного события эти письма не отзывает. Из-за этого создание устроено умышленно неудобно:
- Создание — команда
ktalk create-meeting-confirm. Она работает только в интерактивном терминале (проверяет, что и ввод, и вывод — реальный TTY) и перед отправкой печатает предпросмотр и требует набрать словода. - Предпросмотр без создания —
ktalk create-meeting-preview, не делает ни одного сетевого запроса. - Обе команды используют session token — единственный оставшийся режим авторизации (ADR-025).
Ни одно поле не имеет значения по умолчанию (кроме описания встречи — пустая строка, если не задано). Тема, начало, конец, часовой пояс, комната, участники, анонимный доступ, PIN — каждое нужно передать явно; иначе команда откажет и назовёт, какого поля не хватает. Так сделано намеренно: молчаливый часовой пояс сдвинет встречу в календаре участников на другое время, а молчаливая автозапись незаметно для организатора изменит, записывается ли встреча.
Из этого вытекают практические следствия:
- Часовой пояс принимает только форму
GMT±N(примерGMT+3) — IANA-имена видаEurope/Moscow, смещения ISO и аббревиатуры сервер не распознаёт. --enable-auto-recordingи--allow-anonymousпринимают только явныеtrueилиfalse— «флаг просто не указан» не считается ответом.- «Встреча без обязательных участников» — это отдельный флаг
--no-required-attendees, а не просто отсутствие--required-attendee-key. Значение--required-attendee-key— числовой id участника, не логин. - «Без PIN» — отдельный флаг
--no-pin-code, а не пустая строка в--pin-code. --anonymous-access-expirationобязателен, только если--allow-anonymous true.
Повторяющиеся встречи в этой версии не поддерживаются — можно создать только разовое событие.
При сетевом сбое во время создания команда не повторяет запрос сама: если сеть
оборвалась, неизвестно, ушло приглашение или нет, и автоматический повтор рискует
создать дубль. Решение о повторной попытке — за вами; перед ней стоит проверить
ktalk list-calendar, не появилась ли встреча уже.
Создание встречи ещё ни разу не выполнялось на боевом окружении — команда реализует задуманное поведение, но не проверена живым вызовом.
# Предпросмотр — без сети, без побочных эффектов
ktalk create-meeting-preview \
--subject "Синк по проекту" \
--start 2026-08-20T10:00:00 --end 2026-08-20T10:30:00 --timezone GMT+3 \
--room-name "Переговорная 1" \
--no-required-attendees \
--enable-auto-recording false --allow-anonymous false \
--no-pin-code
# Создание — только в интерактивном терминале, требует ввода "да"
ktalk create-meeting-confirm \
--subject "Синк по проекту" \
--start 2026-08-20T10:00:00 --end 2026-08-20T10:30:00 --timezone GMT+3 \
--room-name "Переговорная 1" \
--required-attendee-key 123 --required-attendee-key 456 \
--enable-auto-recording false --allow-anonymous false \
--no-pin-code
API
CLI работает с KTalk Web API через единственный (session token) режим авторизации
(см. «Авторизация» выше) — query-параметр sessionToken, внутренний недокументированный
контур API:
| Эндпоинт | Описание |
|---|---|
GET /api/recordings |
Список записей |
GET /api/recordings/{id} |
Детали записи |
GET /api/recordings/{id}/transcript |
Транскрипт |
GET /api/recordings/v2/{id}/summary |
Полное саммари (v2) |
GET /api/recordings/{id}/summary/{type} |
Саммари по типу |
Архив встреч (list-archive) недоступен: под session token у него нет и никогда не
было рабочего пути (ADR-025) — команда отказывает до сети с явным сообщением.
OpenAPI спецификация
talk.public.api-api-2.jsonвключена как справочник, но содержит расхождения с реальным API (пути, формат авторизации, структура ответов). Пути, достижимые только под снятым режимом персонального ключа (X-Auth-Token), больше не применимы к этому CLI.
Реестр записей (ktalk)
Та же команда ktalk ведёт операционный реестр обработки записей на SQLite.
Вся детерминированная механика (синхронизация списка записей, дедуп,
смена статусов, рендер дашборда и markdown-зеркала, разовая
миграция) живёт в коде, а не в рассуждениях модели.
SQLite — операционный source of truth. Markdown-файл registry.md —
генерируемое read-only зеркало для git (ktalk export), руками не редактируется.
Путь к базе: флаг --db PATH > registry.db_path из .ktalk.toml
проекта-хозяина > машинный дефолт централизованного хранилища (ADR-013;
переменная KTALK_REGISTRY_DB снята в 4.0.0 и не читается, ADR-027).
ktalk auth-status, ktalk create-meeting-preview и ktalk create-meeting-confirm
реестр не открывают вовсе — им он не нужен. В частности, auth-status работает
даже если файла базы данных нет или он недоступен. Планирование встречи —
отдельный раздел «Планирование встречи» выше.
| Команда | Назначение |
|---|---|
ktalk sync [--days N] [--json] [--dry-run] |
Загрузить записи из KTalk и upsert'нуть их в реестр (новые — new, существующие — с обновлёнными не-статусными полями; статус ни одной записи не меняется). Без --days окно — от момента последней синхронизации минус 1 день запаса (первый запуск — 90 дней); --days N — явное переопределение нижней границы. Идемпотентно. --dry-run — сверить id с реестром без записи, ничего не пишет. В --json-ответе ключа expired больше нет (4.0.0): смены статуса как побочного эффекта чтения не происходит. |
ktalk token set <значение|-> |
Записать session-токен в ~/.config/ktalk-mcp/token (0600). - — прочитать из stdin: pbpaste | ktalk token set -. Значение не печатается. |
ktalk token status [--json] |
Есть ли файл токена, его права и маска значения. |
ktalk auth-status [--json] |
Диагностика активной авторизации — жив ли токен. См. «Диагностика авторизации». |
ktalk config set base-url <url> |
Записать адрес стенда в ~/.config/ktalk-mcp/config.toml (0644). См. «Конфигурация: адрес стенда». |
ktalk config show [--json] |
Машинная конфигурация оператора (адрес, путь config.toml, статус файла токена) и резолвленный .ktalk.toml проекта-хозяина. |
ktalk dashboard [--json] |
Дашборд: новые записи, статистика по статусам. |
ktalk list [--status S] [--json] |
Список записей с фильтром по статусу. |
ktalk show <id> [--json] |
Детали записи: участники, статус, пути, длительность. |
ktalk mark-processing <id> |
Перевести в processing. |
ktalk mark-done <id> --transcript P --protocol P [--type T] |
Завершить, проставить пути и processed_at. |
ktalk mark-partial <id> [--transcript P] [--protocol P] |
Частичная обработка. |
ktalk mark-skipped <id> |
Пропустить вручную. |
ktalk set-vault-id <id> <ktalk_id> <vault_id> |
Привязать профиль к участнику. |
ktalk export [--out PATH] [--full] |
Сгенерировать markdown-зеркало. |
ktalk migrate <vault> [--dry-run] [--json] |
Разовый импорт из markdown-реестров. |
Несколько фоновых агентов могут безопасно писать параллельно (WAL + busy_timeout
- транзакция на операцию).
Разработка
git clone https://github.com/mdemyanov/ktalk-cli.git
cd ktalk-cli
uv sync
# Запуск тестов
uv run pytest -v
# Линтинг
uv run ruff check .
# Локальный запуск CLI (токен и адрес — файлами, см. «Авторизация»)
pbpaste | uv run ktalk token set -
uv run ktalk config set base-url https://your-domain.ktalk.ru
uv run ktalk auth-status
Пакет и плагин Claude Code
ktalk-cli работает и сам по себе, и как предусловие плагина Claude Code ktalk. Плагин не
обращается к KTalk напрямую и не поднимает MCP-сервер — он вызывает эту же команду ktalk
как единственную точку входа в контур.
Плагин пинует точную версию пакета (не нижний порог: «ровно эта версия», не «эта или новее») в собственном файле совместимости. Если что-то в интеграции с плагином ведёт себя не так, как описано в его документации, — первым делом сверьте версию:
ktalk --version # см. «Проверка версии» в разделе «Установка»
Версия не совпадает с той, что требует плагин, — обновите пакет тем же способом, что при
установке (uv tool upgrade ktalk-cli, см. «Установка»); не совпадает в другую сторону
(пакет новее, чем ожидает плагин) — не откатывайте его самостоятельно, сверьтесь с тем, кто
настраивал плагин.
Проблемы и вопросы
Нашли баг, некорректное поведение или неточность в документации — заведите issue в этом репозитории: https://github.com/mdemyanov/ktalk-cli/issues.
Лицензия
MIT
Release files for ktalk-cli 4.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ktalk_cli-4.0.0.tar.gz | 265.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ktalk_cli-4.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 393.5 kB
Release files / ktalk_cli-4.0.0.tar.gz
| Download URL | ktalk_cli-4.0.0.tar.gz |
|---|---|
| Size | 265.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6fe2bc97628348b73c860bcffe22ef4876b966b11a8a371f7043ddb7e9e5ecfc
|
|
BLAKE2b-256 checksum How to use checksums |
ca8d9cbbac019075c4b6b6cb38670578a8f7969b1bcdc2167bfa70fab14dc9b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Release files / ktalk_cli-4.0.0-py3-none-any.whl
| Download URL | ktalk_cli-4.0.0-py3-none-any.whl |
|---|---|
| Size | 128.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5a030199a3e8f21919cdfa25c67c5f325106044829c431707be2f46b3a0d714c
|
|
BLAKE2b-256 checksum How to use checksums |
b3620ee207374379af6c56c68d2731b15216c80875fb118c3b1242c73ab0d6da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|