Composed FastMCP server combining CMU services: Dining, Maps, Courses, Guide, and Bus predictions
The server has 28 tools across 5 domains (bus, dining, courses, maps, guide). Most tools are explicitly registered with FastMCP and have descriptions, but critical gaps emerge in parameter schema documentation, output schema specification, and error handling guidance. Tools follow a consistent naming pattern (verb_noun) and descriptions range from adequate to good (80-250 chars typical), but parameter schemas are often incomplete, many lack explicit type constraints, enums, and LLM-actionable error messages. The bus and guide services show better structure; dining and courses are more sparse. No tool exhibits the full A+ pattern (complete schema + LLM-optimized descriptions + error recovery guidance). Average per-tool score: 62/100.
Compute distance in meters between two locations.
Fetch a CMU course by its ID (exact match, e.g. "15-122" or "15-213").
Fetch all instructors for a CMU course by its ID (exact match).
Fetch the requisites for a CMU course by its ID (exact match).
Fetch all schedules/times for a CMU course by its ID (exact match).
Fetch a list of CMU courses by their IDs (exact match, e.g. ["15-122", "15-213"]).
Fetch general education requirements allowed for a specific department, optionally filtered by school and requiring a user token.
Output schemas not documented. Tools return dicts with unknown field structure. LLMs cannot plan downstream calls or extract key data reliably.
Parameter descriptions missing or minimal for many dining and course tools. E.g., 'location_name' in get_location_hours lacks guidance on partial matching behavior; 'query' in search_courses_by_query says nothing about supported syntax or field coverage.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 69 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 59 | - | v1 |
Fetch all general education requirements, optionally filtered by school.
Get all CMU dining locations with their basic information formatted as clean markdown. Returns a formatted list of all dining locations on campus including name, cuisine type, location, hours, status, and whether they accept online orders. Locations are grouped by cuisine type for easy browsing.
Get live predictions for both configured Forbes/Morewood bus stops. Stop 4407 is inbound toward Downtown/Oakland near Tepper Quad. Stop 7117 is outbound near CUC. ``seconds`` is time until the bus reaches the listed boarding stop.
Explain how eligible CMU students use the PRT Ready2Ride benefit.
Get detailed information for a specific dining location formatted as clean markdown.
Find dining locations by cuisine type or food description formatted as clean markdown.
Get dining locations open at a specific day and time formatted as clean markdown.
Get all dining locations that are currently open formatted as clean markdown. Returns a formatted list of locations that are open right now based on current day and time. Locations are grouped by cuisine type for easy browsing.
Get the earliest matching bus for each relevant direction. Stop 4407 is inbound/Downtown near Tepper; 7117 is outbound near CUC. A route-only or unfiltered request returns separate inbound and outbound results. ``place`` accepts either a configured neighborhood/waypoint or a case-insensitive live route destination. Squirrel Hill results distinguish Forbes & Murray (61A/61B/61C/61D) from Wilkins & Murray (67/69). Arrival seconds and minutes are countdowns to the named boarding stop, not ride time to the destination area. A no-match response includes all current predictions under ``available.predictions`` so the client can offer live alternatives without making another tool call.
Fetch the complete raw markdown of a single page from the guide, by its repo path (e.g. "src/pages/meal-plans.md"). Use list_pages to see valid paths. Prefer search_guide + get_section for targeted lookups; use this only when you actually need the whole page.
Get a path between two locations by ID/coordinates.
Fetch the full text of one chunk/section returned by search_guide, by its chunk_id (e.g. "src/pages/loareturn.md#3").
Get predictions for one configured stop ID. Use 4407 for the inbound/Downtown side near Tepper Quad. Use 7117 for the outbound side near CUC. ``seconds`` is time until arrival at that stop.
List every page in the cmu-guide with its title, description, and repo path. Good starting point to see what topics are covered before searching or fetching.
List possible location names matched by a query.
Re-fetch the latest content from github.com/ScottyLabs/cmu-guide and rebuild the search index. The index is normally cached for 24h in memory, so call this if the guide may have been updated and you need fresh content.
Search buildings/floorplans by query string (e.g., 'morewood').
Literally search current stop IDs, routes, destinations, or capacity. This case-insensitive search does not resolve arbitrary places or neighborhoods. Arrival time is the countdown to the listed boarding stop.
Search for CMU courses by name or description (e.g. "programming" or "database").
Search for dining locations by name and return formatted results.
Full-text search over the ScottyLabs cmu-guide (cmu.guide) — dorms, meal plans, leaves of absence, transferring majors, accommodations, etc. Returns short snippets with a chunk_id and source file for each match. Use get_section or get_page to pull the full text of a specific result once you know which one you need; don't load whole pages up front.
No enum constraints on search/filter parameters. 'cuisine_query' in get_locations_by_cuisine and 'query' strings in search tools accept free-form input with no documented valid values, inviting hallucinated queries.
Error handling lacks recovery guidance. Tools return 'input_error' or unspecified errors without actionable next steps. E.g., 'unknown_stop' error in get_stop_predictions includes known_stops list (good), but search tools return no alternatives on no-match.
Tool names ending in '_tool' signal incomplete abstraction (fetch_geneds_tool, fetch_geneds_for_department_tool). Rename to canonical verb_noun form: get_gened_requirements, get_department_geneds.
No guidance on pagination or result limits. Tools returning lists (get_all_dining_locations, list_pages, search_guide) do not document expected size, cap, or how to iterate large result sets.
Optional parameters lack defaults. get_locations_open_at_time 'minute' defaults to 0, but many tools with optional filters (stop_id, route, place, direction in get_next_bus) do not document default behavior when omitted.
fetch_geneds_tool and fetch_geneds_for_department_tool accept 'user_token' parameter. Sensitive tokens should never appear as tool parameters, use server-side secret injection.