ntnu-api
Click on "Install 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., "@ntnu-apisearch courses for objektorientert in 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.
ntnu-api
TypeScript client for NTNU course data. Wraps the three public, no-auth data sources for course information at the Norwegian University of Science and Technology behind one typed interface. Fetch-based with zero runtime dependencies — works in Node ≥ 20, Cloudflare Workers, browsers, and any other fetch-capable runtime.
Namespace | Data | Backing source |
| catalog search, per-course schedules & weekly timetables | ntnu.no course-page JSON (Liferay) |
| exam info (date, time, duration, aid code, rooms), fact box, descriptions, study programs | ntnu.no course-page HTML (scraped — no JSON upstream) |
| grade distributions per course/year/semester | HK-dir DBH statistics API |
| study-program catalog (~400 programs), per-cohort study plans (courses per semester, specializations) | ntnu.no program pages (Liferay JSON) |
| term ids ( | NTNU's TP timetable system |
See docs/api-research.md for the full survey of NTNU data sources (including the dead and auth-gated ones) and the exact upstream request shapes.
Usage
npm install ntnu-apiimport { NTNUClient } from "ntnu-api";
const client = new NTNUClient();
// Server-side course search (one 500-course page)
const page = await client.courses.search(2026, "objektorientert");
for (const hit of page.courses.slice(0, 3)) {
console.log(hit.courseCode, hit.courseName);
}
// Full catalog iteration (dedups the upstream's duplicate entries)
for await (const resultPage of client.courses.searchAll(2026)) {
// ...
}
// Dated teaching activities and the summarized weekly grid
const activities = await client.courses.schedules("TDT4100", 2026);
const grid = await client.courses.timetable("TDT4100", 2026);
// Everything else on the course page (HTML-only upstream, scraped):
// exams with start time/duration/hjelpemiddelkode/rooms, credits, level,
// descriptions, and the study programs the teaching is planned for —
// details.studyPrograms maps the studyProgramKeys on schedule/timetable
// entries to program names.
const details = await client.courses.details("TDT4100", 2026);
for (const exam of details?.exams ?? []) {
console.log(exam.occasion, exam.date, exam.time, exam.duration, exam.aidCode);
}
// Study programs: the catalog, and the full plan for a cohort
// (course codes+versions per semester, specialization choice points).
// planCourseCodes() flattens a plan to its course codes.
const programs = await client.programs.all();
const plan = await client.programs.studyPlan("MTDT", 2024);
// Grade distribution (accepts bare or DBH-versioned codes)
for (const row of await client.grades.distribution("TDT4100", { years: [2023] })) {
console.log(row.year, row.semesterName, row.grade, row.total);
}
// Terms as known by NTNU's timetable system
const current = await client.semesters.current();All errors derive from NTNUAPIError (with NotFoundError,
RateLimitError, APITimeoutError, ... subclasses). Transient failures
(429, 502–504, connection errors) are retried with exponential backoff,
honoring Retry-After. Upstream payloads are parsed into plain typed
objects; helpers like bestName() (trilingual name fallback) and
weekNumbers() (ISO-week range expansion) are exported alongside them.
A word of caution: the ntnu.no endpoints are NTNU's own internal AJAX surface, not a documented API — treat results accordingly and be polite (the client ships a descriptive User-Agent by default).
MCP server
The ntnu-mcp sibling repo hosts a
remote MCP server built on this package (Cloudflare Worker), exposing the
client as ten LLM-shaped tools — connect Claude or ChatGPT to
https://ntnu-mcp.martinsundal.no/mcp. Upstream fixes and new data sources
land here; the MCP repo only shapes typed data for LLMs.
Related MCP server: aula-mcp
Stack
TypeScript (strict), ESM-only, zero runtime dependencies
vitest — tests over captured live fixtures
Biome — linting + formatting
mise — pins Node and exposes task shortcuts
Dev Container — reproducible environment
Development
mise install # pinned Node
npm installTask | Command |
|
|
|
|
|
|
|
|
|
|
| lint + typecheck + test |
The default test run is fully mocked (injected fetch) against real
captured payloads in tests/fixtures/. To also verify against the live
endpoints (drift check):
NTNU_API_LIVE=1 npm testReleases are tag-driven: npm version <patch|minor|major> && git push --follow-tags. The release workflow then
verifies the tag, runs the full check suite, publishes to npm (trusted
publishing with provenance — no token secrets), and creates the GitHub
Release with generated notes. The prepare script builds dist/, so
github:MartinSA04/ntnu-api installs also work between releases.
History
This library began as an async Python client (httpx + pydantic, with a CLI
and a stdio MCP server); it was ported 1:1 to TypeScript so one codebase
serves Node, Workers, and browsers, per
docs/ts-migration-spec.md. The final Python
state is preserved at the
python-final
tag.
Roadmap
MCP server exposing the client as tools → ntnu-mcp
Expose the remaining catalog search facets (campus, level, faculty/institute)
Course detail scraping (exams, description, credits, prerequisites — HTML-only upstream) →
courses.details()TP
emner.phpsemester catalog (English names, campus ids — see docs/api-research.md)TP iCal export as a secondary timetable source once semesters publish
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceMCP server for querying a university course catalog. Enables searching courses, checking prerequisites, and looking up instructors via natural language.
- Alicense-qualityAmaintenanceThis server enables MCP clients (LLMs) to access data from the Danish school platform Aula, such as messages, schedules, and child profiles, by authenticating via MitID and running locally.1033MIT
- Flicense-qualityCmaintenanceMCP server that exposes a university course catalog to LLMs, enabling course search, prerequisite lookup, instructor details, and department directory through natural language.
- Flicense-qualityBmaintenanceMCP server that aggregates department notices and provides structured answers to queries about courses, schedules, and academic dates via tool calling.
Related MCP Connectors
MCP server exposing the Backtest360 engine API as tools for AI agents.
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MartinSA04/ntnu-api'
If you have feedback or need assistance with the MCP directory API, please join our Discord server