Skip to main content
Glama

ticktick-mcp

CI License: GPL v3 Python 3.13+ Glama MCP Server

MCP-сервер для управления задачами TickTick. Создавайте, обновляйте, завершайте, перемещайте и фильтруйте задачи через TickTick v2 API, с обновлениями, сохраняющими поля, проверкой дня недели, верификацией после записи и идемпотентным отслеживанием завершения.

Разработан для Claude Code и других MCP клиентов.

Неофициальный. Не связан с TickTick Ltd. Создан на основе ticktick-py (MIT).

Возможности

  • Полный жизненный цикл задач — создание, обновление, завершение, перемещение, подзадачи и удаление

  • Обновления с сохранением полейticktick_update_task повторно получает задачу и накладывает только те поля, которые вы задали, поэтому API никогда не стирает те, что вы опустили

  • Проверка дня недели — любой вызов, устанавливающий дату, должен подтвердить день недели, что позволяет выявить ошибки в датах до отправки на сервер

  • Верификация после записи — create/update повторно читают задачу и показывают _verification_warnings, если ответ сервера не совпадает

  • Компактный список — инструменты списка по умолчанию возвращают усечённое представление, чтобы большие проекты оставались в пределах лимита размера результата MCP (см. ниже)

  • Свежие чтения — инструменты чтения по запросу синхронизируют состояние сервера, поэтому изменения, сделанные в приложении TickTick на других устройствах, появляются без перезапуска

  • Отслеживание завершений — отмечайте завершённые задачи как обработанные, чтобы агент просматривал каждую ровно один раз

Related MCP server: ticktick-mcp-server

Требования

  • Python 3.13+

  • uv (рекомендуется — см. примечание по установке ниже)

  • Учётная запись TickTick

  • Зарегистрированное приложение TickTick для учётных данных OAuth (бесплатно — developer.ticktick.com)

Установка

git clone https://github.com/partymola/ticktick-mcp
cd ticktick-mcp
uv sync

Это создаёт .venv и устанавливает из uv.lock, давая вам консольный скрипт в .venv/bin/ticktick-mcp или .venv\Scripts\ticktick-mcp на Windows. Все команды ниже называют его в стиле POSIX.

pip install . тоже работает. Форк ticktick-py, необходимый этому серверу, закреплён как прямая git-ссылка внутри dependencies, которую уважают и pip, и uv; рекомендуется uv sync, потому что он устанавливает точные версии из uv.lock, а не пересобирает их.

Учётные данные

Для входа в TickTick нужны две вещи: приложение OAuth (client ID + secret) и ваш собственный логин учётной записи.

  1. Зарегистрируйте приложение на developer.ticktick.com. Установите Redirect URI на http://localhost:8080/redirect. Запишите Client ID и Client Secret.

  2. Скопируйте шаблон в каталог, который читает сервер, и заполните его:

    mkdir -p ~/.config/ticktick-mcp && cp .env.example ~/.config/ticktick-mcp/.env
    TICKTICK_CLIENT_ID=your_client_id
    TICKTICK_CLIENT_SECRET=your_client_secret
    TICKTICK_REDIRECT_URI=http://localhost:8080/redirect
    TICKTICK_USERNAME=your_ticktick_email
    TICKTICK_PASSWORD=your_ticktick_password
  3. Этот файл содержит пароль вашей учётной записи в открытом виде, и сервер не создаёт его, поэтому ужесточите его самостоятельно. В POSIX:

    chmod 700 ~/.config/ticktick-mcp
    chmod 600 ~/.config/ticktick-mcp/.env

    Это биты режима POSIX, и на Windows они не действуют: доступ там определяется ACL, которые файл наследует от родительского каталога. Эквивалент этих двух команд для Windows здесь не документирован.

    Два файла токенов рядом с ним создаются только для владельца, и каталог конфигурации, который создаёт сервер, тоже — но если он находит уже существующий, он остаётся как есть. Это тоже режимы POSIX, устанавливаемые и на Windows, где они не ограничивают, кто может читать.

Авторизуйтесь один раз в терминале перед регистрацией сервера:

.venv/bin/ticktick-mcp auth

Он открывает браузер и просит вставить URL, на который вы попали, затем завершается. Токен кэшируется рядом с вашим .env как .token-oauth, и каждый последующий запуск использует его повторно. TickTick не выдаёт refresh-токен, поэтому это повторяется при истечении срока действия токена — выполните ту же команду снова.

Не позволяйте этому шагу выполняться внутри MCP-сервера. Запрос читается из стандартного ввода, который для stdio-сервера является каналом JSON-RPC, поэтому неавторизованный первый вызов инструмента открывает браузер на хосте и блокирует. В контейнере это вообще невозможно выполнить — запустите auth на хосте и смонтируйте каталог конфигурации.

Часть с именем пользователя/паролем не требует отдельного шага: сервер выполняет вход лениво при первом вызове инструмента и кэширует токен сессии как .token-v2, поэтому он не отправляет ваши учётные данные повторно при каждом запуске.

Сервер ищет .env в следующем порядке: аргумент --dotenv-dir <path>, затем переменная окружения TICKTICK_MCP_DOTENV_DIR, затем ~/.config/ticktick-mcp/. Если .env не найден, он напрямую использует переменные окружения TICKTICK_*, что удобно для контейнеров/CI.

Конфиденциальность и неофициальный API

Ваши учётные данные TickTick хранятся только в вашем локальном .env (или в окружении) и отправляются только на собственные серверы TickTick — никогда разработчику или третьим лицам. Сервер читает и записывает только вашу собственную учётную запись.

Этот сервер использует неофициальный v2 API TickTick (через ticktick-py), а не официальный Open API. Это осознанный выбор: в официальном API нет конечной точки для списка завершённых задач, нет тегов и нет списка задач по всем проектам — всё это сервер использует. Полное обоснование, компромисс по рискам и триггеры, которые заставили бы нас пересмотреть решение, см. в docs/why-not-the-official-api.md.

Регистрация в Claude Code

claude mcp add -s user ticktick -- /path/to/ticktick-mcp/.venv/bin/ticktick-mcp --dotenv-dir /path/to/config

--dotenv-dir необязателен, если ваш .env находится в ~/.config/ticktick-mcp/ или вы передаёте переменные TICKTICK_* через окружение.

Затем спрашивайте Клода, например:

  • "Что у меня в списке TickTick на этой неделе?"

  • "Добавь задачу позвонить стоматологу в пятницу в 9 утра."

  • "Отметь задачу о покупках как выполненную."

  • "Перемести задачу о бюджете в проект Finance."

Docker

Образы публикуются в ghcr.io/partymola/ticktick-mcp. Теги имеют префикс v (:vX.Y.Z), а :latest следует за последним релизом.

Сначала авторизуйтесь на машине с браузером, затем смонтируйте этот каталог. Это единственный путь, и он действует даже с docker run -it: базовая библиотека сама открывает браузер и никогда не печатает URL, поэтому из контейнера без браузера нечего копировать. Затем она ждёт этот URL на стандартном вводе, который для stdio-сервера является каналом JSON-RPC — так что контейнер, запущенный с каталогом без кэшированного токена, тоже не завершается корректно, он потребляет запросы вашего клиента, ожидая ввод, который никогда не поступит.

Для авторизации требуется установка из исходников (Install) и учётные данные из Credentials — опубликованного пакета для запуска нет. Не выполняйте pip install ticktick-mcp: это имя на PyPI принадлежит несвязанному проекту с почти идентичным описанием.

.venv/bin/ticktick-mcp auth       # once, on the host, in a terminal

claude mcp add -s user ticktick -- \
  docker run --rm -i --user $(id -u):$(id -g) \
  -v ~/.config/ticktick-mcp:/data \
  ghcr.io/partymola/ticktick-mcp:latest

-i обязателен — сервер общается по JSON-RPC через stdin и stdout.

--user присутствует, потому что контейнер по умолчанию работает от root, и всё, что он записывает в смонтированный каталог, становится принадлежащим root — после чего ticktick-mcp на хосте больше не может обновлять кэш токена сессии и при каждом запуске переходит к ограниченному входу. Вы снова будете запускать его на хосте: у OAuth-токена нет обновления, поэтому auth повторяется по истечении срока.

Монтируйте уже авторизованный каталог, никогда не пустой том. /data содержит .env, кэшированный OAuth-токен, токен сессии v2 и базу данных отслеживания завершений. В новом томе ничего этого нет, и запасной вход по паролю ограничен блокировкой на 15–30 минут.

Если вы предпочитаете вообще не хранить .env на диске, передайте учётные данные как переменные окружения. Монтирование всё равно необходимо — оно содержит кэш токенов, а не только .env:

docker run --rm -i --user $(id -u):$(id -g) \
  -v ~/.config/ticktick-mcp:/data \
  -e TICKTICK_CLIENT_ID -e TICKTICK_CLIENT_SECRET \
  -e TICKTICK_USERNAME -e TICKTICK_PASSWORD \
  ghcr.io/partymola/ticktick-mcp:latest

Указание каждой переменной без значения передаёт её из вашей оболочки, поэтому секрет не появляется ни в команде, ни в истории оболочки. Эти переменные переопределяют смонтированный .env: файл загружается без override, поэтому всё, что уже есть в окружении, побеждает. Для авторизации всё равно нужно экспортировать эти переменные на хосте, поскольку auth тоже не имеет .env для чтения.

CLI

ticktick-mcp                       Start the MCP server (stdio transport)
ticktick-mcp --dotenv-dir PATH     Directory holding the .env file
ticktick-mcp --version             Print the installed package version

auth — единственная другая подкоманда, и она существует для того, чтобы шаг с браузером выполнялся в терминале, а не внутри сервера. Все операции с задачами выполняются через инструменты MCP ниже.

Инструменты MCP

Инструмент

Описание

ticktick_create_task

Создать задачу, сохраняя поля даты/напоминания/приоритета/часового пояса; предупреждает, если не установлена дата выполнения (напоминание не сработает)

ticktick_update_task

Обновить задачу, накладывая только заданные вами поля на текущий объект сервера (опущенные поля никогда не стираются)

ticktick_complete_task

Отметить задачу как выполненную и повторно проверить; различает повторяющуюся задачу, переходящую вперёд, и обычное завершение

ticktick_delete_tasks

Удалить одну или несколько задач по ID

ticktick_move_task

Переместить задачу в другой проект

ticktick_make_subtask

Вложить одну задачу как подзадачу другой в том же проекте

ticktick_get_tasks_from_project

Список всех открытых задач в проекте (компактный или полный)

ticktick_filter_tasks

Найти задачи по любому сочетанию проекта, приоритета, тега, статуса и окна дат выполнения/завершения

ticktick_get_by_id

Найти любую задачу, проект или тег по полному ID

ticktick_get_all

Вывести все проекты или все теги из локального состояния

ticktick_sync

Принудительное немедленное обновление локального состояния с сервера

ticktick_get_unprocessed_completions

Список недавно завершённых задач в проекте, ещё не отмеченных как обработанные

ticktick_mark_completion_processed

Записать, что завершённая задача была проверена, исключив её из будущих проверок

ticktick_convert_datetime_to_ticktick_format

Преобразовать дату и время ISO 8601 + часовой пояс IANA в формат передачи TickTick

Проекты: имя или ID

Каждый инструмент, принимающий ID проекта, также принимает имя проекта — ticktick_create_task, ticktick_get_tasks_from_project, ticktick_update_task, ticktick_move_task, ticktick_delete_tasks, ticktick_filter_tasks и оба инструмента отслеживания завершений:

ticktick_create_task(title="Renew insurance", project_id="Home Admin")

Имена сопоставляются без учёта регистра, игнорируя окружающие пробелы, а "Inbox" соответствует вашему входящему ящику. ID продолжают работать без изменений и всегда имеют приоритет, поэтому ничего из того, что работает сегодня, не меняется.

Единственная новая ошибка — неоднозначность: если два проекта имеют одинаковое имя, вызов завершается ошибкой и называет оба ID, а не выбирает один, поскольку угадывание привело бы к размещению задачи там, где вы не стали бы искать. Всё остальное, что сервер не может разрешить, передаётся в API без изменений, как и раньше.

Два инструмента отслеживания завершения задач являются исключением: они отказываются принимать ссылку на проект, которую не могут подтвердить, вместо того чтобы передать её дальше, поскольку это значение является ключом, под которым хранятся записи их локальной базы данных. Нераспознанная ссылка привела бы к записи строки, которую последующий поиск по ID не сможет найти. Если список проектов не удалось обновить для проверки, они сообщают об этом (outcome: "project_list_unverifiable") вместо того, чтобы утверждать, что проекта не существует.

Вывод списка задач: компактный режим по умолчанию

Инструменты, возвращающие списки, — ticktick_get_tasks_from_project и ticktick_filter_tasks — по умолчанию используют detail="compact". Компактный вывод сохраняет поля, важные для просмотра (id, projectId, title, dueDate, startDate, priority, status, isAllDay, timeZone, tags), а также contentPreview (первые ~200 символов content), и отбрасывает тяжёлые блоки content/desc/элементов чек-листа items и громоздкие метаданные синхронизации. Это позволяет большим проектам оставаться в пределах лимита размера результата MCP, так что клиенту не приходится сбрасывать результат на диск. Поиск по ключевым словам по-прежнему работает по title и contentPreview.

  • Нужны полные объекты? Передайте detail="full".

  • Нужно полное содержимое одной задачи? Используйте ticktick_get_by_id.

  • Редактирование задачи: сначала получите полный объект через ticktick_get_by_id, затем отправьте все поля обратно через ticktick_update_task. API TickTick стирает любое поле, пропущенное при обновлении, поэтому компактный вывод никогда не должен использоваться для обновления.

Если компактный результат всё равно превышает бюджет размера, возвращаются задачи с ближайшим сроком выполнения, а финальный элемент _truncation_note сообщает, сколько было пропущено, — ничего не отбрасывается молча. До остальных можно добраться с помощью более узкого запроса ticktick_filter_tasks, detail="full" или ticktick_get_by_id.

Актуальность: чтение не устаревает

Учётная запись TickTick может редактироваться из приложения на других устройствах, пока сервер работает. Чтобы чтение не устаревало, инструменты чтения повторно синхронизируют состояние сервера по требованию, с ограничением не чаще одного раза за окно (по умолчанию 15 секунд, переопределяется через TICKTICK_MCP_SYNC_TTL_SECONDS). Изменение, сделанное в другом месте, становится видимым в пределах этого окна; вызовите ticktick_sync, чтобы принудительно выполнить немедленное обновление и получить текущее количество задач/проектов. Если синхронизация не удалась, возвращается последнее известное состояние, а не ошибка, — за исключением ticktick_get_all, который обновляется при каждом вызове и сообщает об ошибке, поскольку полный дамп — не то место, где можно тихо отдать устаревший ответ.

Конфигурация

Переменная

По умолчанию

Описание

TICKTICK_MCP_DOTENV_DIR

~/.config/ticktick-mcp/

Каталог, содержащий .env, кэшированные токены и базу данных отслеживания завершения задач (аргумент --dotenv-dir имеет приоритет). В контейнерном образе установлено значение /data

TICKTICK_MCP_SYNC_TTL_SECONDS

15

Минимальное количество секунд между повторными синхронизациями чтения по требованию

TICKTICK_MCP_INIT_RETRY_SECONDS

60

Пауза перед повторной попыткой входа клиента после неудачного первого подключения

TICKTICK_MCP_RATELIMIT_RETRY_SECONDS

300

Пауза перед повторной попыткой входа после ограничения частоты запросов (HTTP 429); длиннее паузы инициализации, поскольку 429 снимается медленно, а каждая повторная попытка продлевает её

TICKTICK_MCP_PROTECTED_TASK_IDS

unset

ID задач, которые агент никогда не должен изменять, разделённые пробелами или запятыми. Каждый изменяющий инструмент отказывается выполнять действие до отправки чего-либо; чтение не затрагивается. Если не задано, защита отсутствует.

Защита задач от изменения

Некоторые задачи никогда не должны изменяться агентом, что бы его ни попросили сделать. Перечислите их ID в TICKTICK_MCP_PROTECTED_TASK_IDS:

TICKTICK_MCP_PROTECTED_TASK_IDS="60ca9dbc8f08516d9dd56324,60ca9dbc8f08516d9dd56325"

ticktick_update_task, ticktick_complete_task, ticktick_delete_tasks, ticktick_move_task и ticktick_make_subtask затем отклоняют любой вызов, в котором указана защищённая задача, возвращая outcome: "protected_task". Ни один запрос на чтение или запись задачи не отправляется. Пакетное удаление, содержащее защищённый ID, отклоняется целиком, а не применяется частично, поскольку частичное удаление нельзя отменить.

Поскольку TickTick распространяет удаление и перемещение на подзадачи, delete, move и make_subtask также отклоняют вызов, когда защищённая задача является родительской или подзадачей указанной вами задачи. Эта проверка сначала обновляет локальное состояние, поэтому при включённой защите добавляется один запрос на каждое удаление, перемещение или смену родителя — и возвращается outcome: "protection_unverifiable", если обновление не удалось, поскольку нельзя исключить защищённую подзадачу на снимке, который не удалось обновить. Если переменная не задана, никакой дополнительной работы не выполняется. ID сопоставляются без учёта окружающих пробелов, кавычек и регистра. Чтение защищённых задач всегда работает.

Учётные данные (TICKTICK_CLIENT_ID, TICKTICK_CLIENT_SECRET, TICKTICK_REDIRECT_URI, TICKTICK_USERNAME, TICKTICK_PASSWORD) читаются из файла .env или, если его нет, непосредственно из окружения.

Безопасность данных

Pre-commit хук (scripts/check-no-data.sh) блокирует случайную фиксацию баз данных, учётных данных и больших файлов — *.db и резервных копий, всего в config/, кроме .gitkeep и *.example*, а также файлов размером более 100 КБ (кроме uv.lock). Установите его после клонирования:

ln -sf ../../scripts/check-no-data.sh .git/hooks/pre-commit

Участие в разработке

См. CONTRIBUTING.md с описанием настройки разработки, рабочего процесса тестирования и pre-commit хука. Изменения отслеживаются в CHANGELOG.md.

Лицензия

GPL-3.0-or-later

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
1wRelease cycle
9Releases (12mo)
Commit activity

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • ClickUp MCP — wraps the ClickUp REST API v2 (BYO API key)

  • MCP server wrapping the Tesla Fleet API and TeslaMate API

  • MCP server for Withings health data — sleep, activity, heart, and body metrics.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/partymola/ticktick-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server