Ida-Untis

Ida-Untis

MCP server for accessing WebUntis timetable data, providing tools to query timetables, absences, and substitutions for a configured class.

Category
Visit Server

README

Ida-Untis

Ein MCP-Server (Model Context Protocol), der WebUntis-Stundenplandaten für Claude bereitstellt: ausgefallene Stunden, Vertretungen, Raum-/Lehrerwechsel, Klassen, Lehrer, Räume, Fächer und Ferien. Läuft als Docker-Container und wird über einen bestehenden Cloudflare Tunnel unter einer eigenen Domain erreichbar gemacht.

Architektur

Claude  --https-->  Cloudflare Tunnel (öffentliche Domain)
                            |
                            v
                 127.0.0.1:8000 auf deinem Server
                            |
                            v
                 Docker-Container "ida-untis-mcp"
                            |
                            v
                      WebUntis JSON-API

Der Container published seinen Port nur auf 127.0.0.1 -- er ist von außen nicht direkt erreichbar, sondern nur über den bereits auf dem Server laufenden cloudflared-Prozess. Zusätzlich verlangt der Server bei jeder Anfrage ein geheimes Token (MCP_AUTH_TOKEN). Beides zusammen sorgt dafür, dass nicht "jeder" an die Domain kommt, selbst wenn die Domain bekannt ist.

Voraussetzungen

  • Docker + Docker Compose auf dem Server
  • Ein bereits eingerichteter und verbundener Cloudflare Tunnel auf diesem Server
  • Ein WebUntis-Zugang (Schüler-, Eltern- oder Lehrer-Login)
  • Ein GitHub-Repo namens Ida-Untis (dieses hier) mit Actions aktiviert

1. Einrichten

git clone https://github.com/<dein-user>/Ida-Untis.git
cd Ida-Untis
cp .env.example .env

.env ausfüllen:

Variable Bedeutung
UNTIS_SERVER Nur der Host, z.B. nessa.webuntis.com (aus der Browser-URL, wenn in WebUntis eingeloggt)
UNTIS_SCHOOL Schulname/-kürzel wie bei der Schulauswahl in WebUntis
UNTIS_USERNAME / UNTIS_PASSWORD Normaler WebUntis-Login
UNTIS_KLASSE Kürzel der einen Klasse, auf die der Server fest eingestellt ist (z.B. 1T) -- alle Tools liefern ausschließlich Daten dieser Klasse
MCP_AUTH_TOKEN Langes Zufalls-Token, das Claude beim Verbinden mitschicken muss. Erzeugen mit openssl rand -hex 32
MCP_PORT Lokaler Port (Standard 8000)
GITHUB_OWNER Dein GitHub-Benutzername in Kleinbuchstaben (für das Image aus GHCR)

.env bleibt lokal auf dem Server und wird nicht committet (steht in .gitignore).

2. Image bauen lassen (GitHub Actions)

Bei jedem Push auf main baut .github/workflows/docker-publish.yml das Docker-Image automatisch und veröffentlicht es nach ghcr.io/<dein-user>/ida-untis:latest.

Damit docker compose das Image ohne Login ziehen kann, muss das Package beim ersten Mal auf öffentlich gestellt werden: GitHub -> dein Profil -> Packages -> ida-untis -> Package settings -> Change visibility -> Public.

Alternativ (wenn privat bleiben soll): auf dem Server einmalig docker login ghcr.io -u <dein-user> mit einem Personal Access Token (Scope read:packages) ausführen.

3. Starten

docker compose pull
docker compose up -d
docker compose logs -f

Der Healthcheck prüft http://127.0.0.1:8000/healthz. Mit docker compose ps sollte der Container als healthy erscheinen.

4. An den bestehenden Cloudflare Tunnel anbinden

Kein neuer Tunnel nötig -- nur eine zusätzliche Ingress-Regel im bestehenden Tunnel, die auf den lokalen Port zeigt.

Dashboard (Zero Trust -> Networks -> Tunnels -> dein Tunnel -> Public Hostname):

  • Hostname: z.B. untis.deine-domain.de
  • Service: http://localhost:8000

Oder per config.yml, falls du den Tunnel so verwaltest:

ingress:
  - hostname: untis.deine-domain.de
    service: http://localhost:8000
  - service: http_status:404

Danach cloudflared neu laden bzw. den Tunnel-Dienst neu starten, damit die neue Ingress-Regel greift.

Optional für eine zusätzliche Sicherheitsebene: Die Hostname per Cloudflare Access (Zero Trust) zusätzlich auf bestimmte E-Mail-Adressen oder ein Service-Token einschränken -- dann muss man sowohl an Cloudflare Access als auch am MCP_AUTH_TOKEN vorbei.

5. Mit Claude verbinden

Der MCP-Endpunkt liegt unter https://untis.deine-domain.de/mcp (Streamable HTTP). Das Token kann auf drei Arten mitgeschickt werden -- je nachdem, was der jeweilige Claude-Client unterstützt:

  • Header Authorization: Bearer <MCP_AUTH_TOKEN>
  • Header X-API-Key: <MCP_AUTH_TOKEN>
  • Query-Parameter ?token=<MCP_AUTH_TOKEN> (falls der Client nur eine reine URL akzeptiert, z.B. manche Custom-Connector-UIs)

Claude Code CLI:

claude mcp add --transport http ida-untis \
  https://untis.deine-domain.de/mcp \
  --header "Authorization: Bearer <MCP_AUTH_TOKEN>"

claude.ai / Claude Desktop (Custom Connector): Einstellungen -> Connectors -> Add custom connector -> URL eintragen. Falls dort kein Header konfigurierbar ist, die Token-Variante als Query-Parameter verwenden: https://untis.deine-domain.de/mcp?token=<MCP_AUTH_TOKEN>.

Verfügbare Tools

stundenplan, ausfaelle, aenderungen und vertretungen sind fest auf die in UNTIS_KLASSE konfigurierte Klasse eingestellt -- es gibt keinen Parameter, um eine andere Klasse abzufragen. Das ist bewusst so (Scope-Lock auf eine Klasse) und umgeht nebenbei auch ein WebUntis-Problem: manche Accounts haben für die generische "eigener Stundenplan"-Abfrage keine Berechtigung (Fehler no right for timetable), der Klassen-Stundenplan funktioniert aber unabhängig davon.

Tool Zweck
stundenplan(von, bis) Kompletter Stundenplan der konfigurierten Klasse im Zeitraum
ausfaelle(von, bis) Nur ausgefallene Stunden
aenderungen(von, bis) Nur geänderte Stunden (Raum-/Lehrerwechsel)
vertretungen(von, bis) Vertretungen, gefiltert auf die konfigurierte Klasse
klassen_liste() Alle Klassen der Schule (nur Namen/IDs, keine Stundenplandaten)
lehrer_liste() Kürzel aller Lehrkräfte der Schule (keine vollen Namen, Datenschutz)
raeume_liste() Alle Räume der Schule
faecher_liste() Alle Fächer der Schule
ferien_liste() Ferien/Feiertage

Datumsangaben immer als JJJJ-MM-TT, z.B. 2026-07-21.

Lokal testen ohne Cloudflare

docker compose up -d
curl -H "Authorization: Bearer $MCP_AUTH_TOKEN" http://127.0.0.1:8000/healthz

Troubleshooting

  • Container startet nicht / beendet sofort: docker compose logs prüfen -- meist fehlt eine Pflicht-Variable in .env (klare Fehlermeldung beim Start).
  • Login bei WebUntis schlägt fehl: UNTIS_SERVER/UNTIS_SCHOOL prüfen (Server nur als Host, ohne https://), Zugangsdaten in WebUntis selbst testen.
  • Claude bekommt 401: Token in der Client-Konfiguration und in .env vergleichen (Groß-/Kleinschreibung, keine Leerzeichen).
  • GHCR-Image lässt sich nicht pullen: Package-Sichtbarkeit prüfen (siehe Schritt 2) oder docker login ghcr.io auf dem Server ausführen.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured