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
Авторизация
С версии 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, если она всё ещё задана в окружении, не
читается как credential ни на одном шаге — CLI печатает об этом одно предупреждение
на stderr при каждом вызове и продолжает работу на сессионном токене.
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 # жива ли авторизация — реальный запрос, не имитация
Путь переопределяется переменной KTALK_TOKEN_FILE; каталог уважает XDG_CONFIG_HOME.
Порядок источников — первый непустой выигрывает:
| # | Источник | Комментарий |
|---|---|---|
| 1 | KTALK_SESSION_TOKEN (окружение или .env в рабочей директории) |
заданное явно сильнее лежащего на диске |
| 2 | ~/.config/ktalk-mcp/token |
дефолтный путь для повседневной работы |
Ни один запрос не несёт заголовок 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 -перезаписывает файл, права переставлять не нужно.
Переменные окружения
export KTALK_SESSION_TOKEN="ваш_session_token"
export KTALK_BASE_URL="https://your-domain.ktalk.ru"
Переменная не обязательна: без неё читается файл ~/.config/ktalk-mcp/token
(см. «Session token»).
Также поддерживается файл .env в рабочей директории:
KTALK_SESSION_TOKEN=ваш_session_token
KTALK_BASE_URL=https://your-domain.ktalk.ru
Диагностика авторизации
Проверьте авторизацию без запроса записей:
ktalk auth-status
Диагностика различает два случая, которые снаружи выглядят одинаково — просто ошибка, — но чинятся по-разному:
- 401 — токен невалиден либо истёк. Обновите его:
ktalk token set -(или переменнуюKTALK_SESSION_TOKEN, если она задана). - 403 — токен рабочий, но у текущей сессии нет прав на эту операцию. Перевыпускать токен не нужно.
У 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 > переменная KTALK_REGISTRY_DB > дефолт
95_TRANSCRIPTS/.registry.db (относительно текущего каталога). Бинарную БД
нужно добавить в .gitignore (.registry.db, .registry.db-wal, .registry.db-shm).
ktalk auth-status, ktalk create-meeting-preview и ktalk create-meeting-confirm
реестр не открывают вовсе — им он не нужен. В частности, auth-status работает
даже если файла базы данных нет или он недоступен. Планирование встречи —
отдельный раздел «Планирование встречи» выше.
| Команда | Назначение |
|---|---|
ktalk sync [--days 7] [--json] [--dry-run] |
Загрузить записи из KTalk, upsert новых (new), экспирировать new старше N дней → skipped, показать дашборд. Идемпотентно. --dry-run — сверить id с реестром без записи, ничего не пишет. |
ktalk token set <значение|-> |
Записать session-токен в ~/.config/ktalk-mcp/token (0600). - — прочитать из stdin: pbpaste | ktalk token set -. Значение не печатается. |
ktalk token status [--json] |
Есть ли файл токена, его права и маска значения. |
ktalk auth-status [--json] |
Диагностика активной авторизации — жив ли токен. См. «Диагностика авторизации». |
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 (session token — см. «Авторизация»)
KTALK_SESSION_TOKEN=... KTALK_BASE_URL=... 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 3.0.2
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-3.0.2.tar.gz | 228.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ktalk_cli-3.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 344.4 kB
Release files / ktalk_cli-3.0.2.tar.gz
| Download URL | ktalk_cli-3.0.2.tar.gz |
|---|---|
| Size | 228.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c9e71eaa60a28e190f4e7684b85e219e6e2452a41379df94282e54a800b2cfa2
|
|
BLAKE2b-256 checksum How to use checksums |
264a8d35a2a3e818a179b5ddeaf2ef3b5e2fd169421c95607f2fcd14a504e96e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / ktalk_cli-3.0.2-py3-none-any.whl
| Download URL | ktalk_cli-3.0.2-py3-none-any.whl |
|---|---|
| Size | 115.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2d59f9c1ddc5123894dae245553ea03e9a258dd03cfa07d5b3bbeec92b39e2da
|
|
BLAKE2b-256 checksum How to use checksums |
b9485ec8341f1b2d1b69fc0b724b76819f531abbb899c12fe730f2da720000ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|