kaiten-mcp
MCP-сервер для Kaiten — предоставляет 246 инструментов для работы с Kaiten API через протокол Model Context Protocol.
Поддерживает два transport-а:
stdioдля локального подключения из Claude Code / Claude DesktopHTTPдля удалённого deployment-а в Docker
Возможности
| Область | Модуль | Кол-во | |---------|--------|--------| | Карточки | cards | 8 | | Комментарии | comments | 4 | | Участники карточек | members | 5 | | Логи времени | time_logs | 4 | | Теги | tags | 6 | | Чеклисты | checklists | 8 | | Блокировки | blockers | 5 | | Связи карточек | card_relations | 9 | | Внешние ссылки | external_links | 4 | | Файлы карточек | files | 4 | | Подписчики | subscribers | 6 | | Пространства | spaces | 5 | | Доски | boards | 5 | | Колонки и подколонки | columns | 8 | | Дорожки | lanes | 4 | | Типы карточек | card_types | 5 | | Кастомные свойства | custom_properties | 10 | | Документы | documents | 10 | | Вебхуки | webhooks | 9 | | Автоматизации и воркфлоу | automations | 11 | | Проекты и спринты | projects | 13 | | Роли и группы | roles_and_groups | 14 | | Аудит и аналитика | audit_and_analytics | 11 | | Service Desk | service_desk | 47 | | Графики и аналитика | charts | 15 | | Дерево сущностей | tree | 2 | | Утилиты | utilities | 14 | | Итого | 27 модулей | 246 |
Требования
- Docker или Python >= 3.11
- Аккаунт Kaiten с API-токеном
Переменные окружения
| Переменная | Обязательна | Описание | |------------|-------------|----------| | KAITEN_SUBDOMAIN | Да | Поддомен компании (yourcompany для yourcompany.kaiten.ru) | | KAITEN_BASE_DOMAIN | Нет | Базовый домен, по умолчанию kaiten.ru | | KAITEN_BASE_URL | Нет | Полный override URL API-хоста; имеет приоритет над KAITEN_SUBDOMAIN/KAITEN_BASE_DOMAIN | | KAITEN_DOMAIN | Нет | Устаревший fallback для обратной совместимости вместо KAITEN_SUBDOMAIN | | KAITEN_TOKEN | Да | API-токен пользователя Kaiten для локального stdio или legacy shared HTTP | | MCP_HTTP_HOST | Нет | Хост для HTTP transport (по умолчанию 0.0.0.0) | | MCP_HTTP_PORT | Нет | Порт для HTTP transport (по умолчанию 8000) | | MCP_HTTP_BASE_PATH | Нет | Базовый путь HTTP transport (по умолчанию /mcp) | | MCP_HTTP_AUTH_MODE | Нет | oauth, shared или none; для production shared server используйте oauth | | MCP_PUBLIC_URL | Да | Публичный URL MCP endpoint, например https://mcp.example.com/mcp | | MCP_OAUTH_ISSUER_URL | Да | Публичный URL auth/onboarding сервера, например https://mcp.example.com | | MCP_RESOURCE_METADATA_URL | Нет | Override URL OAuth protected-resource metadata | | MCP_ALLOWED_ORIGINS | Нет | Comma-separated allowlist browser origins для Streamable HTTP | | MCP_REQUIRED_SCOPES | Нет | OAuth scopes для MCP access token, по умолчанию kaiten:tools | | MCP_AUTH_TOKEN | Нет | Legacy shared bearer token для single-tenant HTTP endpoint |
Для локального stdio заполняйте KAITEN_TOKEN и ровно один способ настройки хоста:
KAITEN_SUBDOMAINдля обычного*.kaiten.ruKAITEN_SUBDOMAIN+KAITEN_BASE_DOMAINдля кастомного доменаKAITEN_BASE_URLдля полного override
KAITEN_BASE_URL нужен для нестандартных доменов и стендов. Примеры:
KAITEN_SUBDOMAIN=yourcompany->https://yourcompany.kaiten.ru/api/latestKAITEN_SUBDOMAIN=kaiten+KAITEN_BASE_DOMAIN=kaiten.ru->https://kaiten.kaiten.ru/api/latestKAITEN_BASE_URL=https://kaiten.kaiten.ru->https://kaiten.kaiten.ru/api/latest
Для локального запуска через Python сервер читает .env через load_dotenv(). Переменные процесса имеют приоритет над .env.
Быстрый старт с .env:
cp .env.example .env
Потом откройте .env и оставьте только подходящий вам вариант host-конфига.
Для shared HTTP deployment с MCP_HTTP_AUTH_MODE=oauth пользовательский KAITEN_TOKEN не задаётся в .env: пользователь вводит свой Kaiten domain и API key на onboarding-странице, ключ хранится только в памяти до expiry сессии.
Подключение к Claude Code
Ниже описан локальный stdio режим. Он сохранён и работает как раньше.
Способ 1: Docker (рекомендуется)
Собрать образ (однократно):
docker build -t kaiten-mcp .
Эта команда по умолчанию собирает локальный stdio-образ. Для удалённого HTTP transport используйте отдельный target baked-http.
Зарегистрировать MCP-сервер:
claude mcp add kaiten \
-e KAITEN_SUBDOMAIN=yourcompany \
-e KAITEN_TOKEN=your-api-token \
-- docker run --rm -i -e KAITEN_SUBDOMAIN -e KAITEN_TOKEN kaiten-mcp
Перезапустить Claude Code (/exit и запустить заново) — 246 инструментов Kaiten станут доступны.
Для нестандартного домена добавьте KAITEN_BASE_DOMAIN или KAITEN_BASE_URL:
claude mcp add kaiten \
-e KAITEN_SUBDOMAIN=kaiten \
-e KAITEN_BASE_DOMAIN=kaiten.ru \
-e KAITEN_TOKEN=your-api-token \
-- docker run --rm -i \
-e KAITEN_SUBDOMAIN -e KAITEN_BASE_DOMAIN -e KAITEN_TOKEN kaiten-mcp
Способ 2: Python (venv)
python3 -m venv .venv
.venv/bin/pip install -e .
claude mcp add kaiten \
-e KAITEN_SUBDOMAIN=yourcompany \
-e KAITEN_TOKEN=your-api-token \
-- .venv/bin/kaiten-mcp
Перезапустить Claude Code.
Способ 3: Docker Compose
claude mcp add kaiten \
-e KAITEN_SUBDOMAIN=yourcompany \
-e KAITEN_TOKEN=your-api-token \
-- docker compose --project-directory /path/to/kaiten-mcp run --rm -T kaiten-mcp
Замените /path/to/kaiten-mcp на абсолютный путь к репозиторию.
Важно: Используйте
--project-directory, а не-f. Флаг-fзадаёт только путь к yml-файлу, но build context и.envвсё равно ищутся относительно CWD. Флаг-Tобязателен — без него Docker выделяет pseudo-TTY, что ломает JSON-RPC протокол MCP.
Проверка
claude mcp list
Сервер kaiten должен быть со статусом connected.
Подключение к Claude Desktop
Добавьте в claude_desktop_config.json:
Docker:
{
"mcpServers": {
"kaiten": {
"command": "docker",
"args": ["run", "--rm", "-i", "-e", "KAITEN_SUBDOMAIN", "-e", "KAITEN_TOKEN", "kaiten-mcp"],
"env": {
"KAITEN_SUBDOMAIN": "yourcompany",
"KAITEN_TOKEN": "your-api-token"
}
}
}
}
Python:
{
"mcpServers": {
"kaiten": {
"command": "/path/to/kaiten-mcp/.venv/bin/kaiten-mcp",
"env": {
"KAITEN_SUBDOMAIN": "yourcompany",
"KAITEN_TOKEN": "your-api-token"
}
}
}
}
Важные замечания о Docker и MCP
MCP использует stdio transport (JSON-RPC через stdin/stdout). При запуске через Docker:
- Флаг
-i(--interactive) — обязателен, держит stdin открытым. - Флаг
-t(--tty) — запрещён, TTY-символы ломают протокол. - Для
docker compose run— используйте-T(отключает TTY). .envфайл не нужен — переменные передаются через-eфлаги.- Если используете
KAITEN_BASE_DOMAINилиKAITEN_BASE_URL, их тоже нужно пробросить через-e.
Для удалённого deployment-а есть отдельный HTTP transport. Он не требует -i/-T, потому что работает как обычный web-service.
Удалённый HTTP deployment
HTTP transport запускается отдельно и не заменяет локальный stdio. Для общего сервера на много пользователей используйте MCP_HTTP_AUTH_MODE=oauth. В этом режиме Authorization: Bearer ... — это MCP access token, а не Kaiten API key. Kaiten API key пользователь вводит на onboarding-странице после OAuth redirect.
Для первого VPS smoke deploy используйте server-side инструкции из docs/deployment.md: сервер подтягивает публичную ветку remote-server-transport из GitHub, runtime-переменные лежат вне репозитория, а сервис временно публикуется напрямую на http://158.160.37.91:8000 в shared bearer-token режиме. HTTPS/OAuth через Caddy оставлен отдельным production-шагом.
Для проверки входа именно из ChatGPT используйте HTTPS tunnel из docs/deployment.md: ChatGPT Developer mode подключает remote MCP apps по SSE/streaming HTTP с OAuth/No Auth/Mixed Auth, поэтому plain HTTP shared endpoint на :8000 нужен только как низкоуровневый smoke. Для ChatGPT указывайте tunnel URL с trailing slash: https://.../mcp/.
Подключение в ChatGPT
После OAuth-deploy или запуска deploy/chatgpt-tunnel.sh сначала проверьте публичный endpoint:
curl -sS https://<host>/readyz
curl -sS -o /tmp/kaiten-mcp-unauth.json -w "%{http_code}\n" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"1"}}}' \
https://<host>/mcp/
Ожидаемо: /readyz возвращает {"status":"ready","auth_mode":"oauth"}, а unauthenticated POST /mcp/ возвращает 401 invalid_token.
В ChatGPT:
- Удалите или Disconnect старый app/draft, если он был создан при
MCP_HTTP_AUTH_MODE=none.
- Создайте новый app в Developer mode / Apps settings.
- Вставьте MCP URL с trailing slash:
https://<host>/mcp/. - Ожидайте в настройках app:
Authorization supported: OAuth; после
подключения: Authorization used: OAuth.
- При первом подключении ChatGPT откроет
/authorize; пользователь вводит
Kaiten company domain и свой Kaiten API key на странице MCP server.
- Дальше ChatGPT передаёт только MCP OAuth access token, а MCP server ходит в
Kaiten с сохранённым request-scoped Kaiten credential.
Если ChatGPT показывает Authorization supported: None, app был создан против no-auth endpoint или endpoint всё ещё отвечает auth_mode=none. Удалите этот draft, проверьте /readyz, пересоздайте app после OAuth-deploy.
Если tool возвращает KAITEN_TOKEN is required, вызов дошёл до no-auth/legacy ветки без пользовательской OAuth-сессии. Для публичного ChatGPT deployment-а не добавляйте KAITEN_TOKEN в env контейнера; вместо этого верните MCP_HTTP_AUTH_MODE=oauth и переподключите app.
Как работает авторизация
- Администратор публикует один общий MCP server с
MCP_HTTP_AUTH_MODE=oauth. - В production env не задаются
KAITEN_TOKENиMCP_AUTH_TOKEN: общий сервер не работает от имени одного Kaiten-пользователя. - LLM-клиент читает OAuth metadata, регистрирует client через
/registerи отправляет пользователя на/authorize. - Пользователь вводит Kaiten company domain и свой Kaiten API key на onboarding-странице MCP server.
- MCP server валидирует ключ запросом к Kaiten
/users/current, сохраняет Kaiten credential только в памяти и выдаёт authorization code. - LLM-клиент меняет code на MCP access token через
/token. - Дальше все tool calls идут с MCP bearer token; MCP server достаёт связанную сессией Kaiten credential и создаёт request-scoped Kaiten client.
- После expiry сессии или рестарта процесса пользователь должен подключиться заново.
Способ 1: Docker Compose
docker compose --profile http --project-directory /path/to/kaiten-mcp up --build -d kaiten-mcp-http
Проверка:
curl http://127.0.0.1:8000/readyz
OAuth discovery endpoints:
/.well-known/oauth-protected-resource
/.well-known/oauth-authorization-server
/register
/authorize
/token
MCP endpoint по умолчанию публикуется на:
http://127.0.0.1:8000/mcp
Способ 2: Docker run
docker build --target baked-http -t kaiten-mcp-http:latest .
docker run --rm \
--read-only --tmpfs /tmp:noexec,nosuid,size=64m \
--security-opt=no-new-privileges:true --cap-drop=ALL \
-p 8000:8000 \
-e MCP_HTTP_AUTH_MODE=oauth \
-e MCP_PUBLIC_URL=https://mcp.example.com/mcp \
-e MCP_OAUTH_ISSUER_URL=https://mcp.example.com \
-e MCP_RESOURCE_METADATA_URL=https://mcp.example.com/.well-known/oauth-protected-resource \
-e MCP_ALLOWED_ORIGINS=https://claude.ai,https://chatgpt.com \
-e MCP_HTTP_HOST=0.0.0.0 \
-e MCP_HTTP_PORT=8000 \
-e MCP_HTTP_BASE_PATH=/mcp \
kaiten-mcp-http:latest
Legacy MCP_AUTH_TOKEN режим остаётся для single-tenant/internal запуска: MCP_HTTP_AUTH_MODE=shared + env KAITEN_TOKEN. Для общего сервера этот режим не подходит, потому что все пользователи будут действовать в Kaiten одним токеном.
Важно для production
- Не публикуйте HTTP endpoint с
MCP_HTTP_AUTH_MODE=none. - Не передавайте Kaiten API key как MCP
Authorizationbearer token. - Ввод Kaiten API key должен происходить только через HTTPS onboarding page.
- Для интернета лучше ставить сервис за Nginx, Caddy, Tailscale или VPN.
- Локальный
stdioрежим для Claude Code и Claude Desktop остаётся предпочтительным, если удалённый deployment не нужен. GET /healthzпроверяет liveness процесса,GET /readyzвозвращает готовность MCP service и текущий HTTP auth mode.
Структура проекта
src/kaiten_mcp/
runtime.py # Общая MCP runtime-логика для stdio и HTTP
server.py # MCP-сервер (stdio transport)
http_server.py # MCP-сервер (streamable HTTP transport)
client.py # HTTP-клиент Kaiten API (httpx, rate limiting)
tools/
compact.py # Компактификация ответов (аватары, лимиты)
spaces.py # Пространства
boards.py # Доски
columns.py # Колонки и подколонки
lanes.py # Дорожки (swimlanes)
cards.py # Карточки (включая bulk-листинг с авто-пагинацией)
comments.py # Комментарии
members.py # Участники и пользователи
time_logs.py # Логи времени
tags.py # Теги
card_types.py # Типы карточек
custom_properties.py # Кастомные свойства
checklists.py # Чеклисты и элементы
blockers.py # Блокировки карточек
card_relations.py # Связи parent/child/planned
external_links.py # Внешние ссылки
files.py # Файлы карточек (загрузка, скачивание, удаление)
subscribers.py # Подписчики карточек
documents.py # Документы и группы документов
webhooks.py # Вебхуки пространств
automations.py # Автоматизации и воркфлоу
projects.py # Проекты и спринты
roles_and_groups.py # Роли, группы, участники пространств
audit_and_analytics.py # Аудит, активность, сохранённые фильтры
service_desk.py # Service Desk (SLA, пользователи, статистика)
charts.py # Графики (CFD, control, cycle/lead time, throughput)
tree.py # Навигация по дереву сущностей
utilities.py # API-ключи, таймеры, календари, корзина
API-клиент
- Базовый URL:
- по умолчанию:
https://{subdomain}.kaiten.ru/api/latest - c кастомным base domain:
https://{subdomain}.{base_domain}/api/latest - при
KAITEN_BASE_URL: override нормализуется до.../api/latest - Авторизация:
Bearerтокен - Rate limiting: 4.5 запросов/сек (серверный лимит — 5 req/s)
- Автоматический retry при HTTP 429 с exponential backoff (до 3 попыток)
Тесты
Тесты запускаются только в Docker:
# Все тесты с проверкой 100% покрытия
docker compose -f tests/docker-compose.test.yml up --build test-overseer
# E2E-тесты (нужен .env с KAITEN_SUBDOMAIN/KAITEN_BASE_URL и KAITEN_TOKEN)
docker compose -f tests/docker-compose.test.yml up --build test-e2e-expanded
Лицензия
MIT
Автор
Виктор Огнев
Дисклеймер
Настоящий репозиторий и размещённое в нём программное обеспечение предоставляются по принципу “как есть” (“as is”) и “по мере доступности” (“as available”), без каких-либо гарантий, явных или подразумеваемых. Автор не предоставляет никаких заверений и гарантий в отношении корректности, надёжности, безопасности, пригодности для конкретных целей или отсутствия ошибок в данном решении.
Используя данный программный продукт, вы подтверждаете, что принимаете на себя все риски, связанные с его использованием, включая, но не ограничиваясь, прямыми, косвенными, случайными или последующими убытками.
Автор настоящего репозитория является единственным разработчиком и правообладателем данного кода. Данное решение разработано и распространяется независимо и не является официальным продуктом или услугой компании Kaiten Software.
Компания Kaiten Software не несёт никакой ответственности за качество работы, производительность, результаты использования или любые последствия, связанные с использованием данного решения. Любые упоминания Kaiten Software приведены исключительно в информационных целях и не означают одобрения, поддержки или аффилированности.






