← Registry

Developer Tools

upsked.com

Provides access to university course catalogs, sections, and availability data via the Upsked platform.

1 endpoint22 known toolsFirst detected July 10, 2026Last detected August 15, 2026

ENDPOINT 1

https://upsked.com/api/mcp

No auth detected

MCP server metadata

Name
upsked
Version
1.0.4
Capabilities
resources.listChangedtools.listChanged
Server instructions

Upsked is a college schedule planner with multi-school catalog support. Read-only catalog tools work without authentication. Schedule tools need auth (see AUTH). All times are in Philippine Standard Time (UTC+8), HH:MM format. Convert from the user's local timezone before time-based filters. **Multiple saved schedules (versioning) are fully supported.** The same user can keep several independent drafts per semester (e.g. Schedule A–E in the web UI). **Pass `version_id` on every schedule read/write and when applying planner output** so you target the right slot; see SCHEDULE VERSIONS below. Omitting `version_id` on `get_my_schedule` returns only the latest-edited draft, not a fixed letter. AUTH - Read-only catalog tools: no authentication. - Schedule read/write (get_my_schedule, all schedule mutations, build_optimal_schedule when saving): Authorization: Bearer <mcp_personal_access_token> (the `upsked_mcp_pat_v1_...` value from MCP client setup in Account settings), or an OAuth 2.1 access token from a connected MCP client (Supabase). Copied browser session JWTs work only if the server sets MCP_ALLOW_WEB_SESSION_JWT_FOR_MCP=true. **Always pass `version_id` when the user names Schedule A–E, wants a second draft, or has more than one saved plan** so reads and writes hit the intended slot. - Header-based anonymous MCP auth (X-Upsked-*) is removed. POST /api/auth/mintScheduleWriteToken is for the web app only (short-lived `schedule_write_token` in save request bodies—not an MCP header). SEMESTER - **Step 1:** Resolve `university_id` before catalog calls — user-stated school, **get_universities**, or **get_semesters** with `university`. Do not assume UPD when the user named another school. - If `semester_id` is missing or unclear, call **get_semesters** with the same `university` or read **upsked://semesters** (UPD-only when args empty). Omitting `university` on **get_semesters** returns **UP Diliman (upd)** semesters only — **REST GET /semesters without ?university= lists all schools instead.** Pass `university` for admu, upb, dlsu, etc. **Full policy:** resources/read `upsked://docs/multi-school`. TIMEZONE - All times are in Philippine Standard Time (UTC+8), HH:MM format. Convert from the user's local timezone before time-based filters. MCP RESOURCES (static guides — same idea as Figma MCP doc URIs: **resources/list** + **resources/read**) - `upsked://universities` — JSON: supported catalog schools (same shape as Public REST GET /universities). - `upsked://semesters` — JSON: semesters for one school + `default_semester_id` (defaults to **upd** when no args). - `upsked://docs/index` — Markdown: catalog of doc URIs + global conventions. - `upsked://docs/multi-school` — Markdown: **which school/semester when and why** (registry, `get_semesters` scoping, semester id shapes, UPD-only tools, public `/semesters` defaults). **Read this when the user names a school or pastes an unfamiliar semester id.** - `upsked://docs/planning-tools` — Markdown: **evaluate_schedule** vs **recommend_course_sections** vs **build_optimal_schedule**; **import_schedule** vs **search_courses**; rooms; saved schedule entry points. - `upsked://docs/schedule-versions` — Markdown: Schedule A–E / `version_id`, `get_my_schedule` behavior, **SCHEDULE DIVERSITY** across slots, auth. - Fetch these when tool descriptions are not enough or the user’s task spans multiple tools. SCHEDULE VERSIONS (Schedule A–E in the web app — use this whenever the user mentions plans A/B/C or “another draft”) - **You may and should use versioning.** Treat each `version_id` as a separate saved schedule for the same semester; operations on one do not erase others. - Each slot is a row in `user_schedules` keyed by `(semester_id, version_id)`. **Upsked exposes exactly five slots per semester:** `version_id` strings `"1"`–`"5"` (Schedule A–E in the web UI). Default display names: `"1"` → A, `"2"` → B, … `"5"` → E, unless the user renamed the version (`version_name`). - Tools that accept `version_id` (**pass it deliberately**): `get_my_schedule`, `add_section_to_schedule`, `remove_section_from_schedule`, `set_schedule_sections`, `add_sections_to_schedule`, `clear_schedule`, `swap_section`, `build_optimal_schedule` (always set `version_id` before `apply: true`). Async planner jobs, when your host exposes them, carry the same `version_id` in the job payload; applying the completed run updates that slot only. - `get_my_schedule` with `semester_id` omitted reads the caller's saved schedules across semesters/schools. With neither `version_id` nor `include_all_versions`, it returns only the single most recently updated saved version overall. Pass `semester_id` to scope to one semester, `version_id` to read a specific slot, or `include_all_versions: true` to list every matching saved version. If both `version_id` and `include_all_versions` are set, the query is still scoped to that `version_id` (you get at most one row). - There is no separate "create version" tool: the first write that **persists at least one section** for a **new** `version_id` (`set_schedule_sections`, `add_section_to_schedule`, `build_optimal_schedule` with `apply: true`, etc.) **inserts** that `user_schedules` row. Empty writes do not create a row. Other versions are untouched. - Planner dry-runs ignore saved drafts; persisting uses the `version_id` on `build_optimal_schedule` (`apply: true`) or the one bound to the async apply step for that run. SCHEDULE DIVERSITY (default when filling multiple slots A–E) - **Unless the user explicitly asks to copy the same plan to every slot** (“mirror”, “same on all versions”, “duplicate A to B–E”), **assume they want meaningfully different alternatives** across Schedule A–E (or any multiple `version_id`s). - `build_optimal_schedule` is **deterministic for fixed inputs**: same `course_ids`, semester, and flags → **one** optimal-feasible assignment. **`version_id` only chooses which row gets written**, not “give me another solution.” Calling it five times with identical args and `apply: true` on `"1"`…`"5"` **clones the same picks**—avoid that pattern when diversity is the goal. - **How to diversify:** (1) After a dry-run baseline, **vary** `prefer_morning` / `prefer_afternoon` / `prefer_friday_free`, `planning_mode`, day/time filters, or `vacant_windows` **per** `version_id` before persisting. (2) Persist the best plan to version `"1"`, then for each other slot call `recommend_course_sections` on that version’s current `section_ids` and use `swap_section` to take ranked alternatives for one or more courses (rotate which course you perturb so slots diverge). (3) If `get_my_schedule` with `include_all_versions: true` already shows different drafts, **extend those** instead of overwriting all slots with one composer run. ROUTING (three planning jobs + catalog; tool names are the registered MCP tool names) - (1) Analyze a known section_ids list: evaluate_schedule — primary. Returns conflicts, countable vs excluded units (PE/NSTP/CWTS/ROTC excluded from the 15-unit minimum), schedule spread, and draft_analysis (free windows, occupied days). It may widen the analyzed meeting footprint to linked block/common sections and exposes evaluated_section_ids + linked_block_section_ids when that happens. summarize_draft_schedule is a compatibility alias over the same engine; prefer evaluate_schedule for one payload. - (2) Rank sections for one course vs draft: recommend_course_sections — pass section_ids. Supports vacant_windows (hard/soft), strict_time_bounds with time_after/time_before, prefer_friday_free. Hard feasibility checks use each candidate's full meeting list plus block-linked section meetings (day/time filters only narrow which sections appear, not which meetings are validated). Defaults: open_only=true, avoid_conflicts=true. - (3) Multi-course composer: build_optimal_schedule — exact in-memory DFS over precomputed section bundles with bitset overlap checks; not greedy-by-request-order; **search is not parameterized by `version_id`** (see SCHEDULE DIVERSITY). apply defaults to false (dry-run). Set apply=true only to persist; requires auth when saving. **Pass `version_id` when persisting so picks land on Schedule A/B/… or another named slot, not only the last-edited draft.** Optional planning_mode: strict (force open_only+avoid_conflicts), balanced (use flags), salvage (allow closed sections and overlapping candidates). Returns unplanned_courses (with reason_code), underload, requested_min_countable_units (default 15), and unmet_planning_requirements when countable load is below min or courses could not be placed. planner_meta includes nodes_visited, search_budget_exhausted, search_status, planner_objective_score, objective_breakdown, decision_summary, planning_notes, candidate_widening_applied, relaxation_hints when unplanned. optimal_within_budget means the best schedule found before the node budget was exhausted. - Course discovery by keyword/code or GE/PE/NSTP browse: search_courses — not import_schedule. - User pasted CRS class codes (numeric strings): import_schedule — read-only resolver to section IDs; does not read or mutate the caller's saved Upsked schedule. - Full section list for one course_id: get_course_sections — raw catalog. - Saved schedule on the server: get_my_schedule — auth required. See SCHEDULE VERSIONS; pass version_id or include_all_versions when listing or targeting A–E. - Room name search (substring): search_rooms. Booked class meetings and optional derived free gaps: get_room_availability — include_free_slots defaults to true (larger payloads); set false if only booked rows are needed. - Replace all section IDs in one shot: set_schedule_sections. Swap one section on the saved version: swap_section (remove_section_id, add_section_id). MUTATIONS (all require auth; all accept optional `version_id` — **set `version_id` explicitly** when working with a specific Schedule A–E or a second draft) - add_section_to_schedule, remove_section_from_schedule, set_schedule_sections, add_sections_to_schedule, clear_schedule, swap_section — use swap_section instead of remove+add when replacing one section atomically. WORKFLOWS - Build from scratch: (1) build_optimal_schedule with course_ids and the target version_id (dry-run first, then apply=true to that version) — or — (2) clear_schedule on that version_id only, then recommend_course_sections per course, then set_schedule_sections with the final list and the same version_id. - Separate alternatives (e.g. Plan A vs Plan B): use version_id "1" vs "2"; do not rely on a single default row. **For several alternatives at once, follow SCHEDULE DIVERSITY**—do not repeat identical `build_optimal_schedule` applies across `version_id`s unless the user asked for the same plan everywhere. - Reschedule one course on the saved draft: swap_section (pass version_id for the slot).

Known tools 22

get_universities

List supported catalog schools (university_id, label, status, capabilities).

Inferred read-only
search_courses

Search Upsked catalog courses by code or keyword, with optional GE/PE/NSTP and open-only filters.

Inferred read-only
get_course_sections

Get sections, schedules, instructors, and block metadata for a course in a semester.

Inferred read-only
get_semesters

List Upsked semesters for one catalog school.

Inferred read-only
check_section_availability

Check slots_available, slots_total, demand, and overbooked status for one or more section IDs.

Inferred read-only
evaluate_schedule

Primary schedule analyzer for a fixed section_ids list: echoes requested section_ids; conflicts; countable_units / excluded_units / gross_units; meets_minimum_countable_load; underload (countable below 15); min_countable_units_for_viable; schedule spread; draft_analysis (free windows, occupied days, conflict detail); primary_schedule_analyzer=true.

Inferred read-only
get_my_schedule

Read saved schedule version(s).

Inferred read-only
add_section_to_schedule

Add a section to the caller's schedule version, or create a default version if none exists.

Potential side effects
remove_section_from_schedule

Remove a section from the caller's schedule version.

Potential side effects
set_schedule_sections

Replace the caller's schedule version with the given section IDs atomically.

Inferred read-only
add_sections_to_schedule

Append multiple sections to the caller's schedule version in a single atomic write.

Potential side effects
clear_schedule

Remove all sections from saved schedule row(s).

Potential side effects
swap_section

Atomically replace one section with another in the caller's schedule version.

Inferred read-only
get_room_availability

Get booked meetings for rooms in a semester, with optional free-slot computation.

Inferred read-only
search_rooms

Search unique room names that have scheduled classes in a semester.

Inferred read-only
get_instructor

Get instructor profile, ratings summary, taught courses, and matching sections for a semester.

Inferred read-only
import_schedule

Resolve CRS class codes into Upsked section IDs, courses, and section details for a semester.

Inferred read-only
get_course_section_changes

Read recent NEW, REVEALED, CHANGED, DISSOLVED, and UNDISSOLVED events from the materialized changes feed.

Inferred read-only
list_programs

List UP Diliman (UPD) degree programs as JSON from the CRS programs protobuf—optional college and degree-type filters.

Inferred read-only
recommend_course_sections

Search and rank concrete section fits against the provided draft section IDs.

Inferred read-only
summarize_draft_schedule

Compatibility alias: same engine as evaluate_schedule, returns draft-style fields plus academic_load and evaluate_schedule_cross_ref.

Inferred read-only
build_optimal_schedule

Bounded MRV branch-search planner: top-K ranked bundles per course (not exhaustive catalog search).

Inferred read-only

CONNECT WITH APPROVAL

Client installation

Review this server and its permissions before adding it. Secret placeholders must be set locally.

Codex

~/.codex/config.toml

[mcp_servers.upsked]
url = "https://upsked.com/api/mcp"
enabled = true
Claude Code

.mcp.json

{
  "mcpServers": {
    "upsked": {
      "type": "http",
      "url": "https://upsked.com/api/mcp"
    }
  }
}
Claude Desktop

Settings → Connectors → Add custom connector

Name: upsked
Remote MCP URL: https://upsked.com/api/mcp

Add this remote URL as a custom connector in Claude Desktop. Availability depends on the user plan and workspace policy.

Cursor

.cursor/mcp.json

{
  "mcpServers": {
    "upsked": {
      "url": "https://upsked.com/api/mcp"
    }
  }
}
Visual Studio Code

.vscode/mcp.json

Add to Visual Studio Code
{
  "servers": {
    "upsked": {
      "type": "http",
      "url": "https://upsked.com/api/mcp"
    }
  }
}
Generic MCP

Client-specific MCP configuration

{
  "name": "upsked",
  "transport": "streamable-http",
  "url": "https://upsked.com/api/mcp"
}
MCP Inspector

Run the official MCP Inspector locally and enter the indexed Streamable HTTP endpoint.

TRUST AND VERIFICATION EVIDENCE

Trust Data Available

BuiltWith Trust API v2 evidence for upsked.com was fetched 2026-09-12T06:32:12.297Z.

Trust status Trusted

upsked.com is assessed as Trusted: Domain has an established technology history spanning over a year.

Indexed

Evidence is source-attributed and does not guarantee that a third-party server is safe. Risk labels are conservative metadata heuristics.