get_grammar_level
ChatGPTGet a compact summary of which grammar the logged-in user has already studied, for shaping the AI's own sentence complexity during free conversation practice (not quizzing). currentLevel is a curriculum position derived from recorded mastery, not a placement-test result or an ability ceiling. levelProgress gives known/total topic counts per level. knownTopics lists every topic the user has started, in curriculum order, each with its englishForm (the grammar structure itself, e.g. 'have been doing') and learningStatus so you know how solid it is. Missing records, including an empty knownTopics, mean ability is unknown, not that the user is a beginner. Reading completion is stored separately and is not reflected here. Use these records as a starting hint alongside diagnosis results, the user's requested practice, and their actual responses; adjust sentence complexity as needed.
get_last_study_session
ChatGPTGet where the user last left off in grammar study (saved by save_study_session), so a new conversation can resume there instead of asking the user to recap or guessing from readingStatus/get_weak_topics alone. This is a single most-recent checkpoint, not a session history — separate from readingStatus, official mastery/SRS, and the AI-understanding notes in save_topic_understanding/get_weak_topics; it only points at 'what was being worked on and what's next'. Call this when the user wants to continue where they left off. Afterward, still call get_topic(topicId) to refresh goals/content/status before actually resuming — don't treat the checkpoint's own copy of goal IDs/topic details as current, since the topic may have changed since it was saved. If resumeAvailable is false, the referenced topic or goal no longer exists (deleted or restructured) — unavailableReason says which. You can still read summary/nextAction for context, but don't call get_question or update progress using nextGoalId/topicId in that case; fall back to get_topic/get_weak_topics instead.
get_learning_growth
ChatGPTGet how the user's cumulative progress (memorized words, perfect words, completed grammar topics) has changed over time, as a series of points bucketed by day/week/month depending on range. This is the same trend chart shown on suplla's mypage — use it to talk about the user's trajectory over sessions (e.g. 'この1ヶ月で覚えた単語が20個増えたね'), which get_learning_status alone can't show since it only reflects today. Each point's counts are cumulative as of that bucket's date, not per-bucket deltas — subtract consecutive points yourself if you need the change within a period.
get_learning_status
ChatGPTGet the logged-in user's learning status: how many words/grammar topics are due for review, how many they've already studied today, their current daily streak, and their daily goals (words/lessons). url links to the progress page on suplla.com — point users there if they want more detail. Note: wordReviewedToday/dueWordCount only reflect suplla's real DB progress, which for word review specifically only persists for premium users — a free user practicing with you won't move these numbers even though they're genuinely studying, so don't treat a low number as proof they've done nothing today. currentStreak is unaffected by this — it's a simple daily-activity counter that updates for every user regardless of premium.
get_lesson
ChatGPTGet a lesson from suplla's structured '/lesson' course path — a curated, ordered sequence of activities (grammar explanation/reading, exercises, word practice, phrase scenes) built from the same underlying content as get_topic/get_question/get_word, plus the user's own progress on it. Call without lessonId to get the next lesson in the user's roadmap (resuming from their most recently completed lesson, or from the start if none). Work through steps in order, resolving each one via the tool named in its type description. completion.mode tells you what finishing means: 'test' -> grade the exercise steps and report accuracy via update_lesson_progress; 'check'/'read' -> call update_lesson_progress once all steps are done, no grading needed.
get_next_words
ChatGPTGet a small batch of words the user hasn't started yet (no learning_status at all — this is for introducing brand-new vocabulary, not review; use get_weak_words for that). Two modes, matching get_topic's mode pattern — see OFFER_VOCABULARY_STUDY_MODES for when to offer which to the user rather than picking silently: 'level' (default) scopes to their target_level (or study_level if no target is set) and prioritizes words connected — synonym, antonym, derivation, or shared etymology — to a word they've already solidly learned (memorized/perfect), returned as connection; connecting new vocabulary to what's already known helps it stick (elaborative encoding). 'topic' (pass topicId) returns words tied to that specific grammar topic instead, returned as reason explaining the tie (e.g. 'be動詞の基本'); not every topic has these tagged, so an empty list means untagged, not that the topic has no relevant vocabulary — fall back to 'level' mode. Whichever mode gives you a connection or reason, use it explicitly when introducing the word rather than presenting it cold — but always be clear about which word is the new one to actually remember versus just context, since blurring that raises cognitive load instead of lowering it. If harderThanConnection is true, say so plainly rather than treating it as equally easy. Keep batches small (the default) — introducing too many new words in one go hurts retention more than it helps; don't raise the limit just to cover more ground faster.
get_question
ChatGPTGet one or more suplla English exercises. The correct answer is included, so use it to grade the user's response during the conversation. topicId/level/goalId/exerciseType/count are all optional. If both topicId and exerciseType are omitted, this first checks whether the user has words due for SRS review and prefers those; otherwise it returns a random multiple-choice question. Set count to get several at once in a single call. To target a specific topic, look up its ID with list_topics first. To target a specific learning goal within a topic (instead of a random mix from the whole topic), pass goalId from get_topic's goals[].id.
get_recent_word_review_session
ChatGPTGet the user's most recent word-review sessions done directly on the suplla website (not through you) — format used, score, and which words were covered. Use this when the user refers back to something they just did on the site (e.g. 'I just did a review round, how'd I do?') so you can react to the actual result instead of asking them to describe it. This data is short-lived (auto-deleted after 24 hours) — it's for catching up on very recent activity, not a long-term history; for that, use get_word/get_learning_status instead. Returns an empty list if nothing recent.
get_study_goal
ChatGPTGet the level the user is aiming to eventually reach (targetLevel, as opposed to get_grammar_level's currentLevel — where they actually are now) and how they want you to approach the gap (studyStyle). These two are set together as one group in suplla's settings screen, never by you — both come back null if the user hasn't set a goal yet. Levels run junior-high-1/2/3, then high-school-1/2/3. Rough Eiken (English proficiency test) equivalence, if the user talks about Eiken instead of a grade: junior-high-3 ≈ Eiken grade 3, high-school-2 ≈ Eiken pre-2. studyStyle 'forward' means work sequentially from currentLevel toward targetLevel; 'backward' means start from content near targetLevel and identify specifically what's missing, backfilling earlier topics only when a gap surfaces. settingsUrl is where the user sets or changes either value — hand them that link (see DONT_READ_URLS_LITERALLY) rather than describing where to find it.
get_topic
ChatGPTGet a grammar topic's explanation (content), description, and learning goals, plus the logged-in user's status (learningStatus/learningStatusLabel/learningStatusOrder/reviewStage/lastReviewedAt/readingStatus). When topicId is omitted, mode controls what you get: 'next' (default) returns the next topic in curriculum order the user hasn't finished reading yet; 'review' returns an already-started topic, ordered by how due it is for review. Use mode='next' for a guided walkthrough of new material, or mode='review' when the user wants to look back at what they've studied — call this repeatedly with topicId omitted to go topic by topic. learningStatusOrder: higher means further along. readingStatus ('unread'/'learning'/'completed', from update_topic_reading_status) is a separate, simpler signal from learningStatus — it tracks whether the topic is recorded as in progress or read, not quiz mastery. Unread may already be familiar; completed does not prove ability or a previous AI explanation. Adapt support to the current conversation rather than using this flag to force stricter drilling. For mode='next' (topicId omitted), readingStatus is also what drives topic selection now — a topic already marked 'completed' is never re-selected, regardless of official quiz mastery. url links to the page on suplla.com — point users there if they want to see it on the web. Use this to explain a topic before quizzing, or to check what a topic covers before calling get_question. Each goal's id can be passed as get_question's goalId (topicId is required alongside it — grammar_topic_goal.id is only unique within its topic, not globally) to target questions at that specific goal instead of the whole topic. Each goal's url deep-links straight to that goal's section on suplla.com — prefer it over the topic-level url when pointing the user at one specific goal.
get_weak_topics
ChatGPTGet the topics the user is weakest on, weakest first, merging two sources: suplla's own official diagnosis test (statistically grounded, from a proper adaptive-testing engine) and your own past conversations' judgment (from save_topic_understanding — a much rougher, session-by-session impression). Each topic's source tells you which: 'diagnosis' or 'diagnosis_and_ai_assessment' entries are backed by the real test and should be trusted more; 'ai_assessment'-only entries are just your own past read on it. Check this before suggesting a review round, so you can prioritize a topic/goal flagged weak instead of picking one at random or relying only on SRS due-dates (get_learning_status/get_topic mode='review'). Returns an empty list if nothing has been assessed yet, or nothing is currently weak. Each weakGoals[].url deep-links straight to that goal's section on suplla.com — prefer it over the topic-level url when telling the user what to read. weakGoals is only ever populated for 'ai_assessment' sources (the diagnosis test doesn't break results down by goal). If the user has taken the official diagnosis test, diagnosis also carries its own generated aiSummary/aiAdvice (the test's own written take on the user's level) and strongTopics (topics it found solid) — read these before repeating what a mere probability number already told you.
get_weak_words
ChatGPTGet the user's actual SRS progress (suplla's real learning_status/review_stage, not an AI judgment) for words they haven't solidly memorized yet, least advanced first. Check this before suggesting a word-review round, so you can prioritize genuinely weak words instead of relying only on due-dates (get_learning_status / get_question exerciseType='word_review'). Returns an empty list if the user has no in-progress words below 'memorized'.
get_word
ChatGPTGet a word's meaning, forms, pronunciation, and example sentences (English/Japanese) for each part of speech, plus the logged-in user's proficiency status (learningStatus etc.), for the given slug (from get_question's word_review, list_topics' url, etc.). The connections field lists which visual 'connections' views actually have data for this word (relation: related words, lexical: collocations, pattern: sentence patterns, conversation: conversation phrases). Each entry's url opens a minimal page showing just that view as a diagram (no article text) — link there when the user wants to see the full picture. For the 'relation' kind specifically, relatedWords gives you the actual content (related words, linked grammar topics, usage comparisons, homographs) including each relation's reason — use this to explain word roots and connections directly in conversation instead of just pointing at the diagram.
get_writing_check
ChatGPTGet one or more Japanese-to-English translation prompts from suplla's AI文法チェック (/learning/grammar-check) question bank — the same pool used by the site's own dedicated writing-practice mode, drawn from across all grammar topics rather than tied to one. Each item's answer is the correct English translation; use it as your grading anchor the way you would sample_answer for a get_question composition item — check meaning and grammar, not verbatim wording, and give feedback in the conversation. This is a premium feature: for a free user, found comes back false with reason 'premium_required' and no questions are returned — the user can still translate sentences with you conversationally, but this dedicated writing-check session needs suplla premium. When that happens, mention it once, briefly, and keep going normally rather than refusing to help with translation at all.
list_topics
ChatGPTList suplla's grammar topics (grammar_topic), each with the logged-in user's status. Includes learningStatus (id like unread/learning/memorized), learningStatusLabel (the app's own Japanese display name), and learningStatusOrder (progress ordering — higher means further along). Use this to check the grade level / unit / progress before picking a topicId for get_question. Filter with level, or omit it to get all.
record_word_result
ChatGPTRecord whether the user got a word right or wrong, updating suplla's real SRS progress (learning_status/review_stage) for it — this is the write counterpart to reviewing a word from get_question's word_review, or practicing a word just introduced via get_next_words. Call this once per word right after you've graded the user's answer, the same way update_topic_reading_status/save_topic_understanding record grammar progress. Saving real SRS progress is a premium feature: for a free user, recorded comes back false and nothing is written — the user can still practice the word with you (the conversation itself isn't gated), but this specific attempt won't count toward their actual learning_status/review_stage in suplla. When recorded is false, mention once, briefly, that saving progress on this needs suplla premium (don't repeat this every single word) and keep going normally.
report_data_issue
ChatGPTUse this whenever you notice during the conversation that some data looks wrong (e.g. a displayed progress count doesn't match what the user reports, or a question's text/answer is clearly broken). Don't block your response to the user — just log it and keep going.
save_study_session
ChatGPTSave where the user currently is in grammar study, so a future session (get_last_study_session) can resume from here instead of the user having to recap or you having to reconstruct it from readingStatus/get_weak_topics alone. This replaces the user's one existing checkpoint entirely (there's only ever one) — it does not touch readingStatus, official mastery/SRS, or save_topic_understanding's AI-understanding note; those are separate records with separate purposes. Save every time the resume position actually changes (after checking a goal, moving to a new goal/topic, or the user pausing) — don't wait for a clean end-of-topic moment. This uses optimistic concurrency: pass the revision from your last get_last_study_session/save_study_session call as expectedRevision (0 for a brand-new checkpoint, i.e. found:false from get_last_study_session). If another save has happened since (revision mismatch), this returns saved:false, reason:'conflict' instead of silently overwriting it — call get_last_study_session again to see the current state, and only retry if you can confirm it's still the same underlying activity, not a different one. Pass a fresh random UUID as mutationId each time you intend a genuinely new save; retrying the exact same mutationId with the exact same content is safe and returns the same success result without double-counting, but reusing a mutationId with different content is rejected — always generate a new one per distinct save. goalChecks/nextGoalId/nextTopicId are validated against the current topic's actual goals — passing a stale or unrelated ID throws rather than saving something inconsistent.
save_topic_understanding
ChatGPTRecord your own read on how solidly the user understands a grammar topic, based on how this conversation's quizzing on it went (not from a single question, but your overall impression after cycling through its goals — see PACE_TOPICS_BRISKLY). This is separate from suplla's own official grammar-level diagnosis; it's a lightweight, MCP-only note to help future sessions pick up where this one left off (e.g. so a later session can prioritize reviewing weakGoalIds instead of re-diagnosing from scratch). Call this at most once per topic per session, at the same wrap-up moment you call update_topic_reading_status.
search_conversation_phrase
ChatGPTSearch suplla's conversation-phrase database (short, situational things people actually say — e.g. 'Can I get a refill?', 'Nice to meet you') by English/Japanese text, or by scene (a lesson's phrase_scene step gives you this directly as scene — pass it verbatim rather than turning it into a text query). This is a different domain from search_phrase (idioms/phrasal verbs like 'give up') — use this one for situational spoken phrases, not fixed multi-word collocations. url is null for entries without suplla's own detail page (aggregated elsewhere on the site) — still fine to explain the phrase yourself in that case, just don't offer a link.
search_phrase
ChatGPTSearch suplla's phrase database (idioms, phrasal verbs, and other fixed collocations — e.g. 'take your time', 'give up', 'in spite of') by English text (partial match) or Japanese meaning. Use this when reading a passage together and a specific multi-word chunk (not a single word — use search_word for that) looks like it could trip the user up, to check whether suplla has it and get its meaning/example. Not every idiomatic phrase is in the database; an empty result doesn't mean the phrase is wrong, just untagged here — explain it yourself from your own knowledge in that case.
search_word
ChatGPTSearch suplla's words by English spelling (full or partial, any inflected form) or Japanese meaning, when you don't already know the exact slug get_word needs. Returns candidate matches with slug/headword/partOfSpeech/translations — pick the right one and call get_word with its slug for full detail (forms, pronunciation, example sentences).
start_level_check
ChatGPTStart suplla's official adaptive grammar level check (/learning/level-check) — the same deterministic, non-AI placement test the site runs, not a casual conversational assessment. It adaptively narrows down the learner's current grammar frontier across junior-high grammar topics using multiple-choice and fill-in-the-blank questions, typically 4-24 questions. This is free to take. Returns the first question plus a sessionId and questionIndex — pass both back into submit_level_check_answer after grading each answer. The session expires after 1 hour of inactivity. Present exactly one question at a time and grade it yourself before calling submit_level_check_answer and keep the correct answer private until the learner has attempted it. For a 'choice' question, treat it like get_question's choice type (options carry is_correct/explanation — keep those private until the learner answers). For a 'fill_blank' question, the learner fills in the blank(s) in prompt; translation is the Japanese meaning, hint may be null. If the learner explicitly says they don't know an answer rather than guessing, that's a real 'skipped' outcome distinct from a wrong guess — pass skipped=true for it in submit_level_check_answer rather than forcing a guess or treating it as incorrect.
submit_level_check_answer
ChatGPTRecord the learner's answer to the question currently pending in a level-check session, then return either the next question or the final summary. Pass the sessionId and questionIndex from the previous start_level_check/submit_level_check_answer response — the server remembers which question was pending, so you only need to report the outcome, not the question itself. Set skipped=true when the learner explicitly said they didn't know rather than guessing (isCorrect is ignored in that case); otherwise pass isCorrect from your own grading. userAnswers is optional and only used to build the final review shown in the summary. When the response comes back with finished: true, the session is over: if the learner has suplla premium, the result was just saved to their official diagnosis history (feeding get_weak_topics); for a free learner it was not saved (summary.saved is false, summary.savedReason is 'premium_required') — mention that once, briefly, without repeating it. Walk the learner through summary naturally rather than dumping it raw: where their current frontier is (reachedLabel), what to study next (nextTopics), and any weak spots worth flagging.
update_lesson_progress
ChatGPTRecord that the user finished a lesson from get_lesson, updating suplla's real lesson progress (user_unit_progress) — the write counterpart to get_lesson. For a 'test'-mode lesson, pass correctCount/totalCount from grading its exercise steps so real accuracy is recorded. For 'check'/'read'-mode lessons, omit both — it's recorded as fully passed, matching how the site's own manual completion button works. Re-completing an already-passed lesson only updates the record if the new accuracy is higher, same as the site. Saving real progress is a premium feature: for a free user, recorded comes back false and nothing is written — the user can still work through the lesson with you, but this completion won't count toward their actual progress. When recorded is false, check reason: premium_required means saving requires premium (mention once); lesson_not_found means the lesson is unavailable, not a subscription issue. Do not report a failed write as saved or repeatedly retry the same unavailable lesson.
update_topic_reading_status
ChatGPTRecord the logged-in user's reading progress on a grammar topic (separate from quiz mastery tracked elsewhere). Call with status='learning' when you start walking the user through a topic's explanation (get_topic), and status='completed' once they've finished a check on it — e.g. after they answer a get_question round for it well enough, or they say they're satisfied and want to move on. This keeps suplla's own reading-progress tracking in sync with what happens in this conversation.