# Ticktick

> Manage tasks and projects in TickTick via the `ticktick-cli` CLI (`ticktick` / `tt`). Use this when the user asks to create/find/update/complete a TickTick task, check what's due today/overdue/upcoming, or work with TickTick projects (lists).

- Skill: `chichiton/ticktick` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add chichiton/ticktick`
- Raw SKILL.md: https://api.skillmd.com/api/skills/chichiton/ticktick/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: chichiton (https://skillmd.com/u/chichiton)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/chichiton/ticktick

---


# TickTick

A skill for working with TickTick via `ticktick-cli` (npm package `ticktick-cli`, binaries
`ticktick` and `tt`) — a TypeScript wrapper around the official TickTick Open API
(https://developer.ticktick.com/docs#/openapi).

*A Russian translation of this document is available in [`SKILL.ru.md`](./SKILL.ru.md).*

## Install & auth (one-time setup)

```bash
npm install -g ticktick-cli
```

1. Go to https://developer.ticktick.com/ → "Manage Apps" → create an app.
   Set the redirect URI to exactly: `http://127.0.0.1:18463/callback` (the CLI's default).
2. Save the Client ID/Secret into the CLI config:
   ```bash
   ticktick config set clientId YOUR_CLIENT_ID
   ticktick config set clientSecret YOUR_CLIENT_SECRET
   ```
3. Authenticate:
   ```bash
   ticktick auth login
   ```
   This opens a browser; after you approve, the token is stored locally
   (`~/Library/Application Support/ticktick-cli/config.json` on macOS) and auto-refreshes.
4. Verify: `ticktick auth status`.

## Critical: proxy workaround for sandboxes without direct network access

If the agent is running in a sandbox where outbound traffic only goes through an HTTP(S) proxy
(`HTTP_PROXY`/`HTTPS_PROXY`), note that Node.js **does not honor those variables by default** in
`fetch`. Because of this, a plain `ticktick <command>` may fail with `fetch failed` /
`ENOTFOUND api.ticktick.com`, even though `curl` to the same host works fine.

**Fix — run commands with the `NODE_USE_ENV_PROXY=1` environment variable:**

```bash
NODE_USE_ENV_PROXY=1 ticktick <command> [...]
```

In a normal terminal (not a sandbox) this variable is harmless — it's safe to always add it "just
in case".

## Command surface (important: NOT `tasks`/`projects` plural)

The main subcommands are `ticktick auth`, `ticktick task`, `ticktick project`, plus the shortcuts
`ticktick today` / `ticktick overdue` / `ticktick next`. This version of the CLI has no setup
wizard beyond the manual steps above, no tags flag on task creation, no short IDs, and no separate
MCP server — it's a plain CLI invoked through the shell.

### Daily overview commands (fastest way to answer "what's on my plate today")

```bash
NODE_USE_ENV_PROXY=1 ticktick today --json      # overdue + due today
NODE_USE_ENV_PROXY=1 ticktick overdue --json    # only overdue open tasks
NODE_USE_ENV_PROXY=1 ticktick next --json       # the next 10 upcoming tasks after today
```

### Projects (lists)

```bash
NODE_USE_ENV_PROXY=1 ticktick project list
NODE_USE_ENV_PROXY=1 ticktick project get <projectId>
NODE_USE_ENV_PROXY=1 ticktick project data <projectId>      # project + tasks + columns
NODE_USE_ENV_PROXY=1 ticktick project create --name "Name" --color "#F18181" --view-mode list --kind TASK
NODE_USE_ENV_PROXY=1 ticktick project update <projectId> --name "New name"
NODE_USE_ENV_PROXY=1 ticktick project delete <projectId>
```

Note: the built-in Inbox project is not returned by `project list` — this is a limitation of the
TickTick Open API itself, not the CLI. You can find the Inbox `projectId` on any task that lives in
it (e.g. via `ticktick next --json` or `ticktick today --json`); it usually looks like
`inbox<number>`.

### Tasks

```bash
# Create a task
NODE_USE_ENV_PROXY=1 ticktick task create --project-id <id> --title "Title" \
  --content "Extra text" --due-date "2026-01-30T09:00:00+0000" --priority 3

# Get a task
NODE_USE_ENV_PROXY=1 ticktick task get <projectId> <taskId>

# Update a task
NODE_USE_ENV_PROXY=1 ticktick task update <taskId> --project-id <id> --title "New title" --priority 5

# Complete / delete
NODE_USE_ENV_PROXY=1 ticktick task complete <projectId> <taskId>
NODE_USE_ENV_PROXY=1 ticktick task delete <projectId> <taskId>

# Move a task between projects
NODE_USE_ENV_PROXY=1 ticktick task move --from-project-id <id1> --to-project-id <id2> --task-id <taskId>

# List completed tasks
NODE_USE_ENV_PROXY=1 ticktick task completed --project-id <id>

# Filter (by date/priority/tag/status)
NODE_USE_ENV_PROXY=1 ticktick task filter --project-id <id> --priority 3 --tag work --status 0
```

`--priority` values are TickTick API numbers (0 = none, 1 = low, 3 = medium, 5 = high) — the CLI
does **not** accept the words `high`/`medium`/`low`, even though older docs for this project might
suggest otherwise.

Date format: `yyyy-MM-dd'T'HH:mm:ssZ`, e.g. `2026-01-30T09:00:00+0000`.

**`--all-day true` gotcha:** for all-day tasks, TickTick stores `dueDate`/`startDate` as
21:00:00 UTC of the **previous** local day (i.e. midnight in Europe/Moscow, UTC+3). To make a task
land in `today`/`overdue` for calendar date `YYYY-MM-DD`, you must set the date to
`(YYYY-MM-DD minus 1 day)T21:00:00+0000`, not the date itself with `T21:00:00+0000`. Setting it
"as-is" pushes the task one day forward and it won't show up in `ticktick today` until tomorrow.
Verify the result with `ticktick today --json` after creating/updating an all-day task.

**Careful with `--json`:** on `today`/`overdue`/`next` it's a boolean output-format switch ("print
JSON"). On `task create`/`task update`/`task filter`/`task move`/`project create`/`project update`
it's an **inline request body** that requires a valid JSON string after the flag
(`--json '{"title":"..."}'`). If you just append `--json` with no value to `task create`, the CLI
fails with `error: option '--json <json>' argument missing`.

### Raw API request

If there's no dedicated flag for what you need, you can hit any documented endpoint directly:

```bash
NODE_USE_ENV_PROXY=1 ticktick request GET /open/v1/project
NODE_USE_ENV_PROXY=1 ticktick request POST /open/v1/task --json '{"title":"...","projectId":"..."}'
```

## Practical workflow

1. If the user names a project instead of giving an ID, run `project list` first and resolve the
   `id` from `name`.
2. For "what's on my plate today" use `ticktick today --json` — don't hand-assemble it via
   `filter`.
3. Always add `--json` (or the equivalent output flag on subcommands that support it) when working
   from a script/agent, so you can parse the output instead of the table.
4. Secrets (`clientSecret`, `accessToken`) live in the config file in plaintext — don't print its
   contents to the user unless necessary, and don't log `auth status` output without an explicit
   `--show-secrets` request.

