edstem-cli
A terminal-first CLI for Ed Discussion: browse courses, lessons, threads, and comments without leaving the terminal.
Features
- Courses: list all enrolled courses
- Lessons: list course lessons and inspect lesson slides
- Lesson read automation: read matching lessons and push their slide status forward
- Threads: list, filter, and sort course threads
- Thread detail: view full thread with answers and comment tree
- Activity: browse your activity across courses
- User profile: view current user info
- JSON output: export any data for scripting and AI agent integration
AI Agent Tip: Always use
--jsonfor structured output instead of parsing the default rich-text display. Use--maxto limit results.
Installation
# Recommended: uv tool (fast, isolated)
uv tool install edstem-cli
# Alternative: pipx
pipx install edstem-cli
Agent Skill
Install the agent skill with the shared skills CLI spec:
npx skills add https://github.com/bunizao/edstem-cli
If you already installed edstem, the CLI exposes the same thing as a thin alias:
edstem skills add
If npx is not available, the alias falls back to npm exec.
Install from source:
git clone https://github.com/bunizao/edstem-cli.git
cd edstem-cli
uv sync
Update
Update the CLI in place:
edstem update
If you installed from source, update the checkout instead:
git pull
uv sync
Running an older version? Check with
edstem --versionfirst. If a command in this README does not exist locally, update the CLI before trying again.
Quick Start
Get your API token from: https://edstem.org/settings/api-tokens
# View your profile and courses
edstem user
# List enrolled courses
edstem courses
# List threads in a course
edstem threads 12345
# List lessons in a course
edstem lessons 12345
# View a thread with comments
edstem thread 67890
Usage
# Courses
edstem courses
edstem courses --archived
edstem courses --json
# Threads
edstem threads <course_id>
edstem threads <course_id> --sort top
edstem threads <course_id> --category "HW1"
edstem threads <course_id> --type question
edstem threads <course_id> --unanswered
edstem threads <course_id> --max 50 --json
# Thread detail
edstem thread <thread_id>
edstem thread <course_id>#<number> # by course thread number
edstem thread <thread_id> --json
edstem thread <thread_id> --md -o thread.md
edstem thread <thread_id> --json --pretty
edstem thread <thread_id> --json --include-html
edstem thread <thread_id> --json --legacy-json
# Lessons
edstem lessons <course_id>
edstem lessons <course_id> --module "Week 1"
edstem lessons <course_id> --type python --status attempted
edstem lesson <lesson_id>
edstem lesson <lesson_id> --json
edstem lesson <lesson_id> --md -o lesson.md
edstem lessons read <course_id> Pre-Reading
edstem lessons read <course_id> Week 3 Workshop
# Activity
edstem activity # all courses
edstem activity <course_id> # specific course
edstem activity --filter answer --json
# User
edstem user
edstem user --json
# Option 1: Environment variable
export ED_API_TOKEN="your-token-here"
# Option 2: Will prompt on first use and save automatically
edstem user
Thread JSON
edstem thread ... --json emits a compact thread shape by default. It hoists
authors into a top-level users map, drops XML content unless
--include-html is requested, trims default false/zero/empty fields, and adds
an endorsement block for source-marked endorsed replies and staff activity.
- Use
--prettywhen a human needs to read the JSON in the terminal. - Use
--legacy-jsonwhen an existing consumer still expects embedded authors and the verbose legacy shape.
Markdown Export
Use --md or --format md on full-detail commands when you want a readable
Markdown file instead of JSON:
edstem lesson 105199 --md -o lesson.md
edstem thread 29579#42 --md -o thread.md
Markdown output strips Ed XML into readable text and keeps lesson slides, thread answers, comments, nested replies, and visible source markers such as endorsed or anonymous replies.
Mark Lessons Read
Use lessons read when you want the CLI to visit lessons and push their slide status forward.
Query words are matched case-insensitively against lesson titles and module names.
For non-quiz slides the CLI calls the lesson completion endpoint. For quiz slides it records a view.
# Mark all pre-reading lessons in a course as read
edstem lessons read 29579 Pre-Reading
# Mark week 1 applied/workshop content as read
edstem lessons read 29579 Week 1 Workshop
edstem lessons read 29579 Week 1 Applied
# Add a delay between slide actions
edstem lessons read 29579 Applied --delay 0.3
# Export a machine-readable summary
edstem lessons read 29579 Pre-Reading --json
Configuration
Create config.yaml in your working directory:
fetch:
count: 30
rateLimit:
requestDelay: 1.0
maxRetries: 3
retryBaseDelay: 3.0
maxCount: 100
fetch.countis the default item count when--maxis omitted
Development
# Install dev dependencies
uv sync --extra dev
# Lint + tests
uv run ruff check .
uv run pytest -q
Acknowledgements
This project builds on ideas and structure from
twitter-cli.
Thanks to the original project for the foundation and inspiration.
Metadata
Release files for edstem-cli 0.3.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| edstem_cli-0.3.6.tar.gz | 87.6 kB | With provenance | Details for edstem_cli-0.3.6.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| edstem_cli-0.3.6-py3-none-any.whl | Python 3 | none | any | Details for edstem_cli-0.3.6-py3-none-any.whl |
Total release size: 124.8 kB
Release files / edstem_cli-0.3.6.tar.gz
| Download URL | edstem_cli-0.3.6.tar.gz |
|---|---|
| Size | 87.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d99077633052827b005f340aea4cd070e3d3f6b4e12b08c42001c5b0ab8e0c22
|
|
BLAKE2b-256 checksum How to use checksums |
5d5b65d73ea0d9299afb7be76004e93643179e22be11a325b9a28ecde79ec962
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 May 15, 2026.
Transparency logRelease files / edstem_cli-0.3.6-py3-none-any.whl
| Download URL | edstem_cli-0.3.6-py3-none-any.whl |
|---|---|
| Size | 37.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78e5d478599659582cf622f9ebf5a5fa58ddd5097a751a94250387ae39400714
|
|
BLAKE2b-256 checksum How to use checksums |
154bddb55457c9181e2920f9cd3eb0ffc00762632cc514769050fea4af6f9c1c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 May 15, 2026.
Transparency logSecurity for edstem-cli 0.3.6
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for edstem_cli-0.3.6.tar.gz
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 May 15, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.