Gradescop
Gradescop is a local, read-only Gradescope MCP server that archives your coursework and lets you query it from Codex.
Connect & check status:
connectopens a browser for interactive sign-in;connection_statusshows stored health, sync freshness, and archive location.Sync your data:
syncasynchronously refreshes courses, attachments, submissions, rubrics, and annotations (optionally scoped by course/assignment);sync_statusreports job progress and gaps.Browse courses & assignments:
list_courseslists courses across terms;list_assignmentsshows status, scores, and visible deadlines with filters (status, search, due-date range, pagination).Inspect assignment detail:
get_assignmentreturns metadata, material file IDs, and completeness;get_submissionreturns submitted answers, page mappings, and history.Read feedback:
get_feedbackreturns visible comments, annotations, and applied rubric items (withapplied_only=falseto see all visible rubric items).Read original documents:
read_documentextracts page-level text from preserved PDFs, with optional local OCR for scanned pages.Search & track changes:
search_courseworksearches titles, feedback, and full document text;get_changeslists archive changes since a timestamp.
All operations are read-only and local—never submitting work, editing answers, or requesting regrades.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Gradescoprefresh Gradescope and show my upcoming assignment deadlines"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Gradescope MCP for Codex — Gradescop
Get started · Architecture · Roadmap · Test coverage · Contribute
Gradescop is a local, read-only Gradescope MCP (Model Context Protocol) server and Codex plugin for students. Archive assignments, deadlines, original and graded PDFs, released rubric feedback, comments, annotations, and accessible submission history across courses.
Preview release: macOS only. Independent project; not affiliated with Gradescope, Turnitin, or OpenAI. Each user signs in to their own account. This repository contains code and synthetic tests, not account data.
Quick start
Requires macOS, Node.js 22.13 or newer, Google Chrome, and Poppler (pdftotext and pdftoppm on PATH). Optional OCR requires Tesseract. With Homebrew, install these using brew install node poppler and optionally brew install tesseract; install Google Chrome separately.
git clone https://github.com/duhaolei43-source/gradescope-mcp.git gradescope-personal
cd gradescope-personal
npm ci
node scripts/configure.mjs
npm test
npm run connect
npm run syncSign in yourself in the browser opened by connect; institutional SSO/MFA may require interaction. Never place your password in a prompt, repository, command, or environment variable. A blocked SSO flow is unsupported until verified; do not bypass it.
Related MCP server: MCP Student Assistant
Connect to Codex
From the cloned directory, register the server with the Codex CLI:
codex mcp add gradescope --env NODE_NO_WARNINGS=1 --env "PATH=$PATH" -- "$(command -v node)" "$PWD/src/server.mjs"Open a new local Codex task. Ask: “Refresh Gradescope and show upcoming assignments,” or “Read all released feedback on this assignment.” Other STDIO MCP clients can use the generated .mcp.json configuration. Keep this checkout in place: configuration points at it.
This command registers MCP tools; it does not install a plugin card in the + picker. For plugin packaging, this repository includes .codex-plugin/plugin.json, the generated .mcp.json, an icon, and skills/gradescope/SKILL.md. Use Codex's plugin-creator workflow to register the clone in your personal marketplace, validate it, and install gradescope-personal@personal. A one-command public marketplace installer is planned. Do not install both registrations simultaneously under the same server name.
What is available
Twelve tools: connection_status, connect, sync, sync_status, list_courses, list_assignments, get_assignment, get_submission, get_feedback, read_document, search_coursework, get_changes.
A full sync includes older courses. It reconciles dashboard counts and reports retrieval failures. Query summaries first, then relevant questions and PDF pages. Original files retain every page. Rubric point_effect accounts for positive and negative scoring. OCR results require verification.
Use node src/cli.mjs status for cached health. A saved session is not proof that login still works. Expired sessions require npm run connect. Sync is asynchronous through MCP; wait for sync_status before reporting current data.
Daily updates
Scheduling is opt-in and is not created by installation. Ask Codex: “Run a full Gradescope sync daily at 9 AM local time, including older courses. Notify only on changed assignments, deadlines, submissions, grades or feedback, failures, or required login. Stay quiet when unchanged.” The host and Codex must be available for local scheduled execution. Never use GitHub Actions to synchronize your actual coursework.
Privacy and limits
The archive is in ~/Library/Application Support/GradescopePersonal, outside this repository. Sessions use AES-256-GCM with a macOS Keychain key. Files are created with owner-only permissions. PDF/text coursework itself is not encrypted by this application. Protect your OS account and disk. Retrieved text enters your MCP client's conversation when requested. No hosted service receives the archive from this code.
The adapter reads account-visible student pages and embedded viewer data. It never submits work, starts assessments, activates attempts, edits answers, or sends regrade requests. Reads may record a view on Gradescope. Hidden grades, unopened timed content, unavailable templates, and unapproved external file hosts cannot be promised. Layout changes can break extraction. Support is currently limited to www.gradescope.com and observed upload hosts.
See public plan, approach comparison, security guidance, and contributing.
How it works
flowchart LR
A[Your Gradescope account] -->|Interactive sign-in| B[Chrome session]
B --> C[Student page reader]
C --> D[(Local archive)]
D --> E[12 MCP tools]
E --> F[Codex conversation]
K[macOS Keychain] -. protects session .-> B
C --> G[Coverage and change checks]
G --> DYou ask | Gradescop retrieves |
What is due? | Assignment status and timezone-aware deadlines |
Why did I lose points? | Released rubric items, scoring direction, comments and annotations |
Show the original work | Preserved PDF files and page-level text |
What changed? | Changes since the previous sync, with explicit retrieval failures |
Quality and licensing
Run npm run smoke after installing Poppler. Tests use synthetic records and a generated PDF, isolated temporary archives and local MCP processes. No login or private coursework is needed. See the test matrix and limits.
Released under the MIT license. Dependency licenses remain their respective authors' property. Gradescope and Codex names identify compatible products; this project is independent.
Available Tools
12 toolsconnectA
Open a private browser for interactive Gradescope login. Never pass credentials to this tool.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnlyHint=false, openWorldHint=true, idempotentHint=false, destructiveHint=false), and the description adds meaningful context: it opens a browser (a side effect the agent must expect), it is interactive, and credentials must not be supplied. It stops short of describing session persistence or what state results after login.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, the primary purpose front-loaded and the critical safety constraint immediately after. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, little more is needed. The description could note what to do after connecting (e.g., check connection_status) to fully close the loop, but the core action and its constraint are covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter documentation burden. The note that credentials should never be passed is a useful clarification given the empty schema, though nothing else needs explaining.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (open a private browser) on a named resource (Gradescope session) and clarifies the mode (interactive login). This clearly distinguishes it from siblings like connection_status (which presumably reports state) and sync (which performs data operations).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it (interactive login) but never explicitly says when to call it versus connection_status, nor states prerequisites such as needing to run this before sync. The one explicit constraint ('never pass credentials') is a usage rule but not a routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connection_statusARead-onlyIdempotent
Check stored connection health, synchronization freshness and shared local archive location. This does not verify a live login.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description does add real context beyond that—it reads *stored* state rather than performing live authentication, and it reports a local archive path—but says nothing about freshness limits, staleness, or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the substantive scope front-loaded and the crucial limitation ('does not verify a live login') placed second so it is not buried. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter status tool with no output schema, the description effectively enumerates what is reported: health, sync freshness, and archive location. It could note how staleness is expressed or that results reflect cached data only, but an agent has enough to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless tool is 4. The description correctly refrains from inventing inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Check') and three concrete resources: stored connection health, synchronization freshness, and the shared local archive location. The second sentence usefully scopes it away from a live-login check, which implicitly separates it from 'connect', though it never names a sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The clause 'This does not verify a live login' implies that 'connect' is the alternative when live verification is needed, giving an inferred usage boundary. However, it never says explicitly when to call this versus 'sync_status' or 'connect', so the guidance remains implicit rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_assignmentARead-onlyIdempotent
Read assignment metadata, material file IDs, original date labels and completeness. Refresh with sync when live verification is needed.
| Name | Required | Description | Default |
|---|---|---|---|
| assignment_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, and open-world traits, so the bar is lower. The description still adds meaningful context beyond them: results are cached/static and can be stale, requiring sync for live verification. It does not disclose error behavior for invalid IDs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with zero filler. The stale-data caveat and the sync escape hatch are front-loaded where the agent will see them.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so by naming the returned fields and flagging staleness. For a single-parameter read tool this is nearly complete; only the failure mode for an unknown assignment_id is unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single parameter, so the schema only supplies a name and pattern. The description adds no meaning about assignment_id, but the parameter is self-evident in a get-by-id tool, so baseline 3 is fair.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Read) and enumerates the resource contents: assignment metadata, material file IDs, original date labels, and completeness. This is more informative than a bare 'get assignment', though the distinction from siblings like get_submission is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative and the condition that selects it: 'Refresh with sync when live verification is needed.' This routes the agent to sync whenever freshness matters, but it gives no exclusions for when to prefer this cached read over other read siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_changesBRead-onlyIdempotent
Read compact archive changes since a timestamp. Complete data remains in the archive; changes are not a substitute for coverage checks.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| since | Yes | ||
| offset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the description's added value is the caveat that results are 'compact' and that 'complete data remains in the archive'. That is genuine behavioral context about result completeness that annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the core operation front-loaded and the caveat following. No wasted text, though the second sentence is somewhat oblique about what a 'coverage check' means.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and 0% parameter coverage, the description should explain the returned record shape and pagination behavior. It leaves pagination (limit/offset) and the change object structure unexplained, so an agent cannot fully predict results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries full burden for three parameters. It only explains 'since' implicitly as a timestamp; the limit and offset parameters, including their defaults and pagination meaning, are left entirely undocumented in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb+resource+scope: 'Read compact archive changes since a timestamp' tells an agent exactly what it retrieves and the required anchor point. It does not explicitly differentiate itself from siblings like sync or sync_status, which is the only gap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The line 'changes are not a substitute for coverage checks' cautions about interpretation but gives no when-to-use rule and names no alternative tool. An agent has no guidance on choosing this over sync or sync_status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_feedbackARead-onlyIdempotent
Read all visible comments and annotations for selected questions. Applied rubric items are returned by default; applied_only=false includes all visible rubric items. Never interpret unapplied items as deductions.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| question_id | No | ||
| applied_only | No | ||
| assignment_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, idempotentHint, destructiveHint=false), so the description's added value is the return-behavior detail: applied rubric items by default, all visible items when applied_only=false, plus the warning not to treat unapplied items as deductions. That is meaningful behavior beyond the annotations, though pagination and response shape are unaddressed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly packed sentences, front-loaded with the core action, then the applied_only behavior, then the interpretive caveat. No filler and nothing repeated from structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must cover return semantics; it does so partially (applied vs all rubric items) but omits pagination behavior, the meaning of limit/offset, and the required assignment_id scope. Adequate but with clear gaps for a five-parameter read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the param burden, and it only clarifies applied_only (default true vs false) and hints at question_id via 'selected questions'. The other three parameters (assignment_id, limit, offset) get no explanation, including pagination semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: reading visible comments and annotations for selected questions. That is clearly distinct from siblings like get_submission or read_document, though it never names an alternative to disambiguate further.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implicitly scopes usage to 'selected questions' (question_id) and explains the applied_only toggle, but gives no explicit when-to-use/when-not guidance relative to siblings such as get_submission or search_coursework. Usage is implied rather than directed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_submissionARead-onlyIdempotent
Read submitted answers, page mappings, history and document references for an assignment or specific archived attempt.
| Name | Required | Description | Default |
|---|---|---|---|
| assignment_id | Yes | ||
| submission_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive, so safety is covered. Beyond that, the description usefully discloses what is retrieved (answers, page mappings, history, document references), which matters because no output schema exists. It stops short of permissions, pagination, or size limits, but adds real behavioral value over the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler, stating the action first and the scope second. It is slightly dense with the four-item content list, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and 0% schema description coverage, the description must do more work; listing the returned data helps, but it omits how the two identifiers interact and whether submission_id is optional for the archived-attempt case. Adequate but leaves an agent guessing on scope resolution.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning; it partially does by indicating an assignment-scoped read versus a specific archived attempt, hinting at the assignment_id/submission_id relationship. It does not clarify that assignment_id is always required or that submission_id narrows to an archived attempt, leaving a gap the schema does not fill.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Read) and enumerates the resource content (submitted answers, page mappings, history, document references) for a clearly scoped entity (an assignment or archived attempt). It is clear what the tool returns, though it never names or contrasts itself with siblings like get_assignment or get_feedback, so the agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for an assignment or specific archived attempt' implicitly signals the two usage modes keyed to assignment_id vs submission_id, which is useful. However, there is no explicit when/when-not guidance and no named alternative such as get_feedback or get_assignment, so routing remains inferential.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_assignmentsBRead-onlyIdempotent
List assignment status, scores and effective visible deadlines. Time remaining is calculated now; fetched_at shows source freshness. Paginate to retrieve all.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No | ||
| offset | No | ||
| status | No | all | |
| course_id | No | ||
| due_after | No | ||
| due_before | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish the read-only, idempotent, non-destructive safety profile, so that burden is lifted. The description adds genuinely non-obvious behavior: 'Time remaining is calculated now' tells the agent that time-remaining is computed at call time rather than stored, and 'fetched_at shows source freshness' warns that underlying data may be stale. This is real context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, all front-loaded and free of filler. Each sentence delivers distinct information: what is returned, how time values behave, and how to retrieve the full set.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description partially compensates by describing returned fields (status, scores, deadlines, time remaining, fetched_at) and the pagination requirement. However, with seven undocumented filter parameters and no output schema, an agent still lacks the detail needed to drive the filters correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across seven parameters, so the description carries the full burden and largely fails it. It mentions pagination generically but never names limit/offset, and says nothing about query, status, course_id, due_after, or due_before semantics, such as what 'effective visible deadlines' means for date filtering.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('List') and resource ('assignments') and goes further by enumerating the returned facets: status, scores, and effective visible deadlines. It is clearly distinguishable from single-item siblings like get_assignment, though it never explicitly contrasts itself with search_coursework or get_submission.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Paginate to retrieve all' implies this is the bulk-listing tool and hints at usage, but it never states when to prefer this over get_assignment (single item) or search_coursework (search). No prerequisites, filters-to-use conditions, or exclusions are given despite seven available filter parameters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_coursesBRead-onlyIdempotent
List all discovered courses across terms. Includes discovery counts, access restrictions and verification time.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds some return-content context ('discovery counts, access restrictions and verification time'), but says nothing about pagination behavior, ordering, or freshness/verification of results — relevant gaps for an open-world listing tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with the resource scoping front-loaded and no filler. Structure is clean, though the second sentence reads as a partial return-fields listing rather than the most decision-relevant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with no output schema, the description hints at returned fields but omits pagination behavior and result ordering, which matter given the limit/offset params. Adequate but with clear gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description never mentions the limit/offset parameters or their defaults, ranges, or pagination semantics. With two undocumented pagination parameters, the description fails to compensate for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List all discovered courses across terms'), which is clear and distinguishable from siblings like list_assignments or search_coursework. However, it does not explicitly differentiate itself from sibling listing tools, leaving the agent to infer scope from the name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no prerequisites (e.g., connection state, sync requirements), and no mention of alternatives such as search_coursework or list_assignments. The agent gets no routing help despite several plausible sibling alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_documentBRead-onlyIdempotent
Read original document text by page. The path points to the preserved original. Optional local OCR helps scanned pages; OCR transcription is unverified.
| Name | Required | Description | Default |
|---|---|---|---|
| ocr | No | ||
| page | No | ||
| page_count | No | ||
| document_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds genuinely new behavioral context: the returned path points to a preserved original, OCR is a local optional step, and its transcription is explicitly unverified — a caveat an agent needs to interpret results responsibly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with the core action front-loaded; no filler or restatement of the tool name. The middle sentence about the preserved original is slightly oblique but still earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description should ideally say what comes back (text per page) and note that page_count controls how many pages are returned and the max of 20. It covers the read/OCR story adequately but leaves the pagination behavior undocumented for an agent that must call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter burden. It explains the purpose of ocr ('optional local OCR helps scanned pages') and implies page semantics ('by page'), but says nothing about page_count (default 3, max 20), the page default/minimum, or the document_id pattern constraint.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (read) and resource (original document text) with a scoping qualifier (by page), which is clear enough for an agent to distinguish it from course/assignment siblings. It also clarifies that it returns the preserved original rather than a derived artifact. It lacks explicit comparison to any sibling, but the domain is distinct enough that this isn't a real ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the ocr flag ('helps scanned pages'), which is a useful conditional hint, but gives no guidance on when to use this tool versus alternatives such as get_submission or search_coursework, and no exclusions or prerequisites for the base read operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_courseworkARead-onlyIdempotent
Search locally preserved assignment titles, submission feedback and full document text. Returns short evidence snippets and IDs; retrieve original documents for full context.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| offset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, open-world behavior, so the safety profile is covered. The description adds non-derived context: results come from a locally preserved index and are deliberately truncated to short evidence snippets, meaning an agent should not expect complete text. Return granularity beyond the annotations is the useful addition; nothing contradicts the hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, with the retrieval scope front-loaded and the follow-up action placed second. Each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description does cover the return shape (short snippets plus IDs), which is the most important unknown for a search tool. However, with zero parameter descriptions and no mention of ranking, pagination, or result-count behavior, the definition is only minimally complete for a search operation with three undocumented inputs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for all three parameters, so the description carries the full burden of parameter explanation and provides none. Nothing is said about query syntax or matching behavior, what limit's default of 20 means in practice, or that offset supports pagination — leaving the agent to guess at the retrieval semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Search) over three concretely enumerated corpora: assignment titles, submission feedback, and full document text. It also implicitly separates itself from full-document retrieval, so an agent can route between 'find evidence' and 'read the source' without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear usage rule: use this for snippets and IDs, then retrieve the original document for full context. That is an explicit when-to-use/when-to-switch statement, though it never names the alternative (read_document) nor states any exclusion relative to list_assignments or get_feedback.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
syncA
Refresh Gradescope course listings, attachments, submissions, visible rubric and annotations. Runs asynchronously; poll sync_status. Omitting filters checks all courses, including older courses.
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | No | ||
| assignment_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose readOnlyHint=false, idempotentHint=false, destructiveHint=false and openWorldHint=true, so the write/network profile is known. The description adds genuinely new behavior: asynchronous execution with a documented polling follow-up, and the scope consequence of an empty filter set. It still omits whether stale local data is removed and any rate/timing expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, no filler, and the most important operational fact (asynchronous, poll sync_status) is placed early. Every clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a non-idempotent, async refresh with no output schema, the description covers the essentials: what is refreshed, that it returns immediately, how to get results, and the default scope. The remaining gap is parameter-level behavior and any note on whether syncing removes data that disappeared upstream.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the schema names course_id and assignment_id but never explains their role, format, or interaction. The description partially compensates by framing them as optional filters whose omission means all courses (including older ones), but it never states what happens when only course_id is supplied or what the ^[a-zA-Z0-9-]+$ format requires.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (refresh/sync) and enumerates the exact resources pulled: course listings, attachments, submissions, rubric, annotations. It also implicitly separates itself from sync_status by naming it as the polling companion. It does not contrast with the related sibling get_changes, so sibling differentiation is incomplete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational context: the run is asynchronous, so call sync_status to poll, and omitting filters widens the scope to all courses including older ones. There is no explicit when-not-to-use guidance or head-to-head routing against get_changes, keeping it below a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sync_statusBRead-onlyIdempotent
Read a background synchronization job. Report partial failures and missing coverage explicitly.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile needs no restating. The description adds genuine value by warning that results may be partial with missing coverage, but omits polling behavior, terminal states, or whether job_id must come from an active job.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the core action front-loaded and no filler. The second sentence earns its place by flagging partial-failure reporting, though it reads slightly like an instruction to the caller rather than tool documentation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining return values, and it only gestures at partial failures and coverage gaps without enumerating job states or progress fields. Adequate for a single-parameter status read, but an agent still cannot predict the response shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for the single parameter, so the schema does not describe job_id at all (only a pattern constraint), and the description does not compensate by saying where the id originates or what a valid id refers to.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Read a background synchronization job'), which is precise enough for an agent to know it inspects state rather than triggering work. It does not, however, differentiate itself from the sibling 'sync' tool or explain the relationship to 'connection_status'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus 'sync' (which presumably starts a job), whether the job_id comes from a prior 'sync' call, or how often to poll. The second sentence describes result handling, not usage conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.1.0- First observed
connect - First observed
connection_status - First observed
get_assignment - First observed
get_changes - First observed
get_feedback - First observed
get_submission - First observed
list_assignments - First observed
list_courses - First observed
read_document - First observed
search_coursework - First observed
sync - First observed
sync_status
TDQS
Scored across 12 tools
Most tools target a distinct resource+action (courses, assignments, submissions, feedback, documents, changes). The only mild overlap is between connect/connection_status (live login vs stored health) and sync/sync_status (trigger vs poll), but descriptions explicitly differentiate these cases. An agent can reliably pick the right tool in nearly all situations.
All names are snake_case, and the majority follow a verb_noun pattern (list_courses, get_assignment, get_submission, read_document, search_coursework, get_changes). A few are bare verbs or noun_status forms (connect, sync, connection_status, sync_status), which are minor deviations from the dominant convention but still readable and consistent.
Twelve tools is well within the ideal 3-15 range and each one earns its place: connection, sync lifecycle, and the read paths for courses, assignments, submissions, feedback, documents, and archive changes. No redundant or filler tools are present.
For a read/archival surface the coverage is strong: connection, sync, discovery, assignments, submissions, feedback, documents, search, and change tracking are all present. Minor gaps exist (no explicit course-detail tool or standalone rubric-metadata tool), but these are workable around via get_assignment and get_feedback.
Maintenance
Related MCP Connectors
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
The Academy curriculum as an offline MCP library. Hosted course connector adds progress.
Aspire Learning MCP — browse courses, chapters, lessons, and import LaTeX quizzes
MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that helps students manage academic workflows by integrating with Canvas and Gradescope to fetch deadlines, download course materials, and sync with macOS Calendar or Reminders.7-
- FlicenseNot gradedqualityCmaintenanceEnables querying student information such as marks, attendance, pending assignments, and timetables from a MySQL database through MCP tools.-
- AlicenseAqualityAmaintenanceRead-only MCP server for Canvas LMS that exposes tools to list courses, assignments, grades, submissions, syllabi, announcements, modules, pages, and files, without any write operations.11111MIT
- AlicenseNot gradedqualityCmaintenanceEnables read-only access to University of Waterloo Learn and Piazza, allowing users to view courses, assignments, grades, submissions, discussions, and more through an MCP server.MIT