A command-line interface for the TickTick task management app, optimized for AI agents.
Requires Node.js 22.12+ (commander v15 is ESM-only and requires Node ≥22.12 for require(esm)):
npm install -g @crcatala/ticktick-cliThe package provides two equivalent commands: tt and ttcli. tt is used throughout this guide.
Build from Source
Requires Node.js 22.12+ and Bun:
git clone https://github.com/crcatala/ticktick-cli.git
cd ticktick-cli
bun install
bun run build
node dist/index.js --helptt auth loginYou'll be prompted for your TickTick username and password. If you have 2FA enabled, provide your TOTP code (automatic generation from a TOTP secret is not supported):
tt auth login --totp-code 123456By default, your session token is stored securely in your system keyring. If you prefer plaintext storage (not recommended), use:
tt auth login --use-configtt task listtt task add "Buy groceries" --priority high --due tomorrow# See all active tasks
tt task list
# See tasks in a specific project
tt task list --project Work
# Mark a task as done (task titles are supported when unambiguous)
tt task done "Buy groceries"# Simple task
tt task add "Call mom"
# Task with all options
tt task add "Prepare presentation" \
--project Work \
--priority high \
--due 2025-01-15 \
--tag work \
--tag urgent \
--content "Q1 sales review slides"# Create a dedicated note list
tt project add "Journal" --kind NOTE
# Add a note (the project must be a NOTE list)
tt note add "Daily reflection" --project Journal --content "What went well today"
# Convert between task and note (conversion clears task-only metadata)
tt task convert-to-note "Daily reflection"
tt note convert-to-task NOTE_ID# List all projects
tt project list
# Create a new project
tt project add "Home Renovation" --color "#FF5733"
# Show inbox ID
tt project inbox# List all tags
tt tag list
# Create a tag
tt tag add "work"
# Create a child tag
tt tag add "urgent" --parent "work"
# Rename a tag
tt tag rename "old-name" "new-name"# Export all data as JSON
tt sync --json > ticktick-backup.json
# Export just tasks
tt task list --json > tasks.jsonAll commands support --json output for easy parsing:
# Get task IDs for scripting
tt task list --json | jq '.[].id'
# Check auth status in scripts
if tt auth status --json | jq -e '.authenticated' > /dev/null; then
echo "Logged in"
fi| Command | Description |
|---|---|
tt auth login |
Log in to TickTick |
tt auth logout |
Log out and clear credentials |
tt auth status |
Show authentication status |
tt auth whoami |
Alias for status |
tt task list |
List active tasks |
tt task show ID_OR_TITLE |
Show task details |
tt task add TITLE |
Create a new task |
tt task edit ID_OR_TITLE |
Edit an existing task |
tt task done ID_OR_TITLE |
Mark task as complete |
tt task abandon ID_OR_TITLE |
Mark task as abandoned |
tt task reopen ID_OR_TITLE |
Reopen closed task |
tt task delete ID_OR_TITLE |
Delete task |
tt task closed |
List completed/abandoned tasks |
tt task subtask:add TASK PARENT |
Make task a subtask |
tt task subtask:unset TASK |
Remove from parent |
tt task convert-to-note ID_OR_TITLE |
Convert a task to a note |
tt note add TITLE --project NAME_OR_ID |
Create a note in a note list |
tt note convert-to-task ID |
Convert a note to a task |
tt project list |
List all projects |
tt project show ID_OR_NAME |
Show project details |
tt project add NAME |
Create a new project |
tt project edit ID_OR_NAME |
Edit a project |
tt project delete ID_OR_NAME |
Delete project |
tt project inbox |
Show inbox project ID |
tt group list |
List project groups |
tt group add NAME |
Create a project group |
tt group edit ID |
Edit a project group |
tt group delete ID |
Delete project group |
tt tag list |
List all tags |
tt tag add NAME |
Create a tag |
tt tag rename OLD NEW |
Rename a tag |
tt tag edit NAME |
Edit tag color/parent |
tt tag delete NAME |
Delete a tag |
tt user profile |
Show user profile |
tt user status |
Show subscription status |
tt user stats |
Show usage statistics |
tt sync |
Fetch full state snapshot |
tt trash empty |
Permanently delete all trashed items |
Task references accept exact IDs, unambiguous ID prefixes, and case-insensitive exact titles. Project references also accept unambiguous case-insensitive name prefixes. If multiple items match, use a full ID or add --project PROJECT to task lookup commands that support it.
Use tt COMMAND --help for detailed options.
Configuration is stored in ~/.config/ticktick-cli/config.json:
{
"auth": {
"username": "your@email.com",
"storage": "keyring"
},
"defaults": {
"project": "inbox_id"
}
}Security Note: By default, session tokens are stored in your system keyring (macOS Keychain, Windows Credential Manager, or Linux Secret Service). If you use --use-config, the token is stored in plaintext in the config file with 600 permissions.
Linux keyring storage requires an active Secret Service/D-Bus session, which is commonly unavailable in headless or SSH shells. If login succeeds but saving credentials fails with an error such as Cannot autolaunch D-Bus without X11 $DISPLAY, log in with the explicit plaintext fallback:
tt auth login --use-config
tt auth statusThis stores the session token in ~/.config/ticktick-cli/config.json with 0600 permissions instead of the system keyring. Use this only when a desktop keyring session is unavailable, and protect the file as you would a password.
This CLI uses TickTick's unofficial web API. If TickTick updates its web-client version before the CLI is updated, set TICKTICK_WEB_VERSION temporarily when running a command:
TICKTICK_WEB_VERSION=8121 tt auth loginThe built-in default is 8121. This setting is only a compatibility escape hatch; do not set it unless you have verified the current web client's X-Device.version.
The TickTick V2 API does not support fetching a single task by ID directly. Commands like tt task show fetch all tasks and filter client-side. This is efficient for most users but may be slow for accounts with thousands of tasks.
This CLI uses TickTick's unofficial V2 API (reverse-engineered from the web app). While more feature-complete than the official V1 API, it may change without notice.
# Install dependencies
bun install
# Run in development mode
bun run dev [command]
# Type check
bun run typecheck
# Run tests
bun run test
# Build JavaScript package output
bun run buildThis is a personally maintained project and does not accept code contributions, pull requests, or feature requests. Bug reports with a clear reproduction are welcome; see CONTRIBUTING.md for details.
See RELEASING.md for the release process and how to publish new versions.
MIT