Is a weighted grade calculator for teachers and tutors who compute class grades each week.
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.
Use this when a teacher or tutor wants a weighted grade calculator for a whole class; list ID and info columns (student number, StudentID, email, SIS, section) in ignore_columns so they stay out of the grades. Examples: final grades from a gradebook, 'calculate my students' grades with Homework 20%, Quizzes 30%, Tests 50%', a gradebook template filled in, class average, or who is missing work. Takes a roster of scores (pasted table, list, or a Google Classroom / Canvas CSV or XLSX export as file) plus optional category weights, points possible, drop lowest per category, blank handling, extra credit and letter scale. Returns each student's final percent and letter (fraction math, rounded only for display), category scores, weights renormalized when a category has no graded work, class mean/median/distribution, missing-work list, and Excel + CSV downloads. Does not store data, connect to a school system, or make progress report PDFs (use generate_progress_reports).
A gradebook export as CSV or XLSX, e.g. the Google Classroom grades CSV or the Canvas gradebook export. One row per student, one column per assignment.
Grading period, e.g. Fall 2026 Quarter 1.
The scores, one row per student: a pasted table (CSV, tab-separated or a markdown table) with a header row of assignment names, e.g. "Student, HW1, HW2, Quiz 1, Test 1\nAna Diaz, 18, 20, 9, 45\nBen Ito, 15, EX, 7, M". Also accepts a list of rows or [{"name":"Ana Diaz","scores":{"HW1":18,"Quiz 1":9}}]. Send this or file.
How to treat empty cells: not_graded (default, left out) or zero (count as 0). EX means excused (left out); M or missing counts as 0.
Same as roster (either name works), e.g. [{"name":"Ana Diaz","scores":{"HW1":18}}].
The header of the student ID / student number column, if any, e.g. "StudentID". It is ignored (same as ignore_columns).
Category weights, e.g. "Homework 20%, Quizzes 30%, Tests 50%" or [{"name":"Quizzes","weight":30,"drop_lowest":1}]. Assignments are matched to categories by name (HW 3 -> Homework, Quiz 2 -> Quizzes, Unit Test -> Tests). Leave out for a total-points grade.
Class name for the files, e.g. Algebra 1, Period 3.
true for +/- letters (A+ 97, A 93, A- 90, ...). Default false.
Optional details per assignment when names do not show the category or the points: [{"name":"Unit 1","category":"Tests","points_possible":50}], or lines like "Unit 1, Tests, 50". Mark bonus work with "extra_credit": true.
Drop each student's lowest scores per category, e.g. {"Quizzes": 1} or "Quizzes 1, Homework 2". A plain number applies to every category.
Letter cutoffs. Default A 90, B 80, C 70, D 60, F below 60. Use "plus_minus" for A+ 97 / A 93 / A- 90 ... D- 60, or a custom list like "A 93, B 85, C 75, D 65".
Teacher or tutor name for the reports, e.g. Ms. Rivera.
Columns that are not scores and must not be graded or copied, by header name: student IDs, student numbers, SIS/login/email, section, notes. Example: ["Student Number", "Email"] or "StudentID, Nr albumu". Always name ID and info columns here.
Points possible when the table does not say: one number for every assignment (e.g. 100), a list in column order (e.g. "20, 20, 10, 50"), or {"Quiz 1": 10}. A 'Points possible' row in the table or headers like "Quiz 1 (10)" also work. Default 100.
How a category score is built: points (default, total points earned / possible in the category) or average (each assignment counts equally).
true to round the final percent to a whole number before picking the letter (89.5 -> 90 -> A). Default false: 89.5 is a B.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http gradebook https://gradebook.zovo.one/mcp
Use this when a teacher or tutor wants a weighted grade calculator for a whole class; list ID and info columns (student number, StudentID, email, SIS, section) in ignore_columns so they stay out of the grades. Examples: final grades from a gradebook, 'calculate my students' grades with Homework 20%, Quizzes 30%, Tests 50%', a gradebook template filled in, class average, or who is missing work. Takes a roster of scores (pasted table, list, or a Google Classroom / Canvas CSV or XLSX export as file) plus optional category weights, points possible, drop lowest per category, blank handling, extra credit and letter scale. Returns each student's final percent and letter (fraction math, rounded only for display), category scores, weights renormalized when a category has no graded work, class mean/median/distribution, missing-work list, and Excel + CSV downloads. Does not store data, connect to a school system, or make progress report PDFs (use generate_progress_reports).
| Argument | Type | Description |
|---|---|---|
| file | object | A gradebook export as CSV or XLSX, e.g. the Google Classroom grades CSV or the Canvas gradebook export. One row per student, one column per assignment. |
| term | string | Grading period, e.g. Fall 2026 Quarter 1. |
| roster | any | The scores, one row per student: a pasted table (CSV, tab-separated or a markdown table) with a header row of assignment names, e.g. "Student, HW1, HW2, Quiz 1, Test 1\nAna Diaz, 18, 20, 9, 45\nBen Ito, 15, EX, 7, M". Also accepts a list of rows or [{"name":"Ana Diaz","scores":{"HW1":18,"Quiz 1":9}}]. Send this or file. |
| blank_as | string | How to treat empty cells: not_graded (default, left out) or zero (count as 0). EX means excused (left out); M or missing counts as 0. |
| students | any | Same as roster (either name works), e.g. [{"name":"Ana Diaz","scores":{"HW1":18}}]. |
| id_column | string | The header of the student ID / student number column, if any, e.g. "StudentID". It is ignored (same as ignore_columns). |
| categories | any | Category weights, e.g. "Homework 20%, Quizzes 30%, Tests 50%" or [{"name":"Quizzes","weight":30,"drop_lowest":1}]. Assignments are matched to categories by name (HW 3 -> Homework, Quiz 2 -> Quizzes, Unit Test -> Tests). Leave out for a total-points grade. |
| class_name | string | Class name for the files, e.g. Algebra 1, Period 3. |
| plus_minus | any | true for +/- letters (A+ 97, A 93, A- 90, ...). Default false. |
| assignments | any | Optional details per assignment when names do not show the category or the points: [{"name":"Unit 1","category":"Tests","points_possible":50}], or lines like "Unit 1, Tests, 50". Mark bonus work with "extra_credit": true. |
| drop_lowest | any | Drop each student's lowest scores per category, e.g. {"Quizzes": 1} or "Quizzes 1, Homework 2". A plain number applies to every category. |
| letter_scale | any | Letter cutoffs. Default A 90, B 80, C 70, D 60, F below 60. Use "plus_minus" for A+ 97 / A 93 / A- 90 ... D- 60, or a custom list like "A 93, B 85, C 75, D 65". |
| teacher_name | string | Teacher or tutor name for the reports, e.g. Ms. Rivera. |
| ignore_columns | any | Columns that are not scores and must not be graded or copied, by header name: student IDs, student numbers, SIS/login/email, section, notes. Example: ["Student Number", "Email"] or "StudentID, Nr albumu". Always name ID and info columns here. |
| points_possible | any | Points possible when the table does not say: one number for every assignment (e.g. 100), a list in column order (e.g. "20, 20, 10, 50"), or {"Quiz 1": 10}. A 'Points possible' row in the table or headers like "Quiz 1 (10)" also work. Default 100. |
| category_scoring | string | How a category score is built: points (default, total points earned / possible in the category) or average (each assignment counts equally). |
| round_for_letter | any | true to round the final percent to a whole number before picking the letter (89.5 -> 90 -> A). Default false: 89.5 is a B. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"file": {
"type": "object",
"required": [
"download_url",
"file_id"
],
"properties": {
"file_id": {
"type": "string",
"description": "ChatGPT file id, e.g. file_abc123."
},
"file_name": {
"type": "string",
"description": "Original file name if known, e.g. statement.pdf."
},
"mime_type": {
"type": "string",
"description": "Media type if known, e.g. application/pdf."
},
"download_url": {
"type": "string",
"description": "Temporary download link for the file, supplied by ChatGPT."
}
},
"description": "A gradebook export as CSV or XLSX, e.g. the Google Classroom grades CSV or the Canvas gradebook export. One row per student, one column per assignment."
},
"term": {
"type": "string",
"maxLength": 60,
"description": "Grading period, e.g. Fall 2026 Quarter 1."
},
"roster": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "The scores, one row per student: a pasted table (CSV, tab-separated or a markdown table) with a header row of assignment names, e.g. \"Student, HW1, HW2, Quiz 1, Test 1\\nAna Diaz, 18, 20, 9, 45\\nBen Ito, 15, EX, 7, M\". Also accepts a list of rows or [{\"name\":\"Ana Diaz\",\"scores\":{\"HW1\":18,\"Quiz 1\":9}}]. Send this or file."
},
"blank_as": {
"type": "string",
"maxLength": 30,
"description": "How to treat empty cells: not_graded (default, left out) or zero (count as 0). EX means excused (left out); M or missing counts as 0."
},
"students": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Same as roster (either name works), e.g. [{\"name\":\"Ana Diaz\",\"scores\":{\"HW1\":18}}]."
},
"id_column": {
"type": "string",
"maxLength": 120,
"description": "The header of the student ID / student number column, if any, e.g. \"StudentID\". It is ignored (same as ignore_columns)."
},
"categories": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Category weights, e.g. \"Homework 20%, Quizzes 30%, Tests 50%\" or [{\"name\":\"Quizzes\",\"weight\":30,\"drop_lowest\":1}]. Assignments are matched to categories by name (HW 3 -> Homework, Quiz 2 -> Quizzes, Unit Test -> Tests). Leave out for a total-points grade."
},
"class_name": {
"type": "string",
"maxLength": 120,
"description": "Class name for the files, e.g. Algebra 1, Period 3."
},
"plus_minus": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 10
}
],
"description": "true for +/- letters (A+ 97, A 93, A- 90, ...). Default false."
},
"assignments": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Optional details per assignment when names do not show the category or the points: [{\"name\":\"Unit 1\",\"category\":\"Tests\",\"points_possible\":50}], or lines like \"Unit 1, Tests, 50\". Mark bonus work with \"extra_credit\": true."
},
"drop_lowest": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 400
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
{
"type": "array",
"items": {},
"maxItems": 30
}
],
"description": "Drop each student's lowest scores per category, e.g. {\"Quizzes\": 1} or \"Quizzes 1, Homework 2\". A plain number applies to every category."
},
"letter_scale": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Letter cutoffs. Default A 90, B 80, C 70, D 60, F below 60. Use \"plus_minus\" for A+ 97 / A 93 / A- 90 ... D- 60, or a custom list like \"A 93, B 85, C 75, D 65\"."
},
"teacher_name": {
"type": "string",
"maxLength": 80,
"description": "Teacher or tutor name for the reports, e.g. Ms. Rivera."
},
"ignore_columns": {
"anyOf": [
{
"type": "string",
"maxLength": 2000
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 120
},
"maxItems": 50
}
],
"description": "Columns that are not scores and must not be graded or copied, by header name: student IDs, student numbers, SIS/login/email, section, notes. Example: [\"Student Number\", \"Email\"] or \"StudentID, Nr albumu\". Always name ID and info columns here."
},
"points_possible": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 4000
},
{
"type": "array",
"items": {},
"maxItems": 300
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Points possible when the table does not say: one number for every assignment (e.g. 100), a list in column order (e.g. \"20, 20, 10, 50\"), or {\"Quiz 1\": 10}. A 'Points possible' row in the table or headers like \"Quiz 1 (10)\" also work. Default 100."
},
"category_scoring": {
"type": "string",
"maxLength": 20,
"description": "How a category score is built: points (default, total points earned / possible in the category) or average (each assignment counts equally)."
},
"round_for_letter": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 10
}
],
"description": "true to round the final percent to a whole number before picking the letter (89.5 -> 90 -> A). Default false: 89.5 is a B."
}
}
}Use this when someone asks what they need on the final: 'what do I need on my final to get a B', final grade calculator, score needed on the final exam to pass, or a teacher asking what each student needs on the final for a C. Takes the current grade percent (or a list of students with current grades), how much the final is worth, and a target percent or letter (default all letters on the scale). Returns the score needed on the final for each target (and the points needed when final points are given), whether it is reachable, and what-if course grades. Assumes the final is a separate weight on top of the current grade; does not model a final inside a weighted category.
| Argument | Type | Description |
|---|---|---|
| target | any | The course grade wanted: a percent (90), a letter ("B") or several ("A, B, C"). Default: every letter on the scale. |
| students | any | For a teacher: several students' current grades, e.g. "Ana Diaz 84.5, Ben Ito 71" or [{"name":"Ana Diaz","current_grade":84.5}]. Send this or current_grade. |
| plus_minus | any | true for +/- letters. Default false. |
| final_weight* | any | How much the final counts toward the course grade, as a percent, e.g. 20 or "20%" (0.2 is read as 20%). |
| letter_scale | any | Letter cutoffs for letter targets. Default A 90, B 80, C 70, D 60; "plus_minus" or a custom list like "A 93, B 85, C 75, D 65". |
Use this when the user wants a progress report template filled in for students; list ID and info columns (student number, StudentID, email, SIS, section) in ignore_columns so they stay out of the grades. Examples: printable progress reports, grade reports for parents, 'make a progress report for each student'. Takes the same roster and grading settings as calculate_class_grades plus optional teacher comments per student, class name, teacher, term, report date and a subset of students. Returns one PDF with one page per student (current grade and letter, category scores, each assignment with excused/missing/dropped marks, missing work list, comment) and the Excel gradebook. Does not email or post reports, and does not store data.
| Argument | Type | Description |
|---|---|---|
| file | object | A gradebook export as CSV or XLSX, e.g. the Google Classroom grades CSV or the Canvas gradebook export. One row per student, one column per assignment. |
| term | string | Grading period, e.g. Fall 2026 Quarter 1. |
| paper | string | letter (default) or a4. |
| roster | any | The scores, one row per student: a pasted table (CSV, tab-separated or a markdown table) with a header row of assignment names, e.g. "Student, HW1, HW2, Quiz 1, Test 1\nAna Diaz, 18, 20, 9, 45\nBen Ito, 15, EX, 7, M". Also accepts a list of rows or [{"name":"Ana Diaz","scores":{"HW1":18,"Quiz 1":9}}]. Send this or file. |
| blank_as | string | How to treat empty cells: not_graded (default, left out) or zero (count as 0). EX means excused (left out); M or missing counts as 0. |
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 8, 2026.
| current_grade |
| any |
| The grade before the final, as a percent, e.g. 84.5 or "84.5%". |
| final_points_possible | any | Points on the final exam, e.g. 120, to also show the points needed. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"final_weight"
],
"properties": {
"target": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 200
},
{
"type": "array",
"items": {
"type": [
"number",
"string"
]
},
"maxItems": 20
}
],
"description": "The course grade wanted: a percent (90), a letter (\"B\") or several (\"A, B, C\"). Default: every letter on the scale."
},
"students": {
"anyOf": [
{
"type": "string",
"maxLength": 20000
},
{
"type": "array",
"items": {},
"maxItems": 500
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "For a teacher: several students' current grades, e.g. \"Ana Diaz 84.5, Ben Ito 71\" or [{\"name\":\"Ana Diaz\",\"current_grade\":84.5}]. Send this or current_grade."
},
"plus_minus": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 10
}
],
"description": "true for +/- letters. Default false."
},
"final_weight": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 40
}
],
"description": "How much the final counts toward the course grade, as a percent, e.g. 20 or \"20%\" (0.2 is read as 20%)."
},
"letter_scale": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Letter cutoffs for letter targets. Default A 90, B 80, C 70, D 60; \"plus_minus\" or a custom list like \"A 93, B 85, C 75, D 65\"."
},
"current_grade": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 40
}
],
"description": "The grade before the final, as a percent, e.g. 84.5 or \"84.5%\"."
},
"final_points_possible": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 20
}
],
"description": "Points on the final exam, e.g. 120, to also show the points needed."
}
}
}| comments | any | Optional teacher comment per student, e.g. {"Ana Diaz":"Strong quiz scores; turn in HW 3."} or lines "Ana Diaz: Strong quiz scores". |
| students | any | Same as roster (either name works), e.g. [{"name":"Ana Diaz","scores":{"HW1":18}}]. |
| id_column | string | The header of the student ID / student number column, if any, e.g. "StudentID". It is ignored (same as ignore_columns). |
| categories | any | Category weights, e.g. "Homework 20%, Quizzes 30%, Tests 50%" or [{"name":"Quizzes","weight":30,"drop_lowest":1}]. Assignments are matched to categories by name (HW 3 -> Homework, Quiz 2 -> Quizzes, Unit Test -> Tests). Leave out for a total-points grade. |
| class_name | string | Class name for the files, e.g. Algebra 1, Period 3. |
| plus_minus | any | true for +/- letters (A+ 97, A 93, A- 90, ...). Default false. |
| assignments | any | Optional details per assignment when names do not show the category or the points: [{"name":"Unit 1","category":"Tests","points_possible":50}], or lines like "Unit 1, Tests, 50". Mark bonus work with "extra_credit": true. |
| drop_lowest | any | Drop each student's lowest scores per category, e.g. {"Quizzes": 1} or "Quizzes 1, Homework 2". A plain number applies to every category. |
| report_date | string | Date printed on the reports, e.g. October 26, 2026. Default: today (US Eastern). |
| letter_scale | any | Letter cutoffs. Default A 90, B 80, C 70, D 60, F below 60. Use "plus_minus" for A+ 97 / A 93 / A- 90 ... D- 60, or a custom list like "A 93, B 85, C 75, D 65". |
| teacher_name | string | Teacher or tutor name for the reports, e.g. Ms. Rivera. |
| only_students | any | Optional subset of student names to print, e.g. "Ana Diaz, Ben Ito". Default: every student. |
| ignore_columns | any | Columns that are not scores and must not be graded or copied, by header name: student IDs, student numbers, SIS/login/email, section, notes. Example: ["Student Number", "Email"] or "StudentID, Nr albumu". Always name ID and info columns here. |
| points_possible | any | Points possible when the table does not say: one number for every assignment (e.g. 100), a list in column order (e.g. "20, 20, 10, 50"), or {"Quiz 1": 10}. A 'Points possible' row in the table or headers like "Quiz 1 (10)" also work. Default 100. |
| category_scoring | string | How a category score is built: points (default, total points earned / possible in the category) or average (each assignment counts equally). |
| round_for_letter | any | true to round the final percent to a whole number before picking the letter (89.5 -> 90 -> A). Default false: 89.5 is a B. |
| show_class_average | any | Print the class average on each report. Default true. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"file": {
"type": "object",
"required": [
"download_url",
"file_id"
],
"properties": {
"file_id": {
"type": "string",
"description": "ChatGPT file id, e.g. file_abc123."
},
"file_name": {
"type": "string",
"description": "Original file name if known, e.g. statement.pdf."
},
"mime_type": {
"type": "string",
"description": "Media type if known, e.g. application/pdf."
},
"download_url": {
"type": "string",
"description": "Temporary download link for the file, supplied by ChatGPT."
}
},
"description": "A gradebook export as CSV or XLSX, e.g. the Google Classroom grades CSV or the Canvas gradebook export. One row per student, one column per assignment."
},
"term": {
"type": "string",
"maxLength": 60,
"description": "Grading period, e.g. Fall 2026 Quarter 1."
},
"paper": {
"type": "string",
"maxLength": 20,
"description": "letter (default) or a4."
},
"roster": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "The scores, one row per student: a pasted table (CSV, tab-separated or a markdown table) with a header row of assignment names, e.g. \"Student, HW1, HW2, Quiz 1, Test 1\\nAna Diaz, 18, 20, 9, 45\\nBen Ito, 15, EX, 7, M\". Also accepts a list of rows or [{\"name\":\"Ana Diaz\",\"scores\":{\"HW1\":18,\"Quiz 1\":9}}]. Send this or file."
},
"blank_as": {
"type": "string",
"maxLength": 30,
"description": "How to treat empty cells: not_graded (default, left out) or zero (count as 0). EX means excused (left out); M or missing counts as 0."
},
"comments": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Optional teacher comment per student, e.g. {\"Ana Diaz\":\"Strong quiz scores; turn in HW 3.\"} or lines \"Ana Diaz: Strong quiz scores\"."
},
"students": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Same as roster (either name works), e.g. [{\"name\":\"Ana Diaz\",\"scores\":{\"HW1\":18}}]."
},
"id_column": {
"type": "string",
"maxLength": 120,
"description": "The header of the student ID / student number column, if any, e.g. \"StudentID\". It is ignored (same as ignore_columns)."
},
"categories": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Category weights, e.g. \"Homework 20%, Quizzes 30%, Tests 50%\" or [{\"name\":\"Quizzes\",\"weight\":30,\"drop_lowest\":1}]. Assignments are matched to categories by name (HW 3 -> Homework, Quiz 2 -> Quizzes, Unit Test -> Tests). Leave out for a total-points grade."
},
"class_name": {
"type": "string",
"maxLength": 120,
"description": "Class name for the files, e.g. Algebra 1, Period 3."
},
"plus_minus": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 10
}
],
"description": "true for +/- letters (A+ 97, A 93, A- 90, ...). Default false."
},
"assignments": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Optional details per assignment when names do not show the category or the points: [{\"name\":\"Unit 1\",\"category\":\"Tests\",\"points_possible\":50}], or lines like \"Unit 1, Tests, 50\". Mark bonus work with \"extra_credit\": true."
},
"drop_lowest": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 400
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
{
"type": "array",
"items": {},
"maxItems": 30
}
],
"description": "Drop each student's lowest scores per category, e.g. {\"Quizzes\": 1} or \"Quizzes 1, Homework 2\". A plain number applies to every category."
},
"report_date": {
"type": "string",
"maxLength": 40,
"description": "Date printed on the reports, e.g. October 26, 2026. Default: today (US Eastern)."
},
"letter_scale": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Letter cutoffs. Default A 90, B 80, C 70, D 60, F below 60. Use \"plus_minus\" for A+ 97 / A 93 / A- 90 ... D- 60, or a custom list like \"A 93, B 85, C 75, D 65\"."
},
"teacher_name": {
"type": "string",
"maxLength": 80,
"description": "Teacher or tutor name for the reports, e.g. Ms. Rivera."
},
"only_students": {
"anyOf": [
{
"type": "string",
"maxLength": 300000
},
{
"type": "array",
"items": {},
"maxItems": 3000
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Optional subset of student names to print, e.g. \"Ana Diaz, Ben Ito\". Default: every student."
},
"ignore_columns": {
"anyOf": [
{
"type": "string",
"maxLength": 2000
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 120
},
"maxItems": 50
}
],
"description": "Columns that are not scores and must not be graded or copied, by header name: student IDs, student numbers, SIS/login/email, section, notes. Example: [\"Student Number\", \"Email\"] or \"StudentID, Nr albumu\". Always name ID and info columns here."
},
"points_possible": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 4000
},
{
"type": "array",
"items": {},
"maxItems": 300
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "Points possible when the table does not say: one number for every assignment (e.g. 100), a list in column order (e.g. \"20, 20, 10, 50\"), or {\"Quiz 1\": 10}. A 'Points possible' row in the table or headers like \"Quiz 1 (10)\" also work. Default 100."
},
"category_scoring": {
"type": "string",
"maxLength": 20,
"description": "How a category score is built: points (default, total points earned / possible in the category) or average (each assignment counts equally)."
},
"round_for_letter": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 10
}
],
"description": "true to round the final percent to a whole number before picking the letter (89.5 -> 90 -> A). Default false: 89.5 is a B."
},
"show_class_average": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 10
}
],
"description": "Print the class average on each report. Default true."
}
}
}