All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
get_attachments(message_id)— list all attachments for a message (name, mime type, size, file ID)download_attachment(message_id, file_id, save_path?)— download an attachment; defaults to~/Downloads/smartschool/, accepts optionalsave_pathhas_attachmentsandattachment_countfields in everyget_messagesresult
download_attachmentcallssession.get()directly instead of the upstream library'sAttachment.download(), which incorrectly base64-decodes a raw binary response (upstream bug)
0.2.0 - 2026-03-25
- Remote MCP support via Streamable HTTP transport (
--transport streamable-http) --host,--portCLI flags withMCP_HOST,MCP_PORT,MCP_TRANSPORTenv var counterparts- Optional Bearer-token authentication via
MCP_API_KEY(_BearerAuthMiddleware) - CORS middleware — required for browser-based clients such as claude.ai
get_schedule(date_offset)— daily lesson schedule viaSmartschoolLessonsget_periods()— academic terms/periods viaPeriodsget_reports()— report cards viaReportsget_planned_elements(days_ahead)— planner items viaPlannedElementsget_student_support_links()— school support resources viaStudentSupportLinksachieved_points,total_points,percentagefields inget_resultsteacher(fromgradebook_owner, no extra API call) andperiodinget_resultswarningfield inget_future_taskstasks- Lazy
_session()singleton — session is created on first tool invocation, not at import time - Professional OSS infrastructure: CI workflow, issue/PR templates, CodeRabbitAI, pre-commit, tests
- Updated
smartschooldependency from personal fork (v0.5.0) to official library (svaningelgem/smartschoolv0.8.0+) - Relaxed Python requirement from
>=3.13to>=3.10 - Modernized all type hints: replaced
typing.List/Dict/Optionalwith built-in generics (list,dict,str | None) get_results: teacher now read fromresult.gradebook_owner(always available); details fetch only used for central tendenciesget_messages: sender filter applied directly from headers (no full message fetch needed); body fetched lazilyget_future_tasks: fixedcourse.course_title(was incorrectlycourse.name)- Fixed
total_taskscalculation (was counting dict keys, not tasks) - Fixed
result.availability_dateandresult.does_countattribute names (camelCase → snake_case) - Fixed
teacher.name.starting_with_last_name/starting_with_first_nameattribute names - Fixed
header.unread(washeader.read) - Replaced removed
ResultDetailclass with lazy-loadedresult.detailsproperty - Updated
publish.ymlto useuv buildinstead of legacypython -m build+ pip
ResultDetailimport (class removed in official smartschool library)
0.1.4 - 2026-03-01
- Initial release with
get_courses,get_results,get_future_tasks,get_messagestools - Claude Desktop integration via stdio transport
- PyPI distribution and MCP Registry listing