NTU Course Index MCP
This server is an NTU course index and timetable tool: it looks up undergraduate/graduate course schedules and helps you compare and filter class indexes without credentials.
Get course details: retrieve metadata and every index with its complete timetable for a course in a given academic year and semester (
get_course).List all indexes: see every lecture, tutorial, lab, and other session for a course (
get_course_indexes).Fetch one index's schedule: get every scheduled session for a specific index (
get_index_schedule).Graduate schedules: get class groups for a graduate course in the currently published term (
get_graduate_course_schedule).Exam schedules: retrieve General Access exam dates and times for a course (
get_undergraduate_exam_schedule).Compare indexes: see shared vs. index-specific sessions and optionally check clashes against supplied time slots (
compare_indexes).Filter/search indexes: find indexes matching day/time/lesson-type/teaching-week rules and avoid clashes with your existing timetable (
find_matching_indexes).
All tools are read-only, idempotent, and open-world (live NTU data); no authentication is required.
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., "@NTU Course Index MCPfind SC2001 indexes for AY2026/27 sem 1 that avoid Fridays"
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.
All About NTU MCP
An MCP server for NTU Singapore schedules, learning materials, campus navigation, research, faculty, library discovery, news, and campus services.
STARS · NTULearn · MazeMap · DR-NTU · Library · Faculty · News · Campus services.
For local stdio usage, install uv and Python 3.10 or newer. Run the public tools from PyPI:
uvx --from all-abt-ntu-mcp==0.1.0-beta.1 all-abt-ntuThe client examples below include the personal extra for authenticated tools.
Custom MCP for Cloud AI
In a cloud AI client that supports custom remote MCP servers:
Open the MCP or connector settings and add a server with any name you like.
Enter this server URL:
https://all-abt-ntu-mcp.vercel.app/mcpSelect No authentication and, if asked, Streamable HTTP as the transport.
Save and enable the server.
The hosted server provides public tools only. No NTU credentials are needed. Personal tools, such as NTULearn and saving STARS plans, require the local setup below.
Related MCP server: University Course Catalog MCP Server
Chromium
For authenticated STARS, NTULearn and LibFacilities tools, install Chromium once:
uvx --from 'playwright>=1.50,<2' playwright install chromiumCredentials
Public tools need no credentials. For personal tools, opt into native OS keyring storage by running this yourself in a local terminal:
uvx --from all-abt-ntu-mcp==0.1.0-beta.1 all-abt-ntu auth saveYour password is hidden while typing and stored encrypted in your OS keyring, rather than in plaintext files. The server never includes it in MCP responses sent to the LLM.
The prompts save one account for STARS, NTULearn and LibFacilities and enable automatic login/session recovery. Run auth save again to update it, auth status to check storage without revealing credentials, or auth delete to remove it. Replace auth save at the end of the command above with the action you want.
The keyring must be available and unlocked: Secret Service or KWallet on Linux, Keychain on macOS, Credential Manager on Windows. There is no plaintext fallback. Passwords are not accepted through MCP, command arguments, environment variables, .env, or client configuration. Remove any credentials left in your old configuration; the server no longer reads them. More details: shared credential storage.
Some Linux installations do not include a keyring service. Install a provider such as GNOME Keyring or KWallet using your distribution's package manager, then follow your desktop's setup instructions to start and unlock it before running auth save.
Codex
Add to ~/.codex/config.toml:
[mcp_servers.all-abt-ntu-mcp]
command = "uvx"
args = ["--from", "all-abt-ntu-mcp[personal]==0.1.0-beta.1", "all-abt-ntu"]
env_vars = ["DBUS_SESSION_BUS_ADDRESS", "XDG_RUNTIME_DIR"] # for Linux
startup_timeout_sec = 120
tool_timeout_sec = 240Restart Codex and check codex mcp list. Personal tools use your locally saved keyring account. The env_vars line forwards the Linux desktop session needed for keyring access; start Codex from a terminal where auth status succeeds. These variables contain no NTU credentials.
Claude Code
Register for your user:
claude mcp add --scope user all-abt-ntu-mcp \
-- uvx --from 'all-abt-ntu-mcp[personal]==0.1.0-beta.1' all-abt-ntu
claude mcp listPersonal tools use your locally saved keyring account. Check claude mcp list or /mcp inside Claude Code. See Claude Code's MCP guide for details.
OpenCode
Add to ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"all-abt-ntu-mcp": {
"type": "local",
"command": ["uvx", "--from", "all-abt-ntu-mcp[personal]==0.1.0-beta.1", "all-abt-ntu"],
"enabled": true,
"timeout": 240000
}
}
}Personal tools use your locally saved keyring account. Check opencode mcp list. See OpenCode's MCP guide for details.
Manual install
Clone the repository and run the server from a local checkout:
git clone --branch main https://github.com/pitchaya-s/all-abt-ntu-mcp.git all-abt-ntu-mcp
cd all-abt-ntu-mcp
uv sync
uv run all-abt-ntuFor personal tools, run uv sync --extra personal, then uv run all-abt-ntu auth save in your own terminal. Use uv run all-abt-ntu auth status or auth delete to inspect storage status or remove the account. These commands manage credentials; starting the server still uses uv run all-abt-ntu.
The process uses MCP stdio, so it stays open while its MCP client is connected. Course responses are cached in memory for one hour by default; vacancy snapshots are cached for at most 60 seconds. Set NTU_CACHE_TTL_SECONDS to change the cache time or use 0 to disable caching.
Source layout
src/
├── shared/ Local/public runtimes, HTTP app, keyring, and parsing
├── stars/
│ ├── mcp_server.py STARS tool registration and input schemas
│ ├── personal_tools.py Local authenticated STARS tools
│ ├── room_tools.py Teaching-based room tool registration
│ ├── room_schemas.py Typed room constraints and results
│ ├── domain/ Course models, timetable matching and room searches
│ ├── client/ Public NTU requests and caching
│ ├── parser/ Schedule and personal-page parsing
│ └── wish/ WISH login and saved-plan editing
├── ntulearn/
│ ├── mcp_server.py NTULearn tool registration and input schemas
│ ├── models/ Typed responses grouped by domain
│ ├── client/ Login, sessions, and REST requests
│ ├── parser/ Response and document parsing
│ └── services/ Content, files, mailbox, people, and activity
├── mazemap/
│ ├── mcp_server.py Public map tool registration and input schemas
│ ├── models.py Typed place and direction responses
│ ├── client.py HTTP requests, pacing, and caching
│ └── parser.py Place and route normalization
├── drntu/
│ ├── mcp_server.py Public repository tool registration and schemas
│ ├── models.py Shared metadata, snapshots, and errors
│ ├── rest/ DSpace search, files, and Dataverse datasets
│ └── oai/ OAI-PMH client, parser, models, and service
├── library/
│ ├── mcp_server.py Library tool registration and schemas
│ ├── personal_tools.py Local authenticated facility tool
│ ├── models.py Catalogue, access and facility responses
│ ├── client.py OneSearch requests and pagination
│ ├── facilities.py Public facility directory and map availability
│ ├── session.py Optional facility login and daily time grids
│ ├── schedule.py Time-grid validation and normalization
│ └── parser.py Primo record normalization
├── faculty/
│ ├── mcp_server.py Public faculty tools and input schemas
│ ├── models.py Typed profile and research-interest responses
│ ├── client.py Directory requests, filters, and pagination
│ └── parser.py Profile cards and interest form parsing
├── news/
│ ├── mcp_server.py Public news tools and input schemas
│ ├── models.py Typed story, category, and article responses
│ ├── client.py News search and bounded article retrieval
│ └── parser.py Story cards and article body extraction
└── service/
├── mcp_server.py Public campus service tools and input schemas
├── models.py Typed location and filter responses
├── client.py Complete directory collection and local search
└── parser.py Contact, hours, and map normalization
tests/
├── stars/ STARS tests and fictionalized fixtures
├── ntulearn/ NTULearn tests and synthetic fixtures
├── mazemap/ MazeMap tests and synthetic fixtures
├── repository/ DR-NTU tests and synthetic fixtures
├── library/ OneSearch and LibFacilities tests and fixtures
├── faculty/ Faculty directory tests and synthetic fixtures
├── news/ News search and article tests with synthetic fixtures
├── service/ Campus directory tests and synthetic fixtures
├── hosted/ Public HTTP protocol, isolation, and deployment checks
├── test_*.py Keyring, local CLI, and shared lifecycle tests
└── typescript_smoke.mjs Shared MCP interoperability checkTools
STARS
Public lookups work without credentials. Planner and Degree Audit use the shared NTU credentials.
Tool | Purpose | Credentials |
| Find undergraduate courses by partial code or title keywords in a published term | No |
| Course name, AUs, prerequisites, description, and term metadata | No |
| All indexes with complete schedules, vacancies, and waitlist lengths | No |
| One index's complete schedule, vacancies, and waitlist length | No |
| Shared sessions, index-specific sessions, and optional clash checks | No |
| Filter by days, times, lesson types, teaching weeks, and supplied schedule clashes | No |
| Teaching-observed rooms with no scheduled classes in a time/week window | No |
| Courses, indexes and lessons using a room | No |
| Graduate course class groups and scheduled sessions | No |
| Undergraduate exam date, time, duration, and published-term notice | No |
| Whether optional WISH credentials are configured and a session has been verified | No |
| Your registered courses and saved Plans 1–3 with timetables | Yes |
| Replace a saved plan's course/index list and verify the saved result | Yes |
| Your AU requirements, results, and registered courses | Yes |
Vacancies are available 09:00–22:00 Singapore time; unknown counts are null. Saving a plan replaces its entire course/index list. See the STARS guide for parameters, examples, and sources.
NTULearn
Tool | Purpose | Credentials |
| Credential configuration and last verified session | No |
| Your enrolled courses and organizations, with availability and IDs | Yes |
| One level of course content, with | Yes |
| Published announcements for one course | Yes |
| Calendar entries and published deadlines | Yes |
| All calendar pages across enrolled or selected courses | Yes |
| Gradebook columns and your own visible scores and status | Yes |
| Attached files for a leaf content item | Yes |
| Read PDF, Office, and text attachments inline | Yes |
| Save an attachment to a new, explicit local file path | Yes |
| List inbox or sent messages from course conversations | Yes |
| Full message body and published conversation recipients | Yes |
| Visible course users and their roles | Yes |
| Course groups and group sets | Yes |
| Visible members of a course group | Yes |
| Recursive substring search within one course | Yes |
| Search course content with course IDs and breadcrumbs | Yes |
| Nested course content tree bounded by depth and size | Yes |
| Download course attachments into local folders | Yes |
| Recent announcements, upcoming events, and grade snapshots | Yes |
Start with ntulearn_list_courses, then use the returned IDs. See the NTULearn guide for parameters, examples, and sources.
MazeMap
Tool | Purpose | Credentials |
| NTU campuses and their map IDs | No |
| Buildings and floor IDs, names, and levels | No |
| Find rooms, venues, and amenities by code or name | No |
| One place's location, aliases, building, and floor | No |
| Walking instructions, distance, time, and accessibility | No |
Search for a place first, then use its POI ID for details or directions. See the MazeMap guide for parameters, examples, and sources.
DR-NTU
Tool | Purpose | Credentials |
| Find publications by keywords, repository scope, and facet filters | No |
| Published metadata, abstracts, citations, and rights | No |
| Explore communities, subcommunities, and collections | No |
| Available search filters, values, and result counts | No |
| An item's file groups, including original documents | No |
| File names, sizes, checksums, rights, and content links | No |
| Published dataset metadata, versions, and file inventories | No |
| Repository identity, date precision, and deletion policy | No |
| Available OAI metadata formats and schemas | No |
| OAI collection and community sets | No |
| Metadata or identifiers filtered by modification date and set | No |
| One record by its OAI identifier | No |
Public metadata can describe restricted files. See the DR-NTU guide for parameters, examples, and sources.
Library
Tool | Purpose | Credentials |
| Search OneSearch by keywords, title, author, ISBN, or resource type | No |
| Bibliographic metadata, identifiers, descriptions, and access links | No |
| Physical holdings and institutional full-text service links | No |
| Library facilities, floor maps, and closure notices | No |
| Seat and room statuses at a Singapore date and time | No |
| Daily room and seat time grids and facility descriptions | Yes |
Use the returned record ID and context for details. See the Library guide for parameters and access limitations.
Faculty
Tool | Purpose | Credentials |
| Find faculty by name or research interest, with public profile details | No |
| Research-interest labels and IDs for faculty search | No |
See the Faculty guide for parameters, pagination, and sources.
News
Tool | Purpose | Credentials |
| Search news by keyword, category, and latest or oldest order | No |
| Published news category labels and filter IDs | No |
| Read an article's text in bounded chunks | No |
See the News guide for parameters and sources.
Campus services
Tool | Purpose | Credentials |
| Find food outlets, shops, clinics, and services with hours and contacts | No |
| Official directory type and category filter IDs | No |
See the Campus services guide for parameters and directory coverage.
Tests
Personal-data, map, repository, library, faculty, news, and service fixtures are synthetic. Timetable fixtures use fictional course labels and indexes while retaining the HTML structures needed for parser tests. Opt-in live tests print counts and statuses; they do not save academic records or learning materials in the repository.
The offline tests cover keyring storage and failure handling, local credential prompts, session recovery, parsing, scheduling, lossless compaction, output-schema validation, tool calls/errors, and resource discovery. Protocol tests use Python SDK clients and an independent JSON-RPC client over stdio, including protocol versions 2025-06-18 and 2025-11-25:
uv run python -m unittest discover -s tests -t . -vAn optional check uses the official TypeScript SDK. Node dependencies stay in a temporary directory:
NTU_MCP_TEST_SDK="$(mktemp -d)"
npm install --prefix "$NTU_MCP_TEST_SDK" --ignore-scripts --no-audit --no-fund @modelcontextprotocol/sdk@1.32.1
uv run node tests/typescript_smoke.mjs "$NTU_MCP_TEST_SDK"These interoperability checks use offline fixtures and never edit saved plans.
Hosted HTTP checks cover public-only registration, rejected personal calls, output schemas, both modern and legacy Python SDK clients, Host/Origin validation, request-size limits, and independent serverless event loops. See the HTTP test instructions for the TypeScript client and opt-in live smoke.
Live checks and service-specific testing instructions: STARS · NTULearn · MazeMap · DR-NTU · Library · Faculty · News · Campus services.
Limitation
Access depends on service availability and NTU permissions.
Timetables are published schedules; vacancies are snapshots.
NTULearn may restrict content, and large collections can return partial results. Inline document reading extracts text without OCR.
MazeMap directions are estimates. Map data does not establish room availability or current physical access.
DR-NTU file metadata does not establish download permission. The dataset service may interrupt requests with CAPTCHA.
Room searches cover published undergraduate teaching only, excluding occupancy, graduate classes, exams, other bookings, and access permissions. Unplaced lesson venues remain outside room-specific coverage.
Library records and access labels do not establish subscription entitlement, anonymous full-text access, or a loanable copy.
Facility booking statuses do not establish occupancy. MFA stops library login; no borrowing or facility bookings are submitted.
Disclaimer
This is an independent project and is not affiliated with, sponsored by, or endorsed by Nanyang Technological University (NTU), Singapore.
Your NTU credentials are retrieved locally from your OS keyring and submitted over HTTPS to NTU or its Microsoft sign-in service. They are never returned through MCP. Academic data returned by tools is visible to the AI client. Keyring storage protects credentials at rest; it does not isolate them from other programs or agents allowed to access your unlocked keyring or the server process.
Available Tools
7 toolscompare_indexesBRead-onlyIdempotent
Compare shared and index-specific sessions; optionally check clashes with supplied time slots.
| Name | Required | Description | Default |
|---|---|---|---|
| indexes | Yes | ||
| semester | Yes | ||
| course_code | Yes | ||
| academic_year | Yes | ||
| against_sessions | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint and idempotentHint, so the safety profile is covered. The description adds the clash-checking behavior, which is useful, but says nothing about how shared vs index-specific differences are reported or that this is a pure computation over existing schedule data.
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 — the core compare action comes first and the optional clash check is appended. It is efficient, though arguably under-specified for a five-parameter tool rather than merely concise.
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?
An output schema exists so return values need not be explained, but for a tool with four required parameters and zero schema coverage the description omits the meaning and accepted forms of nearly every input. An agent could not reliably populate course_code, indexes, academic_year or semester from this text.
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 five parameters, so the description carries the burden and largely fails it. Only the optional against_sessions ("supplied time slots") is hinted at; course_code, indexes, academic_year and the semester enum (including the "S" value) are given no meaning, format or cardinality guidance anywhere.
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 uses a specific verb ("Compare") plus the resources being compared ("shared and index-specific sessions"), which is more concrete than a restatement of the name. It does not, however, differentiate itself from the near neighbours like find_matching_indexes or get_index_schedule, so sibling disambiguation is left to the agent.
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?
"optionally check clashes with supplied time slots" implies when the against_sessions parameter is relevant, which is genuine usage context. But there is no explicit when-to-use/when-not guidance and no reference to the obvious alternatives (find_matching_indexes, get_index_schedule) that an agent would weigh this against.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_matching_indexesARead-onlyIdempotent
Find indexes matching day/time/lesson/week rules and avoiding supplied timetable clashes.
| Name | Required | Description | Default |
|---|---|---|---|
| semester | Yes | ||
| constraints | No | ||
| course_code | Yes | ||
| academic_year | Yes | ||
| against_sessions | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds that the tool avoids supplied timetable clashes and matches day/time/lesson/week rules, which is useful behavioral context, but it does not explain how constraints interact, how uncertainty is handled, or what volume of results to expect.
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?
The definition is a single, front-loaded sentence with no redundant or filler language. Every clause contributes to understanding what the tool searches for and what it avoids.
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 an output schema available and rich nested schema definitions for TimeSlot, TimeWindow, SearchConstraints, and SessionRequirement, the description need not explain return values or every nested field. The one-sentence summary is broadly complete for a constrained search tool, though it leaves usage and required-parameter semantics to inference.
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?
Top-level schema description coverage is low, so the description must compensate. It loosely maps to constraints ('day/time/lesson/week rules') and against_sessions ('supplied timetable clashes'), but it does not explain the required course_code, academic_year, and semester parameters or the detailed semantics of the nested constraint fields.
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 gives a specific verb and resource: 'Find indexes,' and states the filtering criteria as 'day/time/lesson/week rules' and 'avoiding supplied timetable clashes.' It clearly describes a constrained search operation, but it does not explicitly distinguish itself from siblings such as get_course_indexes or compare_indexes.
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?
Usage is implied: call this when you need indexes that satisfy schedule constraints and avoid clashes. However, there is no explicit when-to-use versus when-not-to-use guidance, and no alternative sibling is named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_courseBRead-onlyIdempotent
Get course metadata and every index with its complete timetable.
| Name | Required | Description | Default |
|---|---|---|---|
| semester | Yes | ||
| course_code | Yes | ||
| academic_year | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds useful scope context by saying it returns *every* index with a *complete* timetable (a broad, full-expansion read rather than a paginated summary), but says nothing about authentication, rate limits, or behavior when the course/year/semester combination does not exist.
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 zero filler. The returned scope is stated up front, so an agent can triage the tool in one read.
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?
An output schema exists, so return values need not be explained, and the description does convey what the tool fetches. It is nevertheless incomplete for a 3-required-parameter tool whose parameters carry no documentation at all, particularly the ambiguous semester enum.
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%: none of course_code, academic_year, or semester is documented anywhere. The description only vaguely implies a course identifier is involved and adds nothing about the semester enum values (1, 2, 'S'), which are especially cryptic without explanation.
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 ('Get course metadata and every index with its complete timetable'), which is clearer than a bare 'get course'. However it never differentiates itself from the sibling get_course_indexes or get_index_schedule, so an agent must infer which of the two overlapping-sounding tools to call.
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 when-to-use guidance, no prerequisites, and no mention of any alternative tool. With siblings like get_course_indexes and get_index_schedule that plausibly overlap, the absence of routing guidance is a real gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_course_indexesBRead-onlyIdempotent
List all indexes for a course, including every lecture, tutorial, lab, and other session.
| Name | Required | Description | Default |
|---|---|---|---|
| semester | Yes | ||
| course_code | Yes | ||
| academic_year | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds useful scope information about what the returned index set contains (every lecture, tutorial, lab, and other session), but says nothing about permissions, result size, or pagination behavior.
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. The verb and resource come first and the inclusion scope follows immediately, so nothing needs to be trimmed or reordered.
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?
An output schema exists, so return-format explanation is unnecessary, and annotations cover the read-only/idempotent profile. However, with three required parameters at 0% schema description coverage, the definition never tells the agent how to supply course_code, academic_year, or semester, leaving a real gap for a tool this simple.
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 mentions none of the three required parameters. It does not clarify the course_code format, the academic_year convention, or the meaning of semester values (though 1/2/'S' is at least enumerated in the schema). With low coverage, the description should compensate but does not.
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 ('List') and resource ('indexes for a course'), then scopes the result by naming the session types included (lecture, tutorial, lab, other). It clearly distinguishes itself from schedule-oriented siblings by being a course-level index listing, though it never names an alternative tool 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?
No explicit when-to-use, prerequisites, or alternative routing is given. Usage is only implied by the purpose statement ('list indexes for a course'), which is adequate for a simple lookup but leaves the relationship to siblings like get_index_schedule, compare_indexes, and find_matching_indexes for the agent to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_graduate_course_scheduleBRead-onlyIdempotent
Get a graduate course's class groups for NTU's currently published academic term.
| Name | Required | Description | Default |
|---|---|---|---|
| course_code | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so safety is covered. The description adds a genuinely useful behavioral constraint beyond them: only the currently published academic term is served, so historical terms are unavailable. It still says nothing about behavior when a course code is not found.
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?
One tight sentence with the resource front-loaded and the temporal scope trailing. No filler, though it is arguably too terse to carry the parameter burden.
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?
An output schema exists, so return values need not be explained, and the term scoping is covered. The remaining gap is the undocumented course_code format, which is the one thing an agent must get right to invoke the 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% for the single required parameter course_code, so the description carries the burden. 'A graduate course's' only loosely implies that course_code identifies the course; no format, example, or case sensitivity is given.
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 (Get) and resource (a graduate course's class groups) with the scope qualifier 'currently published academic term'. The 'graduate' qualifier implicitly separates it from get_undergraduate_exam_schedule, 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?
No when-to-use guidance, no prerequisites, and no mention of alternatives such as get_index_schedule or get_course. The agent must infer from the name alone which schedule tool applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_index_scheduleCRead-onlyIdempotent
Get every scheduled session for one course index.
| Name | Required | Description | Default |
|---|---|---|---|
| index | Yes | ||
| semester | Yes | ||
| course_code | Yes | ||
| academic_year | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered structurally. The description adds no behavioral context beyond that — no mention of pagination, term-scoping behavior, or what happens when an index has no sessions.
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 efficient sentence with the object of the operation front-loaded, no filler. Its brevity is appropriate to the sentence itself, though it leaves the tool under-specified rather than genuinely concise.
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?
An output schema exists, so return values need not be described. However, for a tool with four required, undocumented parameters and no usage framing, the description is too thin to let an agent call it confidently versus its five schedule-related siblings.
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?
All four parameters (course_code, index, academic_year, semester) are required with 0% schema description coverage, so the description carries the full burden — yet it only obliquely references 'course index'. It adds no format, range, or interpretation guidance for semester, academic_year, or the index value.
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 ('Get every scheduled session') scoped to 'one course index', so an agent can tell it retrieves schedule data rather than course metadata or index lists. It does not distinguish itself from siblings like get_graduate_course_schedule or get_undergraduate_exam_schedule, which cover overlapping schedule territory.
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 explicit when-to-use, when-not-to-use, or alternative tool named. The phrase 'for one course index' only weakly implies you must already have an index (presumably from get_course_indexes); nothing tells the agent how this differs from the other schedule tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_undergraduate_exam_scheduleARead-onlyIdempotent
Get public General Access exam dates and times for a course in the latest or specified published term.
| Name | Required | Description | Default |
|---|---|---|---|
| semester | No | ||
| course_code | Yes | ||
| academic_year | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and open-world behavior, and the description adds real context on top: results are limited to 'public General Access' exams (excluding restricted/non-public exam types) and the term defaults to the latest published one when not supplied. It stops short of stating what happens when no published schedule exists.
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 tight sentence with the resource and the default-term behavior front-loaded and no filler. Every clause carries information the 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?
An output schema exists, so return values need not be described, and the safety profile is handled by annotations. The remaining gap is the undocumented parameter formats (0% schema coverage) and the absence of any routing hint toward the graduate or index-schedule siblings.
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 compensate. It clarifies that course_code identifies the course and that semester/academic_year are optional, defaulting to the latest published term, but it gives no format for academic_year (e.g. 2024 vs 24) or semester values beyond the schema enum.
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?
Specific verb ('Get') plus a precise resource: public General Access exam dates and times for a course. The word 'undergraduate' in the name plus 'General Access' scoping separates it from get_graduate_course_schedule, though the description never names that 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?
Usage is implied by 'for a course' and by the 'latest or specified published term' phrasing, which tells the agent the term arguments are optional. There is no explicit when-to-use vs when-not guidance and no pointer to get_graduate_course_schedule for graduate courses.
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.
7 tool updates
v0.1.0- First observed
compare_indexes - First observed
find_matching_indexes - First observed
get_course - First observed
get_course_indexes - First observed
get_graduate_course_schedule - First observed
get_index_schedule - First observed
get_undergraduate_exam_schedule
TDQS
Scored across 7 tools
get_course returns course metadata AND every index with its complete timetable, which substantially overlaps with get_course_indexes (list all indexes) and get_index_schedule (one index's sessions). An agent could reasonably pick any of the three for overlapping needs. The exam/graduate schedules and the compare/find pair are clearly distinct, but the course/index trio blurs boundaries.
All names follow a verb_noun pattern (get_course, get_index_schedule, find_matching_indexes, compare_indexes) with snake_case throughout. The graduate/undergraduate schedule names are longer and add scope qualifiers, a minor deviation but still readable and predictable.
Seven tools is well-scoped for a course-index lookup domain, covering distinct resource/action combinations without bloat. No trivial single tool or excessive surface.
The surface covers course metadata, index listing, per-index schedules, graduate/undergraduate scheduling, exam dates, index comparison, and clash-aware matching, which is strong lifecycle coverage. Some gaps remain, such as no explicit search-by-course-code tool, but core planning workflows are supported.
Maintenance
Related MCP Connectors
Unofficial NTNU course data: search, timetables, grades, course info, and exam logistics.
Search university course materials, your flashcards, quizzes, streak and quota. All tools read-only.
Read-only University of Macau course, instructor and review data.
- PAVEOAuthcom.pavecfi
Read-only flight-training records for CFIs, students and schools: syllabus, schedule, FAR/AIM.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables course planning for University of Pennsylvania by searching the catalog, inspecting sections and ratings, detecting schedule conflicts, and building weekly schedules.15MIT
- FlicenseNot gradedqualityDmaintenanceProvides intelligent access to a university course catalog with full-text search, prerequisite tracking, instructor lookups, and course comparison prompts.-
- AlicenseNot gradedqualityAmaintenanceEnables natural-language queries across multiple schools' Canvas and Blackboard accounts for courses, notifications, assignments, grades, feedback, and schedules, with read-only access and local todo/calendar export.8MIT
- AlicenseAqualityAmaintenanceGives AI assistants direct, on-demand access to McGill's public Visual Schedule Builder timetable data, letting them search course offerings, fetch sections and meeting times, check conflicts, and generate ranked schedule combinations without a login, API key, or browser session. Queries and schedule calculations run locally on structured results, with a short-lived cache for repeated requests.412 npm2MIT