NTNU Course Data API, MCP Server & Timetable
Built to be able to ask Claude when the exams are. A typed client over NTNU's three course-data systems, with an MCP server and a timetable on top.
Why it exists
To be able to ask Claude about the schedule. That is the whole reason.
NTNU’s course data is public but not in a state to be looked up: three systems
that were never introduced to each other and agree on nothing, including how a
course is identified. Exam logistics are not data in any of them — they are
published on the course page as HTML. So ntnu-api turns the sources into one
thing to query, and ntnu-mcp puts that where a model can reach it.
The client
TypeScript over fetch with nothing underneath it. One build has to run in
Node, in a browser tab and inside Cloudflare’s runtime, so it carries no
dependencies at all.
| Namespace | Data | Source |
|---|---|---|
courses | catalog search, schedules, weekly timetables | ntnu.no JSON |
courses.details | exams, fact box, descriptions, programs | ntnu.no HTML, scraped |
grades | grade distribution per course, year, semester | HK-dir DBH |
programs | ~400 study programs, per-cohort study plans | ntnu.no JSON |
semesters | term ids, teaching weeks, exam periods | TP |
The work is in the seams. Exam information is scraped and typed on the way out.
Catalog search hands back the same course twice. Grade lookups want TDT4100-1
where the rest of NTNU says TDT4100.
The MCP server
Twelve read-only tools on a Cloudflare Worker, over Streamable HTTP, no key.
Two of them do something the catalog will not: compare_courses puts
candidates side by side, and check_timetable_conflicts finds clashing
lectures and colliding exams, separating lecture against lecture — fatal — from
a clash with an exercise group that usually has another slot going.
The console
A real MCP client in eighty lines of fetch, with no model behind it. That is
why it asks in fill-in-the-blank sentences: the sentence chooses the tool and
the blanks are the arguments. Put your own codes in and the call is the one
Claude would make.
The timetable
Semesterplan, at ntnu.martinsundal.no, is the other thing built on the
client. Pick a study programme and a cohort and the week comes back, rooms and
exam dates included. NTNU auto-enrolls programme students in their courses, so
the programme is the plan rather than a suggestion to confirm; a course comes
off it in one press.
An Astro build and a Cloudflare Worker ship as one unit. The Worker serves the
site and caches /api/* in front of NTNU per data type — six hours for course
details, one hour for timetables. There is no account, and nothing about a
student leaves the browser it was typed into.
- Endpoint
https://ntnu-mcp.martinsundal.no/mcp- Claude
- Settings, then Connectors, then Add custom connector. Paste the endpoint. There is no key to enter.
- Claude Code
claude mcp add --transport http ntnu https://ntnu-mcp.martinsundal.no/mcp
- Anything else
{ "mcpServers": { "ntnu": { "type": "http", "url": "https://ntnu-mcp.martinsundal.no/mcp" } } }
- Package
- ntnu-api on npm
- Runtime deps
- Zero
- Runs in
- Node 20+ · Workers · browsers
- MCP tools
- 12, all read-only
- Registry
- io.github.MartinSA04/ntnu-mcp
- Timetable
- ntnu.martinsundal.no