Skip to main content

Model Context Protocol server for the ScottyLabs CMU Courses API

Project description

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
search_courses Keyword/department search over the catalog. Paginated. none
get_course Full details for a single course (description, prereqs, schedules, etc.). none
get_course_schedules Just the schedules for a course — smaller payload than get_course. none
get_instructor_schedules Schedules taught by a given instructor. none
get_requisites Prereqs / postreqs / AND-of-ORs prereq relations for a course. none
get_geneds Gen-ed-eligible courses for a school (SCS, CIT, MCS, Dietrich). none
search_instructors Discover exact instructor name strings for the by-instructor tools. none
get_course_fces FCE summary for a course (aggregates + 5 recent rows; include_all=True for full history). gated
get_instructor_fces FCE summary for an instructor across courses (same shape as above). gated

API surface this wraps is documented in ../docs/api.md.

Setup

Prerequisites

  • uv — provides the uvx runner 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.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Linux: ~/.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-mcp

Or 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: %APPDATA%\Claude\logs\mcp*.log (Windows) or ~/Library/Logs/Claude/mcp*.log (macOS). Most common: uv not on PATH for the GUI app.
uvx / uv not found in MCP log Claude Desktop's GUI may not see your shell PATH. Run where uvx (Windows) / which uvx (Unix) and put the absolute path in command, e.g. "C:/Users/you/AppData/Local/Python/pythoncore-3.12-64/Scripts/uvx.exe".
FCE tool 401s after running the auth helper Clerk sessions expire (~7 days). Re-run scottylabs-mcp-auth.
Want to verify auth state uv run scottylabs-mcp-auth --show — prints token-file path, presence, and env-var status.
Need to reset the saved token uv run scottylabs-mcp-auth --remove.
Anything else broken uv run python scripts/smoke.py from the project root validates all 13 cases against the live API without involving Claude.

Configuration

Env var Default Notes
SCOTTYLABS_API_BASE https://course-tools.apis.scottylabs.org Override for local backend dev.
SCOTTYLABS_AUTH_TOKEN (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-auth

The helper:

  1. Opens https://www.cmucourses.com in your browser.
  2. Walks you through copying the __client cookie from DevTools. After sign-in you'll be redirected to www.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 check https://clerk.scottylabs.org.
  3. Saves the cookie to a per-user config file (%APPDATA%\scottylabs-mcp\token on Windows, ~/.config/scottylabs-mcp/token elsewhere; 0o600 on 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 cookie

Re-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.py

Expects Summary: 13/13 passed.

Layout

scottylabs-mcp/
├── 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)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scottylabs_mcp-0.1.0.tar.gz (20.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scottylabs_mcp-0.1.0-py3-none-any.whl (21.9 kB view details)

Uploaded Python 3

File details

Details for the file scottylabs_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: scottylabs_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 20.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scottylabs_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 24163fa9f7e4b036667fb901f0072b3d8bdc20a1369a526c15a697b34a0c1b66
MD5 ee8fd2e8faaf2a0ceedbc51e7169fc22
BLAKE2b-256 1ae8e3e3c8e425e02a749d6bc44033aec426f8066788bc5d4ddd1d7960919a2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for scottylabs_mcp-0.1.0.tar.gz:

Publisher: publish.yml on shivendoo123/scottylabs_MCP

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scottylabs_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: scottylabs_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scottylabs_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0d9bf58994cf9527212215c265405cd4fa03ab3a640d738bc23fc96c023f482a
MD5 5c90d35edc0ae4214fb6982f31cb3099
BLAKE2b-256 6b3018b7e5fe423fa7c39c1341a7f769755054f472aab8354a278a8c476c60e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for scottylabs_mcp-0.1.0-py3-none-any.whl:

Publisher: publish.yml on shivendoo123/scottylabs_MCP

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page