Skip to main content
Glama

check_plan

Read-onlyIdempotent

Validates a term-by-term degree plan against the Bulletin before you present it, flagging unmet prerequisites, unit caps, duplicate or unknown courses, and uncovered requirements.

Instructions

Validate a term-by-term plan. Call this before presenting any plan, fix every error, and re-check until valid. courses gives each planned course's title, units and source_page for the plan's table: no get_course per course. Errors (with Bulletin text/pages): prereq not met by that term, course already passed or planned twice, unknown course, units over the term's cap (profile.max_units_per_term, else the term's max_units, else 15), requirement or 120/upper-division units not covered. Warnings: unverifiable prereqs (GPA not given, permission), loads above the normal 15 (p.2393; "as on the Bulletin roadmap" with no advisor when the term's roadmap semester prints that load), unfilled slots. profile.f1: true for an F-1 visa student: a spring/fall term under 12 units is an error (the plan's last term: a warning and the international office), and so is a skipped spring/fall term (pp.2390, 2393). profile.permissions: courses the student says an instructor or department already gave them permission for: those prereq branches count, with a warning to bring it to registration. profile.overload_approved: terms whose overload the student says their advisor approved: no advisor handoff for that load (the term's cap still applies).

plan: {semesters: [{term: '2027-fall', courses: ['CSC 413', {slot: 'senior_electives', units: 3}]}]}. Pass
build_plan's semesters back as returned: their max_units and roadmap {units, source} keep the roadmap's loads. A slot is an
unfilled pick for a requirement group (group ids from get_program_requirements), or {slot: 'elective', units: 3,
upper_division?: true} for free units. Terms are YYYY-spring/summer/fall, or YYYY-winter for Winter Session (January,
between fall and spring, at most 4 units), after the profile's completed terms.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "profile": "<profile>",
      "plan": "<plan>"
    },
    "name": "check_plan"
  }
}

Input Schema

NameRequiredDescriptionDefault
planYes
profileYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this read-only and idempotent, and the description does not conflict with that. It adds substantial behavioral detail beyond the annotations: the full error taxonomy, warning categories, the units-cap fallback chain (max_units_per_term → term max_units → 15), F-1 rules for under-12-unit and skipped terms, and how permissions/overload_approved suppress specific warnings. It could still say more about ordering or precedence when multiple errors overlap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The imperative action is front-loaded and nearly every clause carries a concrete rule rather than filler. Density works against readability in the warnings sentence, where nested parentheticals ("p.2393; 'as on the Bulletin roadmap' with no advisor...") take effort to parse, but the length is justified by the rule surface.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex validator with no output schema, the description covers the input contract and describes what comes back (errors with Bulletin text/pages, warnings, plus the categories of each). Structural details of the response shape (field names, whether a boolean pass/fail accompanies them) are not specified, which is the main remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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, and it does for the highest-risk fields: profile.f1, profile.permissions, profile.overload_approved, max_units_per_term, and the plan.semesters structure including term formats (YYYY-spring/summer/fall, YYYY-winter with its 4-unit cap) and slot forms. It leaves many other Profile fields (gpa, adt, approved, dpr_met, qr_pathway) unexplained, so compensation is strong but not complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Validate a term-by-term plan" states a specific verb and resource, and the description immediately frames its role relative to build_plan ("Pass build_plan's semesters back as returned"). An agent can distinguish validation from planning or course lookup without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use instruction: "Call this before presenting any plan, fix every error, and re-check until valid." It also pre-empts the wrong sibling call by noting "no get_course per course" and points to get_program_requirements for slot group ids.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.