MDXCanvas allows you to define Canvas course content using source files (.md, .xml, .jinja, etc.) and deploy it programmatically to a Canvas instance via the API.
Install via pip:
pip install mdxcanvasYou must also create a Canvas API Token from your Canvas account settings and store it as an environment variable:
export CANVAS_API_TOKEN="your_token_here"To deploy content to Canvas, run:
mdxcanvas --course-info <course_info.json> <content_file>A configuration file specifying course deployment details. Supported formats:
- YAML (
.yaml,.yml) - Recommended - JSON (
.json) - MarkdownData (
.md,.mdd)
The file must include:
CANVAS_API_URLCANVAS_COURSE_IDLOCAL_TIME_ZONE
Example (YAML):
CANVAS_API_URL: https://byu.instructure.com/
CANVAS_COURSE_ID: 12345
LOCAL_TIME_ZONE: America/DenverFor extended options like COURSE_NAME, COURSE_IMAGE, GLOBAL_ARGS, etc., see the
Course Info Guide.
The content file defines what will be pushed to Canvas. Supported formats:
.md.xml.html.jinja
Example (.xml quiz):
<quiz title="Example Quiz">
<description>
# Attention
The following questions test your knowledge of the wizzarding world of **Harry Potter**.
</description>
<questions>
<question type="multiple-choice">
Who is the author of the Harry Potter series?
<correct>J.K. Rowling</correct>
<incorrect>J.R.R. Tolkien</incorrect>
<incorrect>George R.R. Martin</incorrect>
<incorrect>Stephen King</incorrect>
</question>
<question type="true-false" answer="true">
Is Harry Potter a wizard?
</question>
</questions>
</quiz>As shown above, Markdown formatting is supported within content.
See the Demo Course for complete examples.
The mdxcanvas command supports the following options:
--course-info <file>- Path to course configuration file (YAML/JSON/MarkdownData)--args <file>- Path to template arguments file (for Jinja templates)--global-args <file>- Path to global arguments file (merged withGLOBAL_ARGSfrom course_info)--templates <files>- List of template files to import--css <file>- Path to CSS file for styling--debug- Enable debug logging--dryrun/--dry-run- Preview changes without deploying to Canvas--output-file <file>- Save deployment report to specified file
Example with options:
mdxcanvas --course-info course.yaml \
--global-args globals.yaml \
--css styles.css \
--dryrun \
content.xmlThe erasecanvas command removes all content from a Canvas course.
WARNING: This is a destructive operation that cannot be undone.
Usage:
erasecanvas --course-info <course_info.yaml>Options:
--course-info <file>- Path to course configuration file (required)-y- Skip confirmation prompt (use with caution!)
The command will delete:
- Syllabus content
- All assignments and quizzes
- All pages
- All modules
- All files and folders
- All announcements
Without the -y flag, you will be prompted to confirm before deletion proceeds.
These guides cover the full feature set of MDXCanvas:
Configure course metadata such as name, code, and dashboard image.
Full reference of standard content tags like <assignment>, <quiz>, <page>, and more.
Advanced features like <include>, <file>, and <zip> for modular, reusable content.
Use variables and loops to dynamically generate content using .jinja templates.
Apply custom styling across your content using external CSS files.
Explore the demo_course folder to see MDXCanvas in action: