ticktick-mcp
ticktick-mcp
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) и ваш собственный логин учётной записи.
Зарегистрируйте приложение на developer.ticktick.com. Установите Redirect URI на
http://localhost:8080/redirect. Запишите Client ID и Client Secret.Скопируйте шаблон в каталог, который читает сервер, и заполните его:
mkdir -p ~/.config/ticktick-mcp && cp .env.example ~/.config/ticktick-mcp/.envTICKTICK_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Этот файл содержит пароль вашей учётной записи в открытом виде, и сервер не создаёт его, поэтому ужесточите его самостоятельно. В 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 versionauth — единственная другая подкоманда, и она существует для того, чтобы шаг с браузером выполнялся в терминале, а не внутри сервера. Все операции с задачами выполняются через инструменты MCP ниже.
Инструменты MCP
Инструмент | Описание |
| Создать задачу, сохраняя поля даты/напоминания/приоритета/часового пояса; предупреждает, если не установлена дата выполнения (напоминание не сработает) |
| Обновить задачу, накладывая только заданные вами поля на текущий объект сервера (опущенные поля никогда не стираются) |
| Отметить задачу как выполненную и повторно проверить; различает повторяющуюся задачу, переходящую вперёд, и обычное завершение |
| Удалить одну или несколько задач по ID |
| Переместить задачу в другой проект |
| Вложить одну задачу как подзадачу другой в том же проекте |
| Список всех открытых задач в проекте (компактный или полный) |
| Найти задачи по любому сочетанию проекта, приоритета, тега, статуса и окна дат выполнения/завершения |
| Найти любую задачу, проект или тег по полному ID |
| Вывести все проекты или все теги из локального состояния |
| Принудительное немедленное обновление локального состояния с сервера |
| Список недавно завершённых задач в проекте, ещё не отмеченных как обработанные |
| Записать, что завершённая задача была проверена, исключив её из будущих проверок |
| Преобразовать дату и время 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, который обновляется при каждом вызове и сообщает об ошибке, поскольку полный дамп — не то место, где можно тихо отдать устаревший ответ.
Конфигурация
Переменная | По умолчанию | Описание |
|
| Каталог, содержащий |
|
| Минимальное количество секунд между повторными синхронизациями чтения по требованию |
|
| Пауза перед повторной попыткой входа клиента после неудачного первого подключения |
|
| Пауза перед повторной попыткой входа после ограничения частоты запросов (HTTP 429); длиннее паузы инициализации, поскольку 429 снимается медленно, а каждая повторная попытка продлевает её |
| 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.
Лицензия
Maintenance
Related MCP Servers
- AlicenseCqualityCmaintenanceAgent-friendly CLI and MCP server for TickTick and Dida365 task management APIs, enabling project and task management with stable JSON output and OAuth authentication.171MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for TickTick API enabling task management, project organization, habit tracking, and more.4272MIT
- FlicenseNot gradedqualityDmaintenanceRemote MCP server for managing TickTick tasks and projects, offering 22 tools for CRUD, search, and GTD workflows via any MCP client.1
- AlicenseNot gradedqualityCmaintenanceA security-hardened MCP server for TickTick that enables managing your tasks directly through any MCP-compatible client.1MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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