cctodo
The command line tool and Python client for ccToDo, made by CloudCircus.
pip install cctodo
cctodo login # paste a token from Settings → API tokens
cctodo mytasks
cctodo new -group "work group" "my task"
cctodo done 123
It uses only the Python standard library and needs Python 3.9 or newer.
Commands
Tasks are shown with their id (#123), and the commands take that id. Where a command takes a group,
you can give its id, its title, or the start of the title (case-insensitive). Without -g, commands
use your My Tasks.
| Command | What it does |
|---|---|
cctodo mytasks (my) |
Your pending My Tasks. -c shows completed tasks instead. |
cctodo list [GROUP] (ls) |
A group's pending tasks. --all lists every group, -c shows completed tasks. |
cctodo assigned |
Pending tasks assigned to you, in all groups. |
cctodo groups |
Your groups, with their pending counts. |
cctodo new TITLE… [-g GROUP] [-a WHO] [-b BODY] [-e] (add) |
Adds a task at the bottom of the list. -b - reads the details from stdin; -e writes the title and details in $EDITOR. |
cctodo show ID |
A task with its details (markdown) and comments. |
cctodo done ID… / start ID… / reopen ID… |
Sets the state to done, in progress, or to do. |
cctodo edit ID [-t TITLE] [-b BODY] |
Edits a task. With no options it opens $EDITOR: the first line is the title and the rest is the details. It refuses to overwrite someone else's newer edit. |
cctodo assign ID WHO |
Assigns to me, a member's email, or none. |
cctodo mv ID -g GROUP / mv ID --before ID2 / --after ID2 |
Moves a task to another group, or reorders it. |
cctodo rm ID… [-y] |
Deletes tasks after asking you to confirm. |
cctodo comment ID TEXT… [-r COMMENT_ID] |
Adds a comment, or a reply with -r. |
cctodo group new/rename/members/leave/rm |
Manages groups. |
cctodo invite GROUP EMAIL [-m MESSAGE] |
Invites someone. If you're a member rather than an owner, an owner approves the invite first. |
cctodo invites / accept ID / decline ID |
Lists and answers invites addressed to you. |
cctodo whoami / logout |
Shows the account you're logged in as, or forgets the saved token. |
Add --json to any command for the raw API output. NO_COLOR turns colours off.
Exit codes:
0: the command succeeded.1: an error occurred.3: you're not logged in, or your token was revoked.
Configuration
cctodo login saves the token in ~/.config/cctodo/config.json, readable only by you
(%APPDATA%\cctodo\config.json on Windows). You can set these environment variables instead:
CCTODO_TOKEN: the API token.CCTODO_API_URL: the API address. It defaults tohttps://api.cctodo.com.CCTODO_CONFIG: a different config file.
To revoke a token, go to Settings → API tokens on www.cctodo.com.
Python
from cctodo import Client, Conflict
todo = Client() # the same token as the CLI (or Client(token="cct_..."))
work = todo.find_group("work group")
task = todo.create_task(work.id, "Write the report", body="Due **Friday**")
todo.assign(task.id, todo.me().id)
todo.start(task.id)
for t in todo.tasks(work.id): # pending tasks, in order
print(t.id, t.state, t.title) # attribute or t["title"] access
try:
todo.update_task(task.id, body="…", expected_updated_at=task.updated_at)
except Conflict:
print("Someone else changed it first")
Return values: results are the API's JSON as Record objects (dicts with attribute access).
Errors: errors raise cctodo.NotFound (404; this also covers groups you're not in), NotAllowed (403),
Invalid (400), Conflict (409), RateLimited (429) or Unauthorized (401). All of them subclass cctodo.CctodoError.
Development
pip install -e .
python -m unittest discover -s . -t .
CCTODO_API_URL=http://api.localhost:8000 cctodo whoami # against a local cctodo_web
Licence
MIT. See LICENSE.
Metadata
Release files for cctodo 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cctodo-0.1.0.tar.gz | 19.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cctodo-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.8 kB
Release files / cctodo-0.1.0.tar.gz
| Download URL | cctodo-0.1.0.tar.gz |
|---|---|
| Size | 19.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ea617fd5f477082bf5e5d98f1dea0f6730d77f30d941217e005bc5d7dbed88c6
|
|
BLAKE2b-256 checksum How to use checksums |
8fddf456883eec0ed16e6b635b7dda0ad3b6d465f92c843b1973ebf88a52fd58
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / cctodo-0.1.0-py3-none-any.whl
| Download URL | cctodo-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3523e867277a50003614176cc7a45add6761444a4b5def594fa097bcc896872f
|
|
BLAKE2b-256 checksum How to use checksums |
8acaeea93f7404372e458e1620a49753ba3eb3f164708b97d7a040614573b776
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log