ClassMarker MCP by usefulapi
by usefulapi.io · remote · no sign-in to list tools · v1.3.3 · published by io.usefulapi
Read ClassMarker groups, links, exams and recent results; manage question bank and access codes.
15 tools: 3 can delete or cancel things, 8 change things and 4 only read.
Scanned Oct 21, 2026
- Deletes or cancels3Claude Code: deny: see these tools
- Can't be undone0Claude Code: ask
- Changes things8Claude Code: ask: see these tools
- Only reads4Claude Code: allow: see these tools
2 checks matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.
claude mcp add --transport http classmarker https://classmarker.usefulapi.io/mcpFindings
Matches of fixed checks, with the text they matched.
The server marks "classmarker_recent_link_results" read-only (readOnlyHint: true), and its own name, description or input give the class "write".
What this check looks forMatched text
annotations: {"readOnlyHint":true}; The name "classmarker_recent_link_results" says "link": a word for a change.
The server marks "classmarker_recent_link_exam_results" read-only (readOnlyHint: true), and its own name, description or input give the class "write".
What this check looks forMatched text
annotations: {"readOnlyHint":true}; The name "classmarker_recent_link_exam_results" says "link": a word for a change.
Tools
Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.
15 tools
Deletes or cancels 3Claude Code: deny
classmarker_update_categoryWRITE: rename a category and/or move it to another parent (overwrites both fields: send the name and parent_category_id you want it to have).No findings
Why it is in this group
- The name "classmarker_update_category" says "update": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it WRITE: rename a category and/or move it to another parent (overwrites both fields: send the name and parent_category_id you want it to have). Counts as one of ClassMarker's 30 requests per hour per API key. API: PUT /v1/categories/category/{category_id}.json.
Annotations the server declares
- title: Update a category
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: true
classmarker_update_parent_categoryWRITE: rename an existing parent category (overwrites its name).No findings
Why it is in this group
- The name "classmarker_update_parent_category" says "update": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it WRITE: rename an existing parent category (overwrites its name). Counts as one of ClassMarker's 30 requests per hour per API key. API: PUT /v1/categories/parent_category/{parent_category_id}.json.
Annotations the server declares
- title: Rename a parent category
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: true
classmarker_update_questionWRITE (overwrites): replace an existing question-bank question.No findings
Why it is in this group
- The name "classmarker_update_question" says "update": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it WRITE (overwrites): replace an existing question-bank question. Send the COMPLETE question (type, text, options, correct options, points, feedback), not only the changed fields; read it first with classmarker_get_question. Only multiplechoice, multipleresponse, truefalse and essay questions can be updated. Counts as one of ClassMarker's 30 requests per hour per API key. API: PUT /v1/questions/{question_id}.json.
Annotations the server declares
- title: Update a question
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: true
Changes things 8Claude Code: ask
classmarker_add_access_codesWRITE: add access codes (1-100 per call, up to 255 characters each; a list holds at most 20,000) to a link's access-code list, so those people can start the exam.No findings
Why it is in this group
- The name "classmarker_add_access_codes" says "add": a word for a change.
Description, as the server wrote it WRITE: add access codes (1-100 per call, up to 255 characters each; a list holds at most 20,000) to a link's access-code list, so those people can start the exam. The access_list_id comes from classmarker_list_groups_links_exams (links[].access_list_id). Only adds; removing codes is not offered. Does not count against the 30 requests per hour limit. API: POST /v1/accesslists/{access_list_id}.json.
Annotations the server declares
- title: Add access codes to a list
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
classmarker_create_categoryWRITE: create a question category under a parent category.No findings
Why it is in this group
- The name "classmarker_create_category" says "create": a word for a change.
Description, as the server wrote it WRITE: create a question category under a parent category. Returns its category_id. Counts as one of ClassMarker's 30 requests per hour per API key. API: POST /v1/categories/category.json.
Annotations the server declares
- title: Create a category
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
classmarker_create_parent_categoryWRITE: create a new top-level question category.No findings
Why it is in this group
- The name "classmarker_create_parent_category" says "create": a word for a change.
Description, as the server wrote it WRITE: create a new top-level question category. Returns its parent_category_id. Counts as one of ClassMarker's 30 requests per hour per API key. API: POST /v1/categories/parent_category.json.
Annotations the server declares
- title: Create a parent category
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
classmarker_create_questionWRITE: add a new question to the question bank.No findings
Why it is in this group
- The name "classmarker_create_question" says "create": a word for a change.
Description, as the server wrote it WRITE: add a new question to the question bank. Only multiplechoice, multipleresponse, truefalse and essay can be created. Returns the new question_id. For truefalse, give only correct_options ["A"] (True) or ["B"] (False). Counts as one of ClassMarker's 30 requests per hour per API key. API: POST /v1/questions.json.
Annotations the server declares
- title: Create a question
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
classmarker_recent_group_exam_resultsRecent finished results for ONE exam in ONE group (ids from classmarker_list_groups_links_exams), oldest first, PAGED by finish time.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Description, as the server wrote it Recent finished results for ONE exam in ONE group (ids from classmarker_list_groups_links_exams), oldest first, PAGED by finish time. Contains personal data: use small pages. Counts as one of ClassMarker's 30 requests per hour per API key. API: GET /v1/groups/{group_id}/tests/{test_id}/recent_results.json.
Annotations the server declares
- title: Recent results for one group exam
- readOnlyHint: true
classmarker_recent_group_resultsRecent finished test results taken in the key's groups (all groups, all exams), oldest first, PAGED by finish time: test-taker name, email, score, percentage, pass/fail, timing, ce…No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Description, as the server wrote it Recent finished test results taken in the key's groups (all groups, all exams), oldest first, PAGED by finish time: test-taker name, email, score, percentage, pass/fail, timing, certificate. Contains personal data: use small pages. Max look-back 3 months. Counts as one of ClassMarker's 30 requests per hour per API key. API: GET /v1/groups/recent_results.json.
Annotations the server declares
- title: Recent results across all groups
- readOnlyHint: true
classmarker_recent_link_exam_resultsRecent finished results for the exam of ONE link (ids from classmarker_list_groups_links_exams), oldest first, PAGED by finish time.1 finding
Why it is in this group
- The name "classmarker_recent_link_exam_results" says "link": a word for a change.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Findings
- Warn
The server marks "classmarker_recent_link_exam_results" read-only (readOnlyHint: true), and its own name, description or input give the class "write".
What this check looks forMatched text
annotations: {"readOnlyHint":true}; The name "classmarker_recent_link_exam_results" says "link": a word for a change.
Description, as the server wrote it Recent finished results for the exam of ONE link (ids from classmarker_list_groups_links_exams), oldest first, PAGED by finish time. Contains personal data: use small pages. Counts as one of ClassMarker's 30 requests per hour per API key. API: GET /v1/links/{link_id}/tests/{test_id}/recent_results.json.
Annotations the server declares
- title: Recent results for one link exam
- readOnlyHint: true
classmarker_recent_link_resultsRecent finished test results taken through the key's links (all links, all exams), oldest first, PAGED by finish time: test-taker name, email, score, pass/fail, timing, access code…1 finding
Why it is in this group
- The name "classmarker_recent_link_results" says "link": a word for a change.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Findings
- Warn
The server marks "classmarker_recent_link_results" read-only (readOnlyHint: true), and its own name, description or input give the class "write".
What this check looks forMatched text
annotations: {"readOnlyHint":true}; The name "classmarker_recent_link_results" says "link": a word for a change.
Description, as the server wrote it Recent finished test results taken through the key's links (all links, all exams), oldest first, PAGED by finish time: test-taker name, email, score, pass/fail, timing, access code, extra tracking fields, IP address, certificate. Contains personal data: use small pages. Max look-back 3 months. Counts as one of ClassMarker's 30 requests per hour per API key. API: GET /v1/links/recent_results.json.
Annotations the server declares
- title: Recent results across all links
- readOnlyHint: true
Only reads 4Claude Code: allow
classmarker_get_questionGet one question-bank question by id (ids from classmarker_list_questions).No findings
Why it is in this group
- The name "classmarker_get_question" says "get": a word for reading.
Description, as the server wrote it Get one question-bank question by id (ids from classmarker_list_questions). Counts as one of ClassMarker's 30 requests per hour per API key. API: GET /v1/questions/{question_id}.json.
Annotations the server declares
- title: Get a question
- readOnlyHint: true
classmarker_list_categoriesList the question-bank categories with their parent categories and ids (needed for creating and updating questions).No findings
Why it is in this group
- The name "classmarker_list_categories" says "list": a word for reading.
Description, as the server wrote it List the question-bank categories with their parent categories and ids (needed for creating and updating questions). Counts as one of ClassMarker's 30 requests per hour per API key. API: GET /v1/categories.json.
Annotations the server declares
- title: List question categories
- readOnlyHint: true
classmarker_list_groups_links_examsList the groups, links and exams (tests) this API key can access, with the ids the other tools need (group_id, link_id, link_url_id, test_id, and access_list_id for links with an a…No findings
Why it is in this group
- The name "classmarker_list_groups_links_exams" says "list": a word for reading.
Description, as the server wrote it List the groups, links and exams (tests) this API key can access, with the ids the other tools need (group_id, link_id, link_url_id, test_id, and access_list_id for links with an access-code list). Good first call. Counts as one of ClassMarker's 30 requests per hour per API key. API: GET /v1.json.
Annotations the server declares
- title: List groups, links and exams
- readOnlyHint: true
classmarker_list_questionsList the questions of the question bank, 200 per page (page 1, 2, ...): question text, type, category, points, options, correct options, status.No findings
Why it is in this group
- The name "classmarker_list_questions" says "list": a word for reading.
Description, as the server wrote it List the questions of the question bank, 200 per page (page 1, 2, ...): question text, type, category, points, options, correct options, status. A full page means more may follow, so ask for the next page. Counts as one of ClassMarker's 30 requests per hour per API key. API: GET /v1/questions.json?page=N.
Annotations the server declares
- title: List question-bank questions
- readOnlyHint: true
This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.
Install
Pinned to version 1.3.3. Values in angle brackets are yours to fill in.
claude mcp add --transport http classmarker https://classmarker.usefulapi.io/mcpRun in a terminal.
Claude Code permissions
Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.
{
"permissions": {
"allow": [
"mcp__classmarker__classmarker_list_groups_links_exams",
"mcp__classmarker__classmarker_list_categories",
"mcp__classmarker__classmarker_list_questions",
"mcp__classmarker__classmarker_get_question"
],
"ask": [
"mcp__classmarker__classmarker_recent_group_results",
"mcp__classmarker__classmarker_recent_link_results",
"mcp__classmarker__classmarker_recent_group_exam_results",
"mcp__classmarker__classmarker_recent_link_exam_results",
"mcp__classmarker__classmarker_add_access_codes",
"mcp__classmarker__classmarker_create_parent_category",
"mcp__classmarker__classmarker_create_category",
"mcp__classmarker__classmarker_create_question"
],
"deny": [
"mcp__classmarker__classmarker_update_parent_category",
"mcp__classmarker__classmarker_update_category",
"mcp__classmarker__classmarker_update_question"
]
}
}Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as classmarker. Review it before you use it.