Local files
The .canvas-cli folder, file by file: course caches, workspaces, chat sessions, and exports.
Layout
Everything canvas-cli learns about your courses is written to a .canvas-cli folder in the directory you start it from. It is plain JSON, text, and the original files, so you can read, search, or back it up with ordinary tools. Nothing in it is needed by anyone else, so keep it out of version control:
echo ".canvas-cli/" >> .gitignoreIf you keep a .env file with keys in the same folder, ignore it too.
.canvas-cli/
├── user-courses.json your course list and short names
├── courses/
│ └── ece216-101/ one folder per ingested course
├── sessions/
│ └── ece216-lab-3-fourier-series-10100/ one folder per workspace
├── chat-sessions/
│ ├── index.json
│ ├── global-home.json
│ ├── course-101.json
│ └── workspace-ece216-lab-3-fourier-series-10100.json
└── exports/ PDFs made outside a workspaceBecause the folder belongs to the directory, you can keep separate setups side by side, one folder per term for example, each with its own course list and cache.
courses/
One folder per course, named from its code and Canvas id, written by ingestion.
| Path | Contents |
|---|---|
course.json | Name, code, term, dates, and the syllabus |
assignments.json | An index of assignments: dates, points, and how to submit. Descriptions, rubrics, and your feedback are in extracted/ |
modules.json | Modules and their items, in order |
files.json | The Files tab index |
pages.json | An index of every page, including the generated reference pages |
announcements.json, discussions.json | Indexes of posts with authors, dates, and reply counts; the text is in extracted/ |
lectures.json | Discovered lectures: slides, recordings, and embeds |
external-links.json | Linked outside content and whether it was captured |
syllabus-candidates.json | Likely syllabus sources, ranked |
attachments.json | Every file downloaded, skipped, or failed, and why |
ingestion.json | When it ran and what it counted |
attachments/ | The original files, in folders by where they came from |
extracted/ | Plain text for pages, assignments, posts, links, and every document |
Files are written atomically, so an interrupted run never leaves a half-written file. Ingesting again rewrites the indexes, so items removed from Canvas drop out of them, but downloaded files and extracted text stay on disk until you clean up.
sessions/
One folder per workspace, named from the course code, assignment name, and id. It holds the brief (assignment.md), the plan (plan.md), your notes (notes.md, never overwritten), the structured workup (workup.json), the text the investigation read, an empty work/ folder for you, and exports/ for PDFs made there. Assignment workspaces lists every file.
chat-sessions/
One JSON file per conversation: global-home for the home screen, course-<id> per course, and workspace-<folder> per workspace, plus an index.json that /recent reads. Each file holds the messages and a little metadata, such as the last PDF you exported, which is what /open it opens. Deleting a file starts that conversation fresh.
exports/
PDFs from /pdf made outside a workspace, named with the UTC date and time and a short title, such as 20260923-201500-lab-3-study-guide.pdf, with the Markdown (and LaTeX) source beside each. PDFs made inside a workspace go to that workspace’s own exports/ folder.
Config Directory
Separate from all of this, your sign-in lives in your home folder:
~/.config/canvas-cli/
├── config.json default profile settings
├── config.summer.json another profile
└── credentials/ only when the Keychain is not used
├── default.canvas-token
└── default.anthropic-keySee Profiles and settings. The folder and files are readable only by you.
Cleaning Up
| Command | Removes |
|---|---|
canvas-cli clean | The .canvas-cli folder in the current directory |
canvas-cli clean --all | That, plus every profile’s sign-in and the config folder |
canvas-cli logout | One profile's sign-in, leaving local data alone |