A full-featured command-line interface for Things 3 on macOS. Designed for both human use and AI agent integration.
- macOS with Things 3 installed
- Node.js 18+
git clone https://github.com/kaufmanhenry/thingsctl.git
cd thingsctl
npm install
npm linkThis installs thingsctl globally on your system.
# See today's tasks
thingsctl today
# Add a task to today
thingsctl add "Call dentist" --when today
# Complete a task
thingsctl complete 17jJ
# Get help
thingsctl --help
thingsctl add --help# Today's tasks
thingsctl today
thingsctl today --verbose # Show area/project context
thingsctl today --json # JSON output for scripting
thingsctl today --compact # Single-line format
thingsctl today --ids # Just UUIDs (for scripting)
# Other lists
thingsctl inbox
thingsctl anytime
thingsctl someday
thingsctl upcoming # Scheduled for future dates
thingsctl due # Tasks with deadlines
thingsctl repeating # Recurring tasks
thingsctl logbook # Recently completed
thingsctl logbook --limit 50 # More completed tasksFilter any list command by tag, area, or project:
# Filter by tag
thingsctl today --tag Deep
thingsctl anytime --tag Urgent
# Filter by area
thingsctl anytime --area Finance
thingsctl someday --area Home
# Filter by project
thingsctl someday --project CoStudy
# Combine with output options
thingsctl today --tag Deep --compact
thingsctl anytime --area Work --ids# List all projects with task counts
thingsctl projects
# Show tasks in a specific project
thingsctl project "Wedding Planning"
thingsctl project Wedding # Partial match works
# List areas with task/project counts
thingsctl areas
# List all tags with usage counts
thingsctl tags# Full-text search across titles and notes
thingsctl search "birthday"
thingsctl search groceries --verbose
# Show detailed task info (partial UUID works)
thingsctl show 17jJ
thingsctl show 17jJuooocGSZxKNv3JuxRx --jsonthingsctl statsOutput:
Things 3 Statistics
Today: 5
Inbox: 0
Anytime: 10
Someday: 53
Upcoming: 13
Total Open: 132
Completed Today: 14
Projects: 18
# Basic
thingsctl add "Buy milk"
# With scheduling
thingsctl add "Call mom" --when today
thingsctl add "Review proposal" --when tomorrow
thingsctl add "Someday project" --when someday
thingsctl add "Next week task" --when "next week"
thingsctl add "Specific date" --when 2024-03-15
# With deadline
thingsctl add "Tax filing" --deadline 2024-04-15
# With tags (must exist in Things)
thingsctl add "Weekly review" --tags "Review,Deep"
# With checklist items
thingsctl add "Trip prep" --checklist "Passport,Tickets,Charger"
thingsctl add "Morning routine" --checklist "Exercise,Shower,Breakfast,Review tasks"
# Into a project (partial name match)
thingsctl add "Fix login bug" --project "Website"
thingsctl add "Review docs" --project Costudy
# Into an area (partial name match)
thingsctl add "Pay rent" --area Finance
# With notes
thingsctl add "Research topic" --notes "Check the PDF in Downloads"
# Into a heading within a project
thingsctl add "Final test" --project "Launch" --heading "QA Tasks"
# Combined
thingsctl add "Critical fix" --when today --deadline 2024-03-10 --tags Urgent --project "App"# Change title
thingsctl update 17jJ --title "New task title"
# Update notes
thingsctl update 17jJ --notes "Completely replace notes"
thingsctl update 17jJ --append-notes "Add this to the end"
thingsctl update 17jJ --prepend-notes "Add this at the start"
# Reschedule
thingsctl update 17jJ --when tomorrow
thingsctl update 17jJ --when "next week"
thingsctl update 17jJ --when 2026-03-15
# Set/change deadline
thingsctl update 17jJ --deadline 2026-03-20
# Add tags
thingsctl update 17jJ --add-tags "Important,Urgent"
# Multiple updates at once
thingsctl update 17jJ --when today --deadline 2026-03-20 --add-tags Priority# Single task (use partial UUID from any list command)
thingsctl complete 17jJ
thingsctl complete ANsB
# Bulk complete multiple tasks at once
thingsctl complete 17jJ ANsB 9pUS# Move to lists
thingsctl move 17jJ --to today
thingsctl move 17jJ --to anytime
thingsctl move 17jJ --to someday
# Schedule for specific date
thingsctl move 17jJ --to 2024-03-20
thingsctl move 17jJ --to "next week"
thingsctl move 17jJ --to tomorrow# Add tags (tag must exist in Things)
thingsctl tag 17jJ --add Important
thingsctl tag 17jJ --add "Deep Work"Export tasks in various formats:
# Export to markdown (default)
thingsctl export today
thingsctl export today --format md > today.md
# Export to CSV
thingsctl export today --format csv > today.csv
thingsctl export project "CoStudy" --format csv
# Export to JSON
thingsctl export anytime --format json
# Export from different sources
thingsctl export today
thingsctl export anytime
thingsctl export someday
thingsctl export inbox
thingsctl export project "Project Name"
thingsctl export area "Area Name"All commands support --json for scripting:
# Pipe to jq
thingsctl today --json | jq '.[].title'
thingsctl stats --json | jq '.today'
# Count today's tasks
thingsctl today --json | jq length
# Extract task IDs
thingsctl search "meeting" --json | jq -r '.[].uuid'| Option | Description |
|---|---|
--json |
Output as JSON |
--verbose, -v |
Show more details (area/project context) |
--compact |
Single-line output format |
--ids |
Output only UUIDs (for scripting) |
--help, -h |
Show help (global or command-specific) |
--version, -V |
Show version |
Available for list commands (today, anytime, someday, inbox, upcoming):
| Option | Description |
|---|---|
--tag <name> |
Filter by tag (partial match) |
--area <name> |
Filter by area (partial match) |
--project <name> |
Filter by project (partial match) |
thingsctl is designed to work seamlessly with AI assistants and agents (Claude, GPT, etc.). The --json flag on all commands provides structured output that's easy for agents to parse and act on.
- Structured output:
--jsonreturns clean, parseable data - Full CRUD: Read tasks, add new ones, update them, complete them
- Bulk operations: Complete multiple tasks at once
- Partial UUID matching: Agents can reference tasks with short IDs (e.g.,
17jJinstead of full UUID) - Natural language dates:
--when tomorrow,--when "next week"work intuitively - Filtering: Find tasks by tag, area, or project
- Export: Generate markdown/CSV reports
- Search: Find tasks by keyword without knowing exact titles
- Context-aware:
--verboseshows project/area context for better understanding
# Agent checks what's on today's list
thingsctl today --json
# Agent filters to specific tags
thingsctl today --tag Deep --json
# Agent adds a task with checklist
thingsctl add "Trip prep" --checklist "Passport,Tickets,Hotels"
# Agent updates a task
thingsctl update 7Ae --when tomorrow --append-notes "Discussed in meeting"
# Agent bulk completes tasks
thingsctl complete 17jJ ANsB 9pUS
# Agent exports today for summary
thingsctl export today --format md
# Get just IDs for scripting
TODAY_TASKS=$(thingsctl today --ids | tr '\n' ' ')
# Agent provides a daily briefing
thingsctl today --json | jq -r '.[] | "- \(.title)"'
# Agent checks upcoming deadlines
thingsctl due --json | jq '.[] | select(.deadline <= "2024-03-15")'You have access to Things 3 via thingsctl. Use these commands:
- `thingsctl today --json` — Get today's tasks
- `thingsctl today --tag <tag> --json` — Filter by tag
- `thingsctl add "<title>" --when today` — Add a task
- `thingsctl add "<title>" --checklist "Item1,Item2"` — Add with checklist
- `thingsctl update <id> --title "New"` — Update task
- `thingsctl complete <id>` — Mark task done
- `thingsctl complete <id1> <id2> <id3>` — Bulk complete
- `thingsctl search "<query>" --json` — Find tasks
- `thingsctl export today --format md` — Export as markdown
thingsctl reads directly from the Things 3 SQLite database (read-only mode):
~/Library/Group Containers/JLMPQHK86H.com.culturedcode.ThingsMac/
ThingsData-C1ON7/Things Database.thingsdatabase/main.sqlite
All modifications use the Things URL Scheme, the official way to interact with Things programmatically.
| Field | Values | Meaning |
|---|---|---|
todayIndex |
> 0 |
Task is in Today |
start |
0 |
Inbox |
start |
1 |
Anytime |
start |
2 |
Someday |
startDate |
Unix timestamp | Scheduled date |
Due to Things URL scheme constraints:
- Cannot create tags — Tags must already exist in Things
- Cannot set recurrence — Repeating tasks must be created in the app
- Cannot move to Inbox — URL scheme doesn't support this
- Cannot create headings — Headings must already exist in projects
- Things must be running — For write operations
# Add to ~/.bashrc or ~/.zshrc
alias t="thingsctl today"
alias tt="thingsctl today --verbose"
alias ta="thingsctl add"
alias tc="thingsctl complete"
alias ts="thingsctl search"
alias te="thingsctl export today --format md"# Select and complete a task interactively
thingsctl today --json | jq -r '.[] | "\(.uuid)\t\(.title)"' | \
fzf --with-nth=2 | cut -f1 | xargs thingsctl complete
# Select and update a task
TASK=$(thingsctl today --json | jq -r '.[] | "\(.uuid)\t\(.title)"' | fzf --with-nth=2 | cut -f1)
thingsctl update $TASK --when tomorrow# Complete all tasks with a specific tag
thingsctl today --tag Done --ids | xargs thingsctl complete
# Export today's tasks to clipboard
thingsctl export today --format md | pbcopy
# Daily task count
echo "Today: $(thingsctl today --ids | wc -l | tr -d ' ') tasks"MIT