add_material_image
ChatGPTPlace one image already stored in nav4ai, such as an imported image's URL, on an owned material's board, relative to a section, block, or picture. Whatever the placement lands on is pushed down to make room. It never changes what a block says, never deletes a block or section, and never shares or publishes the material. Saves one revision and returns material metadata, the refreshed board, a report, and whether it changed.
create_material
ChatGPTCreate a blank lesson or homework material in the authenticated teacher's Materials root and return it for editing. This does not start AI generation, publish homework, attach to a learner, or delete anything.
edit_material
ChatGPTEdit one owned material's sections and blocks by running Python in the same typed constructor sandbox as nav4ai's in-app editor. The code runs against the current lesson in the constructor form documented below; every existing id is stable, and a patch addresses a node by its id. A syntax or runtime error persists nothing. Otherwise every node is checked once at the end of the call: an invalid new node is dropped, an invalid edit reverts to the version the call started with, and the printed output, returned as report, names each one with the reason; whatever it reports as dropped or reverted is not in the lesson. Successful runs persist atomically as one revision and return the refreshed lesson; changed is false when the lesson is unchanged. With expected_updated_at set, an edit on a newer revision is refused. Scope: section and block content only. The title, level, theme, and board layout are out of reach of this tool, and so are pictures: an image passed to a constructor or written as a markdown image into block text is dropped or reverted. Audio and video need an already available supported URL. External embeds are accepted only for Wordwall, Miro, or Quizlet links listed in teacher_links or already in the lesson. Compact signatures: ``py Constructors build drafts: section(...) for a section, <block>(...) for a block. The id comes first and is unique and stable: "s2" for sections, "<section>-<type>-<n>" for blocks. Every field is optional in the signature because one constructor serves two purposes: - creating: pass the fields listed under "Required to create" in the docstring, then add the draft with add_sections(...) / add_blocks(...); - patching: pass only the fields to change and apply the draft with patch_node(...); unpassed fields keep their value, semantic fields (lines, options, cards, buckets, ...) are replaced whole. Omitted optional fields take the renderer's defaults. Every exercise also accepts feedback=, points=, maxAttempts=, checkLabel=, retryLabel= as extra keywords. Nothing is validated while building. At the end of the call every node is checked once: an invalid new node is dropped, an invalid edit reverts to the version the call started with, and a line says which and why. A constructor that cannot build at all prints one line and returns None, and None drafts are skipped by add/patch. from typing import Any, Literal, TypeAlias, TypedDict Draft: TypeAlias = dict[str, Any] Node: TypeAlias = Draft SectionNode: TypeAlias = Draft class Feedback(TypedDict, total=False): correct: str incorrect: str class Answer(TypedDict): label: str correct: bool class Error(TypedDict): kind: Literal["error"] text: str correction: str class Gap(TypedDict): ... class Card(TypedDict): ... class VocabularyItem(TypedDict): ... --- content blocks ----------------------------------------------------------- def section(id: str, title: str | None = None, blocks: list[Draft | None] | None = None, eyebrow: str | None = None, subtitle: str | None = None, *, appearance: Literal["plain", "card"] | None = None, backgroundColor: str | None = None, border: bool | None = None, borderColor: str | None = None) -> Draft: """ A lesson section holding blocks; its config is only the look (appearance="plain" drops the card). A section has no title of its own: it is named by the first heading of the text block placed first in blocks, and title/eyebrow/subtitle here are sugar that prepend that text block for you (###### eyebrow, ## title, subtitle). Required to create: nothing. section("s1", "Warm-up", eyebrow="5 min", blocks=[text("s1-text-1", "Look at the picture."), quiz_mcq("s1-quiz-mcq-1", ...)]) section("s2", blocks=[text("s2-title", "## Practice"), cloze("s2-cloze-1", ...)]) """ def text(id: str, text: str | None = None, *, look: Literal["hero", "banner", "objectives", "divider"] | None = None) -> Draft: """ Markdown text of any shape: headings (#, ##, ###; ###### = small eyebrow label), prose, lists, - [ ] task lists, quotes, GFM tables, ---` dividers…
get_group_context
ChatGPTGet one owned group's name, level, teacher-private note, archive state, and active member references. Does not return billing, photos, or meeting links.
get_homework_submission
ChatGPTGet a completed submission's effective score, teacher comment, and answer attempts. Returns no drafts, capability tokens, voice or photo media URLs, database attempt IDs, or debug fields.
get_material
ChatGPTGet one owned lesson or homework material for editing: metadata, the lesson as editable constructor code with stable ids, the current theme, the board with every section, block, and picture id and box, and the style targets the lesson contains. Read-only; renders nothing.
get_student_context
ChatGPTGet teaching context for one student owned by the authenticated teacher: display name, status, level, goal, teacher-private notes, locale, and timezone. Does not return email, billing, photos, or meeting links.
get_styling_brief
ChatGPTGet what styling one owned material takes, as nav4ai's in-app styler gets it: the styling guide (topic direction, colour and type system, backgrounds, CSS hooks, targeting, final design check), the current theme, the style_targets the lesson contains, and the brief token style_material requires. Read-only.
import_material_image
ChatGPTImport one image supplied by the MCP host into nav4ai storage for an owned material after validating its type, size, and dimensions, and return its stable nav4ai URL. The temporary source URL and host file reference are never persisted or returned. The material itself is unchanged: an imported image appears in the lesson only once it is placed on the board.
list_groups
ChatGPTList teaching groups owned by the authenticated teacher without billing or meeting details.
list_homework
ChatGPTList active homework owned by the authenticated teacher with its learner/group target and aggregate submission counts. Capability links and homework content are never returned.
list_homework_submissions
ChatGPTList completed submissions for one owned homework assignment. Draft work, capability tokens, answers, and voice or photo media are omitted.
list_materials
ChatGPTList lesson and homework materials owned by the authenticated teacher. Returns concise metadata without content, conversations, learner links, or internal workflow fields.
list_students
ChatGPTList students owned by the authenticated teacher. Returns teaching references, display names, statuses, and levels; goals and private notes are not included.
move_material_item
ChatGPTMove one picture, block, or section on an owned material's board, relative to another board item. Whatever the placement lands on is pushed down to make room. Sections move only on a Space board, and only above, below, left, or right of another section. It never changes what a block says, never deletes a block or section, and never shares or publishes the material. Saves one revision and returns material metadata, the refreshed board, a report, and whether it changed.
remove_material_image
ChatGPTTake one picture off an owned material's board. The stored image file is kept, so the same URL can be placed again. It never changes what a block says, never deletes a block or section, and never shares or publishes the material. Saves one revision and returns material metadata, the refreshed board, a report, and whether it changed.
render_material_preview
ChatGPTRender one owned material's board as PNG pictures: the top screen, or the whole board in up to 6 screen-sized strips from the top, as learners see it, with no answers revealed. Read-only. The pictures come back in the result; nothing is shown to the teacher.
resize_material_item
ChatGPTResize one picture, block, or section on an owned material's board. A picture keeps its shape and a block its content, so both take only a width (a picture 40-1600, a block 160-1600, at most 760 on a Feed board). A section takes a width (224-4000), a height (64-8000), or both, on a Space board only. It never changes what a block says, never deletes a block or section, and never shares or publishes the material. Saves one revision and returns material metadata, the refreshed board, a report, and whether it changed.
show_material
ChatGPTRender an interactive preview of one owned material for the teacher and return its complete lessons-sdk v4 manifest. Read-only: practice answers given in the preview are not saved.
style_material
ChatGPTChange one owned material's theme: background, width, density, palette, fonts, and scoped CSS. brief must be the token get_styling_brief issued for this material; without it nothing changes. CSS targets the hooks the brief's style_targets lists. theme is a patch merged into the current theme top-level field by field: an omitted field keeps its value and a null is ignored, never applied. A field that is sent replaces the current one whole, including the nested palette and fontPair objects, so changing one palette role means sending the whole palette. css is never partial: it replaces the complete stylesheet. Unknown keys are dropped. The change persists atomically; changed is false when nothing differed. The result includes a picture of the top of the board as the learner now sees it.
update_material_metadata
ChatGPTUpdate one owned material's title, level, or lesson/homework kind. Title and level are synchronized into the manifest envelope. This tool cannot otherwise change lesson content or theme.