ucla-soc-mcp
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., "@ucla-soc-mcpWhat open computer science courses are there in Fall 2026?"
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.
UNOFFICIAL UCLA Schedule of Classes — MCP Server & Claude Plugin
An MCP (Model Context Protocol) server that lets Claude or any MCP-capable agent query the public UCLA Schedule of Classes — no login or API key required. It wraps the same AJAX endpoints the SoC website itself uses.
The repo is also a Claude Code plugin (ucla-soc) that bundles the server together with
a schedule-planning skill: a guided workflow that confirms the term being planned, collects
the student's wants and a DARS degree audit, verifies prerequisites and final-exam conflicts,
weighs time-of-day/gap/walking-distance preferences, and renders a mock schedule artifact
from a fixed template.
Tools
Tool | What it does |
| Terms selectable in the SoC (e.g. |
| All subject areas offering courses in a term, with exact codes ( |
| Overview of every course a subject offers in a term — catalog number + title — optionally filtered by availability ( |
| Full detail for one course: each lecture/seminar section's status, enrolled/capacity/spots left, waitlist counts, days, times, locations, units, instructors, plus nested discussion/lab subsections |
| Per-section class detail page: final exam date/day/time/location (or an explicit "none listed"), enforced/warning requisites with minimum grades, grading basis, enrollment restrictions, level, class notes, course description |
| UCLA General Catalog entry for a course (term-independent): title, units, grading basis, level, full catalog description, and the requisite sentences pulled out of it |
| Offline walking-time estimate between two classroom buildings, from raw SoC location strings ( |
| Every UCLA building |
Related MCP server: University Course Catalog MCP Server
Resources
Resource | What it does |
| A self-contained Node.js script (dependencies bundled in) that deterministically parses a saved UCLA Degree Audit (DARS) HTML file. Save it and run |
Inputs are forgiving: terms accept 26F or Fall 2026; subjects accept codes or names
(COM SCI or Computer Science); catalog numbers accept 31, M151B, cs 31-style input.
Ambiguous or unknown inputs return actionable error messages listing valid options.
Schedule planning
Three tools answer the questions that come up once you have a candidate schedule.
get_class_detail reads the class detail page behind each section link, so you can
check whether two courses share a final exam slot (final_exam is null with a
final_exam_note when nothing is scheduled) and whether a class is requisite-blocked.
get_course_description reads the General Catalog entry, which states requisites in
prose ("Enforced requisites: courses 32, 33, 35L.") independent of any term.
estimate_walk_time is fully offline: it strips the room number off a location string,
fuzzy-matches the building against a curated dataset (96 buildings, registrar
abbreviations included), and reports haversine distance × 1.4 walked at 80 m/min.
Coordinates are approximate and labelled as such — it is for spotting a 10-minute
passing-period problem, not for navigation. list_buildings shows what it knows.
Degree audit parsing
Degree audit parsing is a resource, not a tool: the saved DARS HTML lives wherever the caller has it (a local file, a dragged-in upload), not on this server, so the server hands over a script to run rather than accepting a file path as a tool argument.
Open your audit at dars.ucla.edu (Audit Results tab), use the
browser's Save page as (complete webpage or single HTML file), then read the
ucla-soc://scripts/parse-degree-audit.cjs resource, save its contents to a file, and run:
node parse-degree-audit.cjs <path-to-audit.html> [status_filter]status_filter is one of all (default), unfulfilled, in_progress, complete.
The script bundles its own dependencies (no npm install needed) and prints the parsed
audit as JSON to stdout. Parsing is fully deterministic — it walks the audit's stable
DARS markup (.requirement, .subrequirement, .takenCourse, .subreqNeeds, …); no
network access and nothing is uploaded anywhere.
Setup
Claude Code (plugin — recommended)
The repo is its own plugin marketplace. In Claude Code:
/plugin marketplace add aaditsingh07/ucla-soc-mcp
/plugin install ucla-soc@ucla-soc-mcpNo Node build step needed — the plugin ships a self-contained server bundle
(dist/bundle.cjs) and registers all tools automatically. Start planning with
/ucla-soc:schedule-planning, or just ask about UCLA classes and Claude will
pick the skill up on its own.
Manual build (any other setup)
git clone https://github.com/aaditsingh07/ucla-soc-mcp.git
cd ucla-soc-mcp
npm install
npm run buildNote: the repo's
.mcp.jsonis the plugin's server config and uses${CLAUDE_PLUGIN_ROOT}, so it only resolves when installed as a plugin. For a manual setup, register the server yourself as shown below (Claude Code:claude mcp add ucla-soc -- node /absolute/path/to/dist/index.js).
Claude Desktop
Add to claude_desktop_config.json (Settings → Developer → Edit Config), using the
absolute path to dist/index.js in your clone:
{
"mcpServers": {
"ucla-soc": {
"command": "node",
"args": ["/absolute/path/to/ucla-soc-mcp/dist/index.js"]
}
}
}Any other MCP host
Stdio transport: node dist/index.js. All tools are read-only (readOnlyHint: true).
Testing
npm test # builds, then runs scripts/smoke-test.mjs against the live SoC siteHow it works (reverse-engineered endpoints)
This server uses endpoints the web front-end calls:
Terms — parsed from
<option class="select_term">tags on/ro/public/soc.Subject areas —
GET /ro/ClassSearch/Public/Search/GetSimpleSearchData?term_cd={term}&search_type=subject; the response embeds an HTML-encoded JSON array of{label, value}pairs.Course list —
GET /ro/Public/SOC/Results/CourseTitlesViewwithmodel(subject search JSON) andfilterFlags(availability etc.), paged 25 courses at a time. Each course comes with a model object (including a base64 token) used for the detail call.Sections —
GET /ro/Public/SOC/Results/GetCourseSummarywith a course model. Called with the root model it returns top-level sections (lectures); called with a section's child model it returns that section's discussions/labs. Rows are HTML; status ("Open", "81 of 237 Enrolled", "156 Spots Left", "Class Full (160)"), waitlist ("0 of 40 Taken"), days/time/location/units/instructor are parsed from the column cells.Class detail —
GET /ro/Public/SOC/Results/ClassDetail?term_cd=&subj_area_cd=&crs_catlg_no=&class_id=&class_no=, the URL each section link points at. The response is the full SoC page shell, with the data in#final_exam_info,#course_requisites,#enrollment_infoand#section.Catalog descriptions —
GET https://catalog.registrar.ucla.edu/course/{year}/{SUBJECTCODE}{NUMBER}(e.g./course/current/COMSCI111). The catalog's own JSON API needs a key, but the page is server-rendered and every field is in its embedded__NEXT_DATA__blob.
Requests send X-Requested-With: XMLHttpRequest. Terms are cached 1 h, subject lists 12 h;
course/section data is always fetched live so seat counts are current.
Notes
search_coursescaps at 12 pages (300 courses) per subject and sets atruncatedflag if hit.get_course_detailsreturns at most 4 matching courses (relevant for topic-split numbers like188, which appear once per topic).get_class_detailfetches one page per section, so it uses the first matching course and caps at 6 sections per call.Not every class has a final: online, summer-session and many seminar/lab sections come back as "None listed — consult instructor for method of evaluation". Final exam locations are only published in 9th week; before that the location cell says so.
Not affiliated with UCLA. Data comes from the public SoC and is subject to change by the registrar; enrollment capacities are "subject to departmental change" per the site.
License
Unlicense — public domain. Do whatever you want with it.
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Public MCP server for discovering open jobs. Search, filter, and get application links.
MCP server for aerospace calculations: orbital mechanics, ephemeris, DSN operations, ...
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceMCP server for querying a university course catalog. Enables searching courses, checking prerequisites, and looking up instructors via natural language.-
- FlicenseNot gradedqualityDmaintenanceMCP server that exposes a university course catalog to LLMs, enabling course search, prerequisite lookup, instructor details, and department directory through natural language.-
- FlicenseNot gradedqualityCmaintenanceMCP server for a university course catalog backed by SQLite, providing course search, prerequisite lookup, instructor search, and course comparison tools.-
- AlicenseAqualityCmaintenanceAn MCP server for the University of Vienna's course catalogue (u:find), enabling natural language queries for courses, programmes, staff, and schedules. Read-only, no account or API key required.13MIT