scottylabs-mcp
Click on "Install 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., "@scottylabs-mcpSearch CMU courses for machine learning"
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.
scottylabs-mcp
A Model Context Protocol (MCP) server that wraps the
ScottyLabs CMU Courses API
(course-tools.apis.scottylabs.org). It lets a Claude session search the
CMU course catalog and pull full course details from inside a chat.
Tools
Tool | Description | Auth |
| Keyword/department search over the catalog. Paginated. | none |
| Full details for a single course (description, prereqs, schedules, etc.). | none |
| Just the schedules for a course — smaller payload than | none |
| Schedules taught by a given instructor. | none |
| Prereqs / postreqs / AND-of-ORs prereq relations for a course. | none |
| Gen-ed-eligible courses for a school (SCS, CIT, MCS, Dietrich). | none |
| Discover exact instructor name strings for the by-instructor tools. | none |
| FCE summary for a course (aggregates + 5 recent rows; | gated |
| FCE summary for an instructor across courses (same shape as above). | gated |
Wraps the public read endpoints of course-tools.apis.scottylabs.org
(the backend behind cmucourses.com and courses.scottylabs.org).
Related MCP server: Brown Courses MCP Server
Setup
Prerequisites
uv— provides theuvxrunner used below. Install once and you're set.
1. Wire it into Claude Desktop
Edit claude_desktop_config.json:
Windows:
%APPDATA%\Claude\claude_desktop_config.jsonmacOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Create the file if it doesn't exist. Add the scottylabs-cmu-courses entry
under mcpServers (merge with existing entries if present):
{
"mcpServers": {
"scottylabs-cmu-courses": {
"command": "uvx",
"args": ["scottylabs-mcp"]
}
}
}uvx fetches scottylabs-mcp from PyPI and runs it in an ephemeral
environment — no checkout, no manual install. Subsequent runs hit the uv
cache.
2. Restart Claude Desktop
Quit fully (system tray → Quit, not just close window) and reopen. In a
new chat, click the tools icon — you should see all 9
scottylabs-cmu-courses tools listed.
3. Try it in a chat
Public-endpoint examples (no auth required):
"Search CMU courses for machine learning."
"Show me the prereqs for 15-213."
"What is Iliano Cervesato teaching this semester?"
"List SCS gen-eds tagged Science."
4. (Optional) Enable FCE tools
get_course_fces and get_instructor_fces need a Clerk session JWT — see
Auth (FCE tools only) below.
Claude Code instead of Desktop?
claude mcp add scottylabs-cmu-courses --scope user -- uvx scottylabs-mcpOr paste the same mcpServers block into ~/.claude.json under your
project entry.
Local development
If you're hacking on the server, point Claude at your checkout instead:
{
"mcpServers": {
"scottylabs-cmu-courses": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/scottylabs-mcp",
"scottylabs-mcp"
]
}
}
}Forward slashes in the path are JSON-safe on Windows. Restart Claude Desktop to pick up code changes.
Troubleshooting
Symptom | Cause / fix |
Tools don't appear after restart | Check Claude Desktop's MCP log: |
| Claude Desktop's GUI may not see your shell |
FCE tool 401s after running the auth helper | Clerk sessions expire (~7 days). Re-run |
Want to verify auth state |
|
Need to reset the saved token |
|
Anything else broken |
|
Configuration
Env var | Default | Notes |
|
| Override for local backend dev. |
| (unset) | Static Clerk session JWT for FCE tools (advanced; bypasses cookie refresh). See Auth section. |
Auth (FCE tools only)
get_course_fces and get_instructor_fces POST to /fces, which runs through
Clerk's isUser middleware. The production backend has auth enabled (verified
via the smoke harness — calls without a token come back 401), so the MCP
server needs to mint Clerk session JWTs.
Clerk session JWTs only live ~5 minutes, so the MCP server doesn't store a
JWT directly. Instead, it stores the long-lived __client cookie (~7-day TTL)
and exchanges it for a fresh JWT on each FCE call via Clerk's Frontend API.
Tokens are cached in-memory until shortly before they expire.
Option 1 (recommended): the helper
uv run --directory scottylabs-mcp scottylabs-mcp-authThe helper:
Opens
https://www.cmucourses.comin your browser.Walks you through copying the
__clientcookie from DevTools. After sign-in you'll be redirected towww.courses.scottylabs.org— that's where the cookie lives (Application → Cookies →https://www.courses.scottylabs.org→__client→ copy the Value). If it isn't there, also checkhttps://clerk.scottylabs.org.Saves the cookie to a per-user config file (
%APPDATA%\scottylabs-mcp\tokenon Windows,~/.config/scottylabs-mcp/tokenelsewhere;0o600on Unix).
The MCP server picks it up automatically and refreshes JWTs as needed. Manage it with:
scottylabs-mcp-auth --show # check where it's stored / whether it's set
scottylabs-mcp-auth --remove # delete the saved cookieRe-run the helper when:
FCE calls start returning auth errors (cookie expired, ~7 days).
You sign out of cmucourses.com (cookie revoked).
Option 2: env var (advanced)
Set SCOTTYLABS_AUTH_TOKEN to a session JWT directly. The MCP server uses
this value verbatim — no refresh — so you'll need to keep it under 5 minutes
old. Mostly useful for one-off testing. This env var wins over the saved
cookie when both are set.
What happens without auth
The first FCE call returns a ScottyLabsError whose message tells the user
to run scottylabs-mcp-auth. No silent failure.
The other endpoints (search, get-course, schedules, requisites, geneds, instructors) are public and need no auth.
Smoke test
scripts/smoke.py calls the tool functions directly against the live API,
bypassing MCP transport. Useful for sanity checks during development.
uv run --directory scottylabs-mcp python scripts/smoke.pyExpects Summary: 13/13 passed.
Layout
.
├── LICENSE
├── pyproject.toml
├── README.md
├── scripts/
│ └── smoke.py # live-API harness, bypasses MCP transport
├── tests/
│ └── test_summarizer.py # offline unit tests, run by CI
└── src/
└── scottylabs_mcp/
├── __init__.py
├── __main__.py # `python -m scottylabs_mcp`
├── auth_helper.py # `scottylabs-mcp-auth` console script
├── clerk_auth.py # Clerk Frontend API: cookie -> fresh JWT, with cache
├── client.py # shared httpx.AsyncClient + error mapping
├── models.py # pydantic types mirroring the upstream schema
├── server.py # FastMCP app, tool registrations, entry point
└── tools.py # tool implementations (importable for tests)Credits
Huge thanks to ScottyLabs — the student organization at Carnegie Mellon University that builds and maintains the Course Tool (cmucourses.com, courses.scottylabs.org) and its public backend API. This MCP server is just a thin Python wrapper around their work; all the data, scrapers, and infrastructure that make it useful are theirs.
Upstream repo: github.com/ScottyLabs/cmucourses. Consider contributing to or supporting them directly.
Available Tools
9 toolsget_courseA
Fetch full details for a single CMU course, including current schedules.
Use this when you already have the exact course ID. Accepts "15-122" or
"15122". Returns description, units, prereqs/coreqs, cross-listings,
and upcoming schedule with lectures/sections.
Args:
course_id: CMU course ID, e.g. "15-122" or "21-241".
Returns:
Course object with name, department, desc, units, prereqs,
coreqs, crosslisted, schedules, etc.
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| courseID | Yes | |
| name | Yes | |
| department | Yes | |
| desc | No | |
| units | No | |
| manualUnits | No | |
| prereqs | No | |
| prereqString | No | |
| coreqs | No | |
| crosslisted | No | |
| schedules | No | |
| fces | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries the burden. It discloses return fields (description, units, prereqs, etc.) and mentions 'current schedules'. Does not discuss side effects or authorization, but the tool is likely read-only and safe.
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?
Description is concise (three sentences plus Args/Returns lists). Purpose is front-loaded. Every sentence adds value with no 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?
Tool is simple (one parameter, output schema exists). Description lists return fields, but does not address error handling (e.g., invalid course ID). Still, it provides sufficient information 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?
Single parameter course_id with schema schema provides only type and title. Description adds concrete examples ('15-122' or '15122'), explains it's a CMU course ID, and clarifies accepted formats, compensating for 0% schema coverage.
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 clearly states the tool fetches full details for a single CMU course, including schedules. It distinguishes from siblings like search_courses by specifying it requires the exact course ID.
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 says 'Use this when you already have the exact course ID' and provides accepted input formats. Does not reference alternatives from sibling tools, but the guidance is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_course_fcesA
Fetch Faculty Course Evaluations (FCE) ratings for a course.
Use this when the user asks about course difficulty, hours per week,
or instructor ratings. Returns a compact summary: aggregates over all
semesters plus the 5 most recent entries. Set include_all=True only
when the user asks for the full history.
Auth: requires the env var SCOTTYLABS_AUTH_TOKEN to be set to a valid
Clerk JWT. If the upstream backend has auth disabled, the empty token
will work too.
Args:
course_id: CMU course ID, e.g. "15-122".
include_all: Default False — entries holds the 5 most recent
rows and truncated flags whether anything was cut. Pass
True to populate entries with every row. Aggregates
(avg_hrs_per_week, avg_rating, years_covered) always
reflect the full dataset.
Returns:
FCESummary with entry_count, years_covered,
avg_hrs_per_week, avg_rating, entries, truncated.
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | Yes | ||
| include_all | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| entry_count | Yes | |
| years_covered | No | |
| avg_hrs_per_week | No | |
| avg_rating | No | |
| entries | No | |
| truncated | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility. It discloses key behaviors: returns a compact summary with aggregates and 5 recent entries, details the effect of include_all (truncated flag, full history), and mentions auth requirements (env var SCOTTYLABS_AUTH_TOKEN). It does not mention rate limits or destructive effects, but those are not critical for a read 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?
The description is well-structured and front-loaded with the main purpose. It includes all necessary sections (usage, auth, parameters) without excessive verbosity. However, it could be slightly shorter by condensing the auth note or combining some sentences. Overall, it is efficient and clear.
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?
Given the tool has 2 parameters and an output schema (FCESummary), the description covers behavior (aggregates vs. entries), parameters, auth, and return structure adequately. It explains truncation and full history. It does not explicitly list all output fields, but they are partially described in the 'Returns' section and the output schema exists. The description is sufficiently complete for an agent.
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%, but the description provides thorough semantics: course_id is explained with an example ('15-122'), include_all is detailed with its default, behavior (populates entries vs. full dataset), and the 'truncated' flag. This adds significant meaning beyond the schema's bare type and title.
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 explicitly states 'Fetch Faculty Course Evaluations (FCE) ratings for a course,' specifying the verb (fetch), resource (course evaluations), and scope (for a course). It distinguishes from sibling tools like get_instructor_fces, making the purpose clear and unambiguous.
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 provides direct usage guidance: 'Use this when the user asks about course difficulty, hours per week, or instructor ratings.' It also specifies when to set include_all=True ('only when the user asks for the full history'). While it does not explicitly list alternatives or when-not-to-use, the context of sibling tools implies differentiation, and the guidance is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_course_schedulesA
Fetch lecture/section schedules for a single course.
Prefer this over get_course when you only need meeting times — the
response is much smaller. Returns one schedule per offered semester
(typically several across recent years).
Args:
course_id: CMU course ID, e.g. "15-122".
Returns: List of Schedule objects.
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description must cover behavioral traits. It discloses that it returns schedules across recent years, implying a read-only operation via the word 'Fetch'. It is adequate but could explicitly state it is a read-only operation.
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 description is concise with separate sections for Args and Returns. Every sentence adds value, is appropriately front-loaded, and has 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?
Given the tool has only one parameter and an output schema is present, the description provides sufficient context: it explains what the output represents (schedule per semester) and is complete for its complexity.
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%, but the description explains the 'course_id' parameter with an example ('15-122') and notes it is a CMU course ID, adding valuable semantic context beyond the schema's type string.
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 clearly states 'Fetch lecture/section schedules for a single course', using a specific verb and resource. It distinguishes itself from sibling tool 'get_course' by noting it is for schedules only and returns a smaller response.
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 advises to 'Prefer this over get_course when you only need meeting times', providing a clear when-to-use guideline. Also mentions the response structure (one schedule per offered semester).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_genedsA
List gen-ed-eligible courses for a CMU school.
Use this when the user wants courses satisfying a gen-ed requirement for their college.
Args:
school: Exactly one of "SCS" (School of Computer Science),
"CIT" (engineering), "MCS" (sciences), or "Dietrich"
(humanities and social sciences).
Returns:
List of Gened objects, each with course info, gen-ed tags, and
a startsCounting/stopsCounting window.
| Name | Required | Description | Default |
|---|---|---|---|
| school | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description discloses that the tool returns a list of Gened objects with course info, tags, and a start/stop window. This covers the behavioral aspects of a read-only list operation adequately.
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 description is concise with a clear header, then structured Args and Returns sections. Every sentence adds value, and it is front-loaded with the core purpose.
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?
Given the tool has one required parameter and an output schema (implied by 'Returns: List of Gened objects'), the description covers purpose, usage, parameter details, and return format completely. No gaps remain.
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 schema has 0% description coverage, but the description's Args section adds significant meaning by listing valid school values ('SCS', 'CIT', 'MCS', 'Dietrich') and mapping them to their full names, far exceeding the bare schema.
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 clearly states 'List gen-ed-eligible courses for a CMU school,' specifying the verb 'list' and the resource 'gen-ed-eligible courses.' This distinguishes it from sibling tools like search_courses that might list courses in general.
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 explicitly says 'Use this when the user wants courses satisfying a gen-ed requirement for their college,' providing clear when-to-use guidance. It does not explicitly mention when not to use or alternative tools, but the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_instructor_fcesA
Fetch Faculty Course Evaluations (FCE) ratings for an instructor.
Use this for a professor's teaching record across courses, or to compare instructors. Returns a compact summary by default; aggregates span every semester they've taught.
Auth: requires SCOTTYLABS_AUTH_TOKEN (see get_course_fces).
Args:
instructor: Instructor name, exact-match (use search_instructors).
include_all: See get_course_fces. Default False keeps the
response tight.
Returns:
FCESummary (see get_course_fces).
| Name | Required | Description | Default |
|---|---|---|---|
| instructor | Yes | ||
| include_all | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| entry_count | Yes | |
| years_covered | No | |
| avg_hrs_per_week | No | |
| avg_rating | No | |
| entries | No | |
| truncated | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully covers behavior: it returns compact summaries aggregated across semesters, requires auth token, and references return type. No contradictions or missing side effects; it explicitly notes default behavior ('compact summary').
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 description is concise (approx. 100 words) and well-structured with clear sections (Auth, Args, Returns). Every sentence serves a purpose, with no redundancy or outdated info.
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?
Given the tool's simplicity (2 parameters, output schema exists), the description covers all essential aspects: purpose, auth, parameter details, return type reference, and usage context. It is fully adequate for an agent to invoke 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 coverage is 0%, but the description explains both parameters: instructor requires exact match and references search_instructors; include_all is explained via get_course_fces and notes default False. This adds necessary meaning beyond the schema's field names.
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 clearly states the tool's purpose: 'Fetch Faculty Course Evaluations (FCE) ratings for an instructor.' It also specifies use cases ('for a professor's teaching record across courses, or to compare instructors'), differentiating it from sibling tools like get_course_fces and search_instructors.
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 instructs when to use the tool (e.g., for teaching records or comparisons) and provides a prerequisite ('use search_instructors' for exact name match). It references get_course_fces for include_all details but lacks explicit exclusion guidance or full alternative comparisons.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_instructor_schedulesA
Fetch all schedules taught by the given instructor.
Use this for "what is X teaching?" or to find classes by professor.
Pass the instructor name exactly as it appears in the course data —
use search_instructors first to discover the canonical spelling.
Args:
instructor: Instructor name, exact-match. Example: "Iliano Cervesato".
Returns: List of Schedule objects across all courses and semesters.
| Name | Required | Description | Default |
|---|---|---|---|
| instructor | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description discloses behavior: returns list of Schedule objects across all courses and semesters, and notes exact-match requirement. Could mention potential empty results or error behavior but is generally transparent.
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?
Description is concise with front-loaded purpose statement, followed by usage guidance and structured Args/Returns sections. Every sentence adds value without 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?
Given the tool's simplicity (one parameter) and presence of output schema, the description adequately covers usage, parameter semantics, and overall behavior. No gaps for effective agent 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?
Input schema has 0% description coverage (only title), but description adds crucial details: exact-match requirement, example value 'Iliano Cervesato', and instruction to use canonical spelling from search_instructors. Significantly enriches parameter 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 clearly states 'Fetch all schedules taught by the given instructor,' specifying a specific verb and resource. It distinguishes this tool from siblings like 'get_course_schedules' by focusing on instructor-based queries.
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?
Provides explicit usage context: 'Use this for "what is X teaching?"' and recommends using 'search_instructors' first to find canonical spelling. This offers clear when-to-use and alternatives guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_requisitesA
Fetch the prerequisite / postrequisite graph for a course.
Use this for "what do I need before X?" or "what unlocks after X?" questions. Returns:
prereqs: required courses (flat list).prereqRelations: AND-of-ORs decoding (outer AND, inner OR).postreqs: courses that list this one as a prereq.
Args:
course_id: CMU course ID, e.g. "15-213".
Returns:
Object with prereqs, prereqRelations, postreqs.
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| prereqs | No | |
| prereqRelations | No | |
| postreqs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description covers behavior well: explains return structure (prereqs flat list, prereqRelations AND-of-ORs, postreqs). Lacks mention of authentication or performance, but sufficient for a read-only query.
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 paragraphs: first for purpose/usage, second for return structure. No redundant text, every sentence adds value.
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?
Given the tool's simplicity and presence of an output schema, the description fully explains what the tool returns. No gaps.
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 0%, but description adds meaning to course_id with example '15-213', explaining it's a CMU course ID. Single parameter well-described.
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?
Clearly states it fetches the prerequisite/postrequisite graph. Provides specific use-case examples. Distinguishes well from sibling tools by focusing on prerequisites and postrequisites.
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 says when to use with example questions. Does not mention when not to use or alternatives, but context makes it obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_coursesA
Keyword-search the CMU course catalog.
Use this when the user asks about a topic, department, or partial course name and you don't already have an exact course ID. The query is matched against name, department, description, and prereq string.
Args: query: Free-text search. Examples: "machine learning", "discrete math", "Computer Science", "15-122". Department codes work too. page: 1-indexed page number. The backend caps page size at 10.
Returns:
Object with totalDocs, totalPages, page, and docs — a list of
courses with courseID, name, department, desc, units,
prereqs, etc.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| page | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| totalDocs | Yes | |
| totalPages | Yes | |
| page | Yes | |
| docs | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Describes return format, pagination details (page size cap at 10, 1-indexed), and query matching fields (name, department, description, prereq string). Adequate for a search 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?
Structure is clear with summary, usage context, Args, and Returns sections. Front-loaded with main purpose. Slightly verbose but each sentence adds value.
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?
Given output schema exists and description covers input, return format, usage context, and pagination, it is complete for the tool's complexity. No gaps identified.
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%, but description thoroughly explains both parameters: query with examples and page with default and behavior. Adds significant meaning beyond the empty schema descriptions.
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?
Description clearly states 'Keyword-search the CMU course catalog' and explicitly distinguishes from sibling tools like get_course by advising use when the user doesn't have an exact course ID.
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?
Provides explicit guidance on when to use: 'Use this when the user asks about a topic, department, or partial course name and you don't already have an exact course ID.' Does not explicitly state when not to use, but context signals with siblings imply alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_instructorsA
Look up CMU instructor names from the FCE roster.
Use this to discover the exact spelling/casing of an instructor before
calling get_instructor_fces or get_instructor_schedules. Names are
exact-match — pass them verbatim downstream.
Args:
query: Optional case-insensitive substring filter (e.g. "cervesato").
limit: Max results, default 50, hard cap 200.
Returns: List of instructor name strings.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | ||
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description carries full burden. It explains exact-match, case-insensitive substring filtering, default/hard cap on limit, and return type. Could explicitly state it's a read-only operation, but overall adequate.
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?
Description is concise and well-structured: intro, usage guidance, args list, returns. Every sentence adds value. 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?
Given low complexity and presence of output schema, description covers all necessary aspects: purpose, when to use, parameter details, return type, and exact-match constraint. It's complete for the tool's role.
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%, but description compensates well: explains query as optional case-insensitive substring filter with example, and limit with default and hard cap. Adds meaning beyond type/default.
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?
Description clearly states the tool looks up CMU instructor names from the FCE roster, with a specific verb and resource. It distinguishes itself from siblings by positioning as a pre-step for get_instructor_fces and get_instructor_schedules.
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?
Description explicitly tells when to use this tool: to discover exact spelling before calling related instructor tools. It also implies exact-match behavior, guiding the agent to pass results verbatim downstream.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a distinct purpose clearly outlined in its description. Even tools that return related data (e.g., get_course and get_course_schedules) have explicit guidance on when to use each, eliminating ambiguity.
All tool names follow a consistent verb_noun snake_case pattern with 'get_' for retrieval and 'search_' for search operations. No mixing of conventions.
With 9 tools, the server is well-scoped for the domain of CMU course information. Each tool covers a specific query need without being redundant or excessive.
The tool surface covers all major aspects of course information: details, schedules, evaluations, instructors, prerequisites, gen-eds, and search. There are no obvious gaps for the intended use case.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Unofficial NTNU course data: search, timetables, grades, course info, and exam logistics.
Search Codeforces problems and inspect public problem metadata through the official Codeforces API.
Look up Pokémon, moves, abilities, items, natures, and type matchups from PokéAPI v2.
Read and author HiveLearn courses, events, quizzes, certificates, resources, leaderboards, tracks.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceMCP server for querying a university course catalog. Enables searching courses, checking prerequisites, and looking up instructors via natural language.
- FlicenseAqualityDmaintenanceEnables searching Brown University courses, getting detailed course info, and checking schedule conflicts via natural language, using the university's public course catalog API.5
- FlicenseNot gradedqualityCmaintenanceProvides intelligent access to a university course catalog with full-text search, prerequisite tracking, instructor lookups, and course comparison prompts.
- AlicenseAqualityBmaintenanceEnables searching and retrieving course listings, departments, and syllabi from National Chengchi University's public course API using natural language.3MIT
Appeared in Searches
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/shivendoo123/scottylabs_MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server