Skip to content

Releases: partymola/ticktick-mcp

v0.3.0

Choose a tag to compare

@partymola partymola released this 02 Aug 23:51

Changed

  • Ported to the mcp 2.x server API. 2.0.0 renamed mcp.server.fastmcp to mcp.server.mcpserver and the FastMCP class to MCPServer, with no compatibility alias. The tool contract is unchanged: every tool keeps its name, description, and input and output schemas.
  • Every dependency is pinned to an exact version instead of a lower bound: mcp 2.0.0, anyio 4.14.2, python-dotenv 1.2.2, pydantic 2.13.4 and tzlocal 5.4.4, and for development pytest 9.1.1, pytest-asyncio 1.4.0 and ruff 0.16.1.

Fixed

  • A fresh install no longer breaks on import. The mcp spec was >=1.6.0 with no upper bound, so once 2.0.0 was published the resolver picked it and the server failed to start.
  • Strict tool-argument validation is now pinned by a test that invokes a registered tool with an unknown kwarg, rather than only asserting the setting the patch writes. The strictness comes from patching a private mcp internal; if that internal stops being what argument models are built on, the patch still applies cleanly to an object nothing reads and typo'd kwargs silently fall through to their defaults again - which the previous checks could not distinguish from working.

Packaging

  • The build toolchain is pinned alongside the dependencies: setuptools to an exact version, the python:3.13-slim base image by digest, and every GitHub Action to a full commit SHA rather than a moving major tag. The uv binary image, previously referenced as :latest, is pinned to 0.12.1 by digest. A floating tag can change what a build produces with nobody deciding, which is the same failure the dependency pins address.

v0.2.0

Choose a tag to compare

@partymola partymola released this 25 Jul 03:31

Project names are accepted wherever a project ID is, tasks can be marked off-limits to modification, and every ticktick_complete_task and ticktick_update_task result carries an outcome field.

Two changes are not backward compatible:

  • An ambiguous project name is now an error naming both candidate IDs, rather than silently resolving to whichever project sync returned first.
  • ticktick_mark_completion_processed now requires an authenticated client. It previously worked during an auth outage, but would key the completion row by project name - invisible to every later ID-keyed read.

Full detail in CHANGELOG.md.

v0.1.3

Choose a tag to compare

@partymola partymola released this 22 Jul 22:24

Added

  • The v2 session token from a successful login is now cached to disk (config/.token-v2, 0600) and reused on the next start, so the server no longer re-runs the username/password login (user/signon) on every construction. That endpoint is the one TickTick rate-limits with HTTP 429, so reusing the token -- as a logged-in browser does -- avoids the throttle entirely. A stale cached token is detected (the startup sync rejects it), cleared, and replaced by a single fresh login that repopulates the cache.

Full Changelog: v0.1.2...v0.1.3

v0.1.2

Choose a tag to compare

@partymola partymola released this 22 Jul 21:38

Fixed

  • A TickTick login rate-limit is now surfaced explicitly instead of as a generic "Could Not Complete Request". ticktick-py re-authenticates with username/password on every client construction, and TickTick throttles that user/signon endpoint with HTTP 429; the failure now carries the HTTP status code, tool calls return status: "rate_limited" with a clear "stop retrying, wait ~15-30 minutes" message, and the server backs its own initialisation retry off to 5 minutes on a 429 (TICKTICK_MCP_RATELIMIT_RETRY_SECONDS, default 300s) instead of the ordinary 60s, so it stops re-hitting the throttled login and prolonging the block.

Full Changelog: v0.1.1...v0.1.2

v0.1.1

Choose a tag to compare

@partymola partymola released this 11 Jul 23:08

Listed in the official MCP registry (io.github.partymola/ticktick-mcp) via a GHCR container image. The image now builds with uv so it uses the patched ticktick-py fork. Also fixes cached client-init failures.

v0.1.0

Choose a tag to compare

@partymola partymola released this 09 Jun 15:43

First stable release: MCP server for TickTick task management.

Added

  • Tools: create, update, complete, move, delete, filter, get-by-id, get-all, get-from-project, make-subtask, datetime conversion.
  • Completion tracking: idempotent processing of completed tasks via local SQLite (get_unprocessed_completions, mark_completion_processed).
  • Field-preserving partial updates (omitted fields are not cleared on the TickTick side).
  • Day-of-week validation on dueDate to catch date/day-name mismatches.
  • Read-after-write verification (_verification_warnings on mutated tasks).
  • Dateless-task warning (tasks created without a dueDate get a warning that they will not trigger reminders).
  • On-demand freshness: active-read tools and the read step of mutations re-sync server state, throttled (default 15s, TICKTICK_MCP_SYNC_TTL_SECONDS), so edits made in the TickTick app on other devices are visible without restarting the server. Sync failures are fail-soft (last-known state is served).
  • ticktick_sync tool: force an immediate refresh and report task/project counts.
  • Recurring-aware completion: ticktick_complete_task returns outcome: "completed_recurring" and next_occurrence_id when a recurring task rolls forward, instead of a misleading "status still indicates open" warning.
  • Silent no-op detection: ticktick_update_task returns outcome: "no_op" with re-read guidance when the API echoes an empty response and a re-read confirms the change did not apply.
  • Routable-reopen guidance: ticktick_update_task returns outcome: "needs_project_id" when the target id is not in local sync state and no projectId was supplied.
  • Recurring reopen guard: ticktick_update_task returns outcome: "reopen_no_effect" when the only substantive change is status:0 on a recurring task that has already rolled forward.