Ida-Untis

Ida-Untis

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

Category
访问服务器

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.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选