Math practice for the California water operator exams (T1-T3, D1-D3) with worked solutions.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Check the learner's answer to one practice problem and record it, or several problems at once with `answers` (up to 20 pairs of problem id and letter). Returns, per problem, whether it was correct, the correct option, the worked solution and the cited conversion sheet line. The problem id identifies its exam (grade). Side effects: creates the learner's account on first use, saves the attempt to the learner's progress for that grade (mastery per topic and the review schedule; missed problems come back later) and adds a usage record. Overwrites and deletes nothing. Limit: at most 40 answers per minute per account; over it, nothing is recorded and the call can be retried a moment later. Calling it again for the same problem records another attempt, so call it once per answer the user gives. Problems that are part of an open timed set can't be checked until that set is submitted.
The letter the user chose, e.g. "B" (single form)
Several answers at once: [{ questionId, answer }, ...] in the order the user gave them (batch form)
The problem id from practice_questions (single form)
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http waterexammath https://waterexammath.com/mcp
Check the learner's answer to one practice problem and record it, or several problems at once with `answers` (up to 20 pairs of problem id and letter). Returns, per problem, whether it was correct, the correct option, the worked solution and the cited conversion sheet line. The problem id identifies its exam (grade). Side effects: creates the learner's account on first use, saves the attempt to the learner's progress for that grade (mastery per topic and the review schedule; missed problems come back later) and adds a usage record. Overwrites and deletes nothing. Limit: at most 40 answers per minute per account; over it, nothing is recorded and the call can be retried a moment later. Calling it again for the same problem records another attempt, so call it once per answer the user gives. Problems that are part of an open timed set can't be checked until that set is submitted.
| Argument | Type | Description |
|---|---|---|
| answer | string | The letter the user chose, e.g. "B" (single form) |
| answers | array | Several answers at once: [{ questionId, answer }, ...] in the order the user gave them (batch form) |
| questionId | string | The problem id from practice_questions (single form) |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"answer": {
"type": "string",
"maxLength": 20,
"minLength": 1,
"description": "The letter the user chose, e.g. \"B\" (single form)"
},
"answers": {
"type": "array",
"items": {
"type": "object",
"required": [
"questionId",
"answer"
],
"properties": {
"answer": {
"type": "string",
"maxLength": 20,
"minLength": 1
},
"questionId": {
"type": "string",
"maxLength": 100,
"minLength": 1
}
}
},
"maxItems": 20,
"minItems": 1,
"description": "Several answers at once: [{ questionId, answer }, ...] in the order the user gave them (batch form)"
},
"questionId": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "The problem id from practice_questions (single form)"
}
}
}Describe a California drinking water operator exam (grade): what the math covers by topic, the timed practice set format, the size of the problem bank and the official sources (including the CA Exam Conversion Sheet). Without exam and before the user has chosen a grade, lists every available grade with its id. Works signed out. Read-only; changes nothing.
| Argument | Type | Description |
|---|---|---|
| exam | string | Exam (grade) id, e.g. "ca-d2" or "ca-t1". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"exam": {
"type": "string",
"maxLength": 32,
"description": "Exam (grade) id, e.g. \"ca-d2\" or \"ca-t1\". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids."
}
}
}Show the learner's readiness for one exam (grade), overall and per topic (accuracy, number answered, last practiced), how many problems are due for review, the exam date if set, and suggested next steps. Read-only; changes nothing.
| Argument | Type | Description |
|---|---|---|
| exam | string | Exam (grade) id, e.g. "ca-d2" or "ca-t1". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"exam": {
"type": "string",
"maxLength": 32,
"description": "Exam (grade) id, e.g. \"ca-d2\" or \"ca-t1\". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids."
}
}
}Build a day-by-day math study plan for one exam (grade) up to the exam date from the learner's current mastery: daily practice weighted to weak topics, review of missed problems, timed sets and rest days. Uses the exam date saved in WaterExamMath for that grade (save_study_settings saves one); pass examDate (YYYY-MM-DD) to plan for a different date. The date passed here is not saved. Read-only; changes nothing.
| Argument | Type | Description |
|---|---|---|
| exam | string | Exam (grade) id, e.g. "ca-d2" or "ca-t1". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids. |
| examDate | string | Exam date as YYYY-MM-DD, if the user gives one |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"exam": {
"type": "string",
"maxLength": 32,
"description": "Exam (grade) id, e.g. \"ca-d2\" or \"ca-t1\". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids."
},
"examDate": {
"type": "string",
"maxLength": 10,
"description": "Exam date as YYYY-MM-DD, if the user gives one"
}
}
}Get a set of math practice problems WITHOUT their answers, chosen for this learner in one exam (grade): problems they missed come back first, and weak, heavily weighted topics get more problems. Returns each problem's id, topic, text and lettered options (1 to 20 per call, default 5). Optionally limit to one topic by its id from get_exam_overview. Read-only: nothing is recorded until check_answer. Each call may return a different set.
| Argument | Type | Description |
|---|---|---|
| exam | string | Exam (grade) id, e.g. "ca-d2" or "ca-t1". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids. |
| count | integer | How many problems, 1-20 (default 5) |
| domain | string | Topic id to focus on, e.g. from get_exam_overview |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"exam": {
"type": "string",
"maxLength": 32,
"description": "Exam (grade) id, e.g. \"ca-d2\" or \"ca-t1\". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids."
},
"count": {
"type": "integer",
"maximum": 20,
"minimum": 1,
"description": "How many problems, 1-20 (default 5)"
},
"domain": {
"type": "string",
"maxLength": 64,
"description": "Topic id to focus on, e.g. from get_exam_overview"
}
}
}Permanently erase the learner's progress for one exam (grade): every recorded answer, mastery per topic, the review schedule and all timed set results for that grade. Other grades are not touched. This cannot be undone. Requires confirm: true, meaning the user explicitly asked to reset and confirmed which grade. The exam date and account stay. Each call also adds a usage record; repeating it erases nothing more.
| Argument | Type | Description |
|---|---|---|
| exam | string | Exam (grade) id, e.g. "ca-d2" or "ca-t1". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids. |
| confirm* | boolean | Must be true: the user explicitly confirmed erasing their progress |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"confirm"
],
"properties": {
"exam": {
"type": "string",
"maxLength": 32,
"description": "Exam (grade) id, e.g. \"ca-d2\" or \"ca-t1\". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids."
},
"confirm": {
"type": "boolean",
"description": "Must be true: the user explicitly confirmed erasing their progress"
}
}
}Save some or all answers of an OPEN timed set from start_mock_exam as a draft, by problem number (1-based) and letter. Only the listed problems change; the others keep their saved answer. Any answer can be changed again until the set is submitted (send a new letter, or an empty string to leave that problem blank again), so nothing is lost by saving. Nothing is scored and nothing is recorded into the learner's progress until submit_mock_exam. Returns how many problems are answered and which numbers are still blank. Side effects: updates the unsubmitted draft on that one open timed set and nothing else. Safe to retry: the same answers give the same draft. Only submit_mock_exam makes the answers final.
| Argument | Type | Description |
|---|---|---|
| answers* | array | Problem numbers with the letter chosen, e.g. [{ number: 1, answer: "B" }, { number: 2, answer: "" }] |
| mockExamId* | string | The id returned by start_mock_exam |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"mockExamId",
"answers"
],
"properties": {
"answers": {
"type": "array",
"items": {
"type": "object",
"required": [
"number",
"answer"
],
"properties": {
"answer": {
"type": "string",
"maxLength": 20
},
"number": {
"type": "integer",
"maximum": 500,
"minimum": 1
}
}
},
"maxItems": 500,
"minItems": 1,
"description": "Problem numbers with the letter chosen, e.g. [{ number: 1, answer: \"B\" }, { number: 2, answer: \"\" }]"
},
"mockExamId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The id returned by start_mock_exam"
}
}
}Save the learner's grade and, optionally, their exam date and daily problem target for that grade, so later calls default to that grade and get_study_plan uses that date. Side effects: creates the learner's account on first use and REPLACES the saved grade (and the saved exam date or daily target for that grade, when given) with these values. Practice history is not touched. Safe to retry: the same values give the same result.
| Argument | Type | Description |
|---|---|---|
| exam* | string | Exam (grade) id to save, e.g. "ca-d2"; get_exam_overview lists the ids |
| examDate | string | Exam date as YYYY-MM-DD, if the user gives one |
| timeZone | string | The user's IANA time zone, e.g. "America/Los_Angeles", if known; sets which day counts as today in the plan |
| dailyQuestions | integer | Problems per day for the study plan, if the user gives one |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"exam"
],
"properties": {
"exam": {
"type": "string",
"maxLength": 32,
"minLength": 1,
"description": "Exam (grade) id to save, e.g. \"ca-d2\"; get_exam_overview lists the ids"
},
"examDate": {
"type": "string",
"maxLength": 10,
"description": "Exam date as YYYY-MM-DD, if the user gives one"
},
"timeZone": {
"type": "string",
"maxLength": 64,
"description": "The user's IANA time zone, e.g. \"America/Los_Angeles\", if known; sets which day counts as today in the plan"
},
"dailyQuestions": {
"type": "integer",
"maximum": 100,
"minimum": 1,
"description": "Problems per day for the study plan, if the user gives one"
}
}
}Start a timed math set for one exam (grade): problems spread over its math topics, with a time limit. Optional `count` (10, 25 or 50 problems, default 25) and `minutes` (15, 30, 60, 90 or 120, default 60). It covers the math portion only. Returns the set id, the deadline and every problem WITHOUT answers; submit_mock_exam scores all answers at once. Side effects: creates the learner's account on first use, a timed set record and a usage record. If a set is already open for that grade (even past its deadline) that set is returned instead and nothing new is created; after it is submitted, calling again starts a new one. Nothing is closed or cancelled by this call. A set left open more than 7 days past its deadline is closed without a score by a daily cleanup. Timed sets are not limited per month; at most 12 new timed sets can be started per hour per account (over it, nothing is created and the call can be retried later).
| Argument | Type | Description |
|---|---|---|
| exam | string | Exam (grade) id, e.g. "ca-d2" or "ca-t1". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids. |
| count | number | Number of problems: 10, 25 or 50 (default 25) |
| minutes | number | Time limit in minutes: 15, 30, 60, 90 or 120 (default 60) |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"exam": {
"type": "string",
"maxLength": 32,
"description": "Exam (grade) id, e.g. \"ca-d2\" or \"ca-t1\". Leave out to use the grade the user saved (save_study_settings); get_exam_overview lists the ids."
},
"count": {
"enum": [
10,
25,
50
],
"type": "number",
"description": "Number of problems: 10, 25 or 50 (default 25)"
},
"minutes": {
"enum": [
15,
30,
60,
90,
120
],
"type": "number",
"description": "Time limit in minutes: 15, 30, 60, 90 or 120 (default 60)"
}
}
}Submit a timed set from start_mock_exam and get the score report: total, whether it reached the target, score per topic, and the missed problems with worked solutions and sources. Without `answers`, the draft saved with save_mock_answers is submitted. With `answers`, they are letters in problem order, one per problem; use an empty string for a skipped problem. Skipped problems count as wrong. Submitting is final (marked destructive for that reason): the set closes and its answers can't be changed afterwards, so ask the learner once before calling it. A set submitted after its deadline is still scored and marked late. Side effects: closes the timed set, records the answers into the learner's progress for that grade (a crew supervisor the learner joined sees them in practice stats) and adds a usage record. Safe to retry: submitting the same set again returns the stored result and records nothing more.
| Argument | Type | Description |
|---|---|---|
| answers | array | One letter per problem in order, e.g. ["A", "C", ""]; leave out to submit the saved draft |
| mockExamId* | string | The id returned by start_mock_exam |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"mockExamId"
],
"properties": {
"answers": {
"type": "array",
"items": {
"type": "string",
"maxLength": 20
},
"maxItems": 500,
"description": "One letter per problem in order, e.g. [\"A\", \"C\", \"\"]; leave out to submit the saved draft"
},
"mockExamId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The id returned by start_mock_exam"
}
}
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 9, 2026.