- Brand
- NAV4AI
- Category
- Education
- Primary Subcategory
- K-12 Teaching & Curriculum Tools
Integration details
Description
nav4ai helps independent teachers review their students, groups, and completed homework in ChatGPT. Retrieve teaching context, including requested private notes and completed answers, then create, edit, style, and preview interactive lesson or homework materials. Import approved host-supplied images into materials. Changes to attached materials also update their lesson or homework content in nav4ai.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- K-12 Teaching & Curriculum Tools
- Secondary Subcategories
- None listed
- Brand
- NAV4AI
- Access
- Account required
- First tracked
- 2026-09-23
- Tool count
- 24
- Market
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for nav4ai
Get updates when nav4ai’s Discoverability Score or category rank changes.
Competing in ChatGPT K-12 Teaching & Curriculum Tools
View Category24 tools agents can invoke
Place 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`.
add_material_image
Make one owned material follow a design template (its theme becomes the template's and stays in step with it), or detach it with `template_id` null so it shows its own theme again.
apply_template
Create 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.
create_material
Edit 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. An edit whose `expected_updated_at` is not the current 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. Signatures (the authoring guide holds every field's notes and an example call): ```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. 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). Required to create: nothing. 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, $math$, ++underline++, ==highlight==, [[term|translation]] glosses. Required to create: text. def vocabulary_item(translation: str | None=None, *, example: str | None=None, ipa: str | None=None) -> VocabularyItem: # One entry of a vocabulary list; the term itself is the dict key in `vocabulary(items=...)`. def vocabulary(id: str, *, items: dict[str, VocabularyItem | str] | None=None, title: str | None=None, language: str | None=None) -> Draft: # A word list keyed by term. Required to create: items. def dialogue(id: str, *, lines: list[tuple[str, str] | str] | None=None, title: str | None=None) -> Draft: # A speaker-attributed conversation; `(speaker, text)` tuples or `"Speaker: text"` strings. Required to create: lines. def audio(id: str, *, src: str | None=None, title: str | None=None, transcript: list[str] | None=None) -> Draft: # A listening clip. Required to create: src. def video(id: str, *, src: str | None=None, poster: str | None=None, title: str | None=None) -> Draft: # A YouTube/Vimeo watch URL or a direct video file, copied from the brief or the lesson. Required to create: src. def answer(label: str) -> Answer: # Marks an option as correct inside `quiz_mcq`, `odd_one_out` and `select_gap`. def error(text: str, correction: str) -> Error: # The one wrong word of an `error_correction` sentence, inline where it stands, with its fix. def gap(*answers: str, caseSensitive: bool=False, hints: list[str] | None=None) -> Gap: # A blank the student types into; every listed answer is accepted. def select_gap(options: list[str | Answer], *, hints: list[str] | None=None) -> Gap: # A blank picked from a dropdown; exactly one option is wrapped in `answer(...)`. def card(back: str, *, hint: str | None=None) -> Card: # The back of a flashcard; the front is the dict key in `flashcards(cards=...)`. def quiz_mcq(id: str, *, prompt: str | None=None, options: list[str | Answer] | None=None) -> Draft: # One multiple-choice question. Required to create: prompt, options (with one answer(...)). def cloze(id: str, passage: list[str | Gap] | None=None, *, mode: Literal['type', 'drag'] | None=None, distractors: list[str] | None=None) -> Draft: # A gap-fill passage: markdown strings (as in `text`) interleaved with `gap(...)`/`select_gap(...)`, the blanks inline. Required to create: passage (with at least one gap). def flashcards(id: str, *, cards: dict[str, str | Card] | None=None, shuffle: bool | None=None, summary: str | None=None, frontLabel: str | None=None, backLabel: str | None=None, flipLabel: str | None=None, knownLabel: str | None=None, unknownLabel: str | None=None, restartLabel: str | None=None) -> Draft: # A flip-card study deck keyed by front. Required to create: cards. def match(id: str, *, pairs: dict[str, str] | None=None, prompt: str | None=None, leftLabel: str | None=None, rightLabel: str | None=None, shuffle: bool | None=None, rightOrder: list[str] | None=None) -> Draft: # Two-column matching, left to right. Required to create: pairs. def truefalse(id: str, *, text: str | None=None, answer: bool | None=None, prompt: str | None=None, trueLabel: str | None=None, falseLabel: str | None=None) -> Draft: # One statement with a True/False toggle. Required to create: text, answer. def order(id: str, *, parts: list[str] | None=None, prompt: str | None=None, shuffle: bool | None=None) -> Draft: # Arrange parts into the correct sequence. Required to create: parts. def odd_one_out(id: str, *, items: list[str | Answer] | None=None, prompt: str | None=None, reason: str | None=None) -> Draft: # Tap the item that does not belong; exactly one is wrapped in `answer(...)`. Required to create: items (with one answer(...)). def tfng(id: str, *, text: str | None=None, answer: Literal['true', 'false', 'not-given'] | None=None, passage: str | None=None, prompt: str | None=None, trueLabel: str | None=None, falseLabel: str | None=None, notGivenLabel: str | None=None) -> Draft: # Reading statement judged True / False / Not Given against `passage`. Required to create: text, answer. def verb_conjugation(id: str, *, subject: str | None=None, verb: str | None=None, accepted: list[str] | None=None, tense: str | None=None, prompt: str | None=None, caseSensitive: bool | None=None) -> Draft: # Type the conjugated form for one subject + verb cue. Required to create: subject, verb, accepted. def word_formation(id: str, passage: list[str | Gap] | None=None, *, root: str | None=None, prompt: str | None=None) -> Draft: # One sentence with exactly one `gap(...)` that the student fills by transforming `root`; its strings are markdown, as in `cloze`. Required to create: passage (with exactly one gap), root. def anagram(id: str, *, answer: str | None=None, scrambled: str | None=None, clue: str | None=None, prompt: str | None=None, caseSensitive: bool | None=None) -> Draft: # Unscramble letters into one word; omit `scrambled` to auto-shuffle. Required to create: answer. def word_bank(id: str, *, tokens: list[str] | None=None, prompt: str | None=None, distractors: list[str] | None=None, acceptedAnswers: list[list[str]] | None=None, caseSensitive: bool | None=None) -> Draft: # Build a sentence from shuffled word tiles; always add distractors. Required to create: tokens. def error_correction(id: str, passage: list[str | Error] | None=None, *, options: list[str] | None=None, prompt: str | None=None, caseSensitive: bool | None=None) -> Draft: # A sentence whose words the student taps, with exactly one `error(text, correction)` inline where the wrong word stands. Required to create: passage (with one error(...)). def free_text_input(id: str, *, prompt: str | None=None, placeholder: str | None=None, rows: int | None=None, limit: int | None=None, limitUnit: Literal['words', 'chars'] | None=None, submitLabel: str | None=None) -> Draft: # An open written answer, saved for the teacher; not graded. Required to create: nothing. def voice_response(id: str, *, prompt: str | None=None, modelAudio: dict[str, Any] | None=None, showTranscript: bool | None=None, maxDuration: Literal[30, 60, 120, 300] | None=None) -> Draft: # An ungraded spoken answer. Required to create: prompt. def photo_response(id: str, *, prompt: str | None=None, maxPhotos: int | None=None) -> Draft: # An ungraded photo answer: the learner photographs work done on paper. Required to create: prompt. maxPhotos is 1-10 and defaults to 5. def hangman(id: str, *, word: str | None=None, clue: str | None=None, prompt: str | None=None, lives: int | None=None) -> Draft: # Guess a hidden word letter by letter; auto-checks. Required to create: word. def categorize(id: str, *, buckets: dict[str, list[str]] | None=None, prompt: str | None=None, shuffle: bool | None=None) -> Draft: # Sort items into buckets, keyed by bucket label. Required to create: buckets. def add_feedback(draft: Draft | None, *, correct: str | None=None, incorrect: str | None=None) -> Draft | None: # Attach feedback text to an exercise draft and return it. def add_grading(draft: Draft | None, *, points: float | None=None, maxAttempts: int | None=None, checkLabel: str | None=None, retryLabel: str | None=None) -> Draft | None: # Attach scoring to an exercise draft and return it. def get_sections() -> list[SectionNode]: # Return the current lesson as a list of sections. def find_section(id: str) -> SectionNode | None: # The section with that id, or None (a line is printed). def find_node(id: str) -> tuple[SectionNode, Node] | None: # A block and the section that holds it. def section_nodes(section: SectionNode) -> list[Node]: # The blocks of a section, in order. def add_sections(new: list[Draft | None], *, after_id: str | None=None, before_id: str | None=None) -> None: # Insert sections after/before a section id, or append. def add_blocks(new: list[Draft | None], section_id: str | None=None, *, after_id: str | None=None, before_id: str | None=None) -> None: # Insert blocks into `section_id` (appends), or next to a block id. def patch_node(draft: Draft | None) -> Draft | None: # Apply a draft to the existing block or section with the same id and type; only the passed fields change. def replace_node(id: str, new: Draft | None) -> Draft | None: # Swap a block for a whole new draft, keeping the old id; use it to change a block's type. def remove_nodes(ids: list[str]) -> None: # Remove sections and/or blocks by id. def move_sections(ids: list[str], *, after_id: str | None=None, before_id: str | None=None) -> None: # Move sections, in the given order, next to another section. def move_blocks(ids: list[str], section_id: str | None=None, *, after_id: str | None=None, before_id: str | None=None) -> None: # Move blocks into `section_id` (appends) or next to a block id, across sections. async def external_embed(url: str, title: str | None=None) -> Draft | None: # A Wordwall, Miro or Quizlet activity from a link the teacher supplied, as given. ``` `code` holds executable lesson-edit statements only: the signatures above are reference, not code to send.
edit_material
Get what authoring one material takes, as nav4ai's in-app workers get it: the lesson authoring guide (what belongs in a lesson versus a homework, the default shape, choosing blocks by teaching purpose, quality rules, the batched editing workflow) and the complete edit_material constructor reference, every constructor and helper with its fields, what it needs to create, and an example call. Read-only; the same for every material.
get_authoring_guide
Get one owned group's name, level, teacher-private note, archive state, and active member references. Does not return billing, photos, or meeting links.
get_group_context
Get 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_homework_submission
Get 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_material
Get 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_student_context
Get 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.
get_styling_brief
Import 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.
import_material_image
List the authenticated teacher's design templates: reusable themes a material can follow. The default template is what every new material starts with.
list_templates
List teaching groups owned by the authenticated teacher without billing or meeting details.
list_groups
List 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
List completed submissions for one owned homework assignment. Draft work, capability tokens, answers, and voice or photo media are omitted.
list_homework_submissions
List lesson and homework materials owned by the authenticated teacher. Returns concise metadata without content, conversations, learner links, or internal workflow fields.
list_materials
List students owned by the authenticated teacher. Returns teaching references, display names, statuses, and levels; goals and private notes are not included.
list_students
Move 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`.
move_material_item
Take 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`.
remove_material_image
Render 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.
render_material_preview
Resize 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`.
resize_material_item
Render an interactive preview of one owned material for the teacher and return its complete lesson manifest. Read-only: practice answers given in the preview are not saved.
show_material
Change 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. A material that follows a design template (`template_id` set) is refused: its look is the template's. `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.
style_material
Update 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.
update_material_metadata
nav4ai ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve nav4ai's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are nav4ai alternatives on ChatGPT?
As of 2026-11-02, nav4ai competes with AnyLessonPlan for Teachers, Brisk Teaching, ChildEdu Studio, CL for Desmos & Amplify, ClassWise School & District, Cody Reading, CubbyEd Classical Curriculum, Diffit for Teachers and 21 more in ChatGPT K-12 Teaching & Curriculum Tools, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.