aula-mcp
Provides integration with Home Assistant, enabling voice assistants and automations to access Aula data (school communications, schedules, etc.) via the MCP protocol.
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., "@aula-mcpshow my child's next week's schedule"
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.
aula-mcp
Hvad det her er — og hvad det ikke er:
aula-mcp er en server der sidder mellem en MCP-klient (LLM) og Aula — et interface, ikke meget mere. LLM'en er ikke en del af projektet. Du vælger selv klient (Claude Code, Claude Desktop, ChatGPT, Cursor, Ollama, LM Studio osv.), og den kører hvor den nu kører — i Anthropic/OpenAI's cloud, eller lokalt hvis du bruger Ollama el.lign.
Projektet er altså ikke en garanti for at børnenes data kun bliver lokalt. Om dataen forbliver lokal afhænger 100 % af hvilken klient du tilkobler — det er dit eget ansvar, ikke noget aula-mcp selv kan love.
⚠️ Brug det med omtanke
Hobby-eksperiment, ingen garantier. Det rør ved MitID og dine børns skoledata — kig koden igennem (eller få en udvikler-bekendt til det) før du kobler en LLM på. Eget ansvar.
⚠️ Det er klienten der får dataen at se — ikke serveren
Serveren her kører lokalt og sender intet videre på egen hånd. Men den MCP-klient du tilkobler — Claude, ChatGPT, en anden cloud-LLM — får alt det den læser sendt videre til provideren (Anthropic, OpenAI osv.) for at kunne svare dig. Det er ikke "alt sammen lokalt" bare fordi serveren er det. Sådan fungerer MCP: klienten ræsonnerer, serveren henter data.
Hvor det går hen
MitID-credentials og OAuth-tokens
Forbliver lokalt — macOS Keychain eller AES-256-GCM-krypteret fil. Bruges kun til at hente data fra Aula.
Selve dataen (beskeder, ugeplaner, børnenavne osv.)
Sendes til den MCP-klient du vælger. Cloud-LLM → providerens servers (typisk USA). Lokal LLM → forbliver lokalt.
Vil du have det 100 % lokalt? Brug en lokal LLM som klient: Ollama, LM Studio, llama.cpp, Mistral via Hugging Face, etc. Alle taler MCP og kører på din egen hardware.
TypeScript + Bun + Hono. Bygget på skuldrene af scaarup/aula (Python/Home Assistant). Stadig i bevægelse — tools kan ændre signatur, kommandoer kan blive omdøbt, og enkelte vendor-integrationer er kun testet mod ét sæt skoler.

Indhold
Hvad serveren rør ved
Hvad selve aula-mcp-serveren gør (og ikke gør). Hvor dataen ender bagefter er klientens domæne — se disclaimeren øverst.
MitID-credentials og OAuth-tokens bliver lokalt. macOS: Keychain (
securityCLI). Linux/Windows: AES-256-GCM-krypteret fil i~/.config/aula-mcp/. De forlader ikke din computer.Serveren binder kun til
127.0.0.1. Den nægter at binde til en ikke-loopback adresse medmindre du sætterAULA_MCP_ALLOW_REMOTE=1. Default: kun programmer på din egen computer kan ramme den.Ingen telemetri, ingen tredjepart. Programmet taler kun med Aula's egne servere (
api.aula.dk,login.aula.dk), MitID (nemlog-in.mitid.dk) og vendor-API'erne (EasyIQ, Meebook m.fl. — hvis din skole har dem).MitID-godkendelsen går igennem MitID's egen infrastruktur. Protokollen er skrevet om i TypeScript, men selve godkendelsen (QR-koden i MitID-appen) sker som altid mellem din enhed og nemlog-in.dk.
--debug-tracen er opt-in og automatisk redaktet. Cookies, OAuth-koder, MitID-payloads, M1-værdier, flowValueProof, adgangstokens osv. fjernes før noget skrives til disk. Trygt at vedhæfte en GitHub-issue.Loopback-only = familien kan ikke ramme serveren fra deres egen enhed. Skal flere enheder i husstanden kunne spørge, så enten reverse proxy (se Self-hosting) eller en Home Assistant-integration på et tidspunkt.
Kom i gang
Kræver Bun ≥ 1.3 og pnpm ≥ 10. macOS eller Linux.
git clone git@github.com:Casperjuel/aula-mcp.git
cd aula-mcp
pnpm install
# 1. Sanity-tjek
pnpm typecheck && pnpm lint && pnpm test
# 2. Første-gangs MitID-login (QR-kode i MitID-appen)
pnpm login
# 3. Health-check af alle Aula-endpoints
pnpm doctor
# 4. Start MCP-serveren (http://127.0.0.1:7878/mcp)
pnpm mcpDe fleste CLI-kommandoer har en kort genvej: pnpm login, pnpm doctor, pnpm whoami, pnpm status, pnpm logout. Til alt andet videresender pnpm aula <kommando> til CLI'en (fx pnpm aula transcript list, pnpm aula log --last 5).
doctor-kommandoen kører hvert read-endpoint igennem og rapporterer status + svartid for hvert. Det er det hurtigste "virker det her overhovedet?"-tjek:

whoami viser hvilken identitet dine tokens hører til, og hvilke børn der returneres af getProfilesByLogin:

Forbind til Claude Code (eller claude.ai)
Claude Code
# 1. Server kører i ét terminalvindue
pnpm mcp
# 2. Registrér serveren med Claude Code (kun én gang)
claude mcp add --transport http aula http://127.0.0.1:7878/mcp
# 3. I en hvilken som helst Claude Code-session, bekræft at den er forbundet
/mcpSå kan du bare spørge naturligt — børnenes navne bliver fuzzy-matched mod discover-manifestet, du behøver ikke kende deres ID:
hvad står der på ugeplanen næste uge for theo
Claude kalder aula.discover én gang, vælger den rigtige ugeplan-vendor for din skole ud fra detectedWidgets, og svarer på dansk med dansk-formatterede datoer.
Claude Desktop
Drop snippet'et fra examples/claude-config/claude-desktop.json ind i ~/Library/Application Support/Claude/claude_desktop_config.json.
claude.ai (web)
Web-UI'et kræver en offentlig HTTPS-URL — 127.0.0.1 virker ikke, fordi forbindelsen sker server-side fra Anthropic's cloud. Til en hurtig test:
cloudflared tunnel --url http://127.0.0.1:7878
# → https://<random>.trycloudflare.com — indsæt med `/mcp` på enden⚠️ Tunnel-URL'en er offentligt tilgængelig så længe den kører — hvis nogen gætter den, kan de styre dine Aula-tokens. Fint til en hurtig demo, men lad den ikke stå åben. Til en permanent setup, se næste sektion.
Self-hosting
Hvis du vil have serveren kørende uden at have din laptop åben, er der et par måder. Alle holder serveren lokalt — hvor klienten kører er stadig et separat valg (se top-disclaimeren).
Mulighed 1: Single binary på en Linux-boks (Pi, NAS, gammel laptop, billig VPS)
Den simpleste vej. Compile-til-én-binary og kør den under systemd.
# Byg en standalone binary (~50 MB)
bun build --compile --outfile dist/aula-mcp packages/mcp-server/src/server.ts
# Kopiér til din server (Pi, NAS, VPS)
scp dist/aula-mcp aula:/usr/local/bin/aula-mcpTokens på serveren — to veje, vælg den der passer dig:
A. Log ind direkte på serveren via SSH. QR-koderne renderes i SSH-sessionen, scan med MitID-appen på telefonen. Kører på enhver maskine du kan ssh'e ind på med en normal TTY.
ssh aula
aula loginB. Eksportér tokens fra din Mac (eller fra hvor du allerede er logget ind). macOS Keychain kan ikke flyttes mellem maskiner, så aula tokens export re-krypterer dem til en bærbar fil-bundle.
# På din Mac
aula tokens export ~/aula-bundle
# Flyt til serveren — bundle indeholder live credentials, behandl som
# adgangskoder. SSH krypterer i transit.
scp ~/aula-bundle/tokens.json ~/aula-bundle/.key \
aula:/var/lib/aula-mcp/
# Slet bundle på din Mac når du er færdig
rm -rf ~/aula-bundleEller på serveren: aula tokens import ~/aula-bundle hvis du vil have CLI'en til at lægge filerne det rigtige sted.
Eksempel systemd-unit i /etc/systemd/system/aula-mcp.service:
[Unit]
Description=aula-mcp server
After=network.target
[Service]
Type=simple
User=aula
ExecStart=/usr/local/bin/aula-mcp
Environment=AULA_MCP_PORT=7878
Environment=AULA_MCP_HOST=127.0.0.1
Environment=AULA_MCP_DIR=/var/lib/aula-mcp
Environment=AULA_MCP_KEY=<en lang hex-streng eller passphrase>
Restart=on-failure
[Install]
WantedBy=multi-user.targetAktivér med systemctl enable --now aula-mcp. Tjek journalctl -u aula-mcp -f for logs.
Mulighed 2: Bag en authenticeret reverse proxy (familien tilgår fra mobilen)
Default binder serveren kun til 127.0.0.1. For at familien (eller dig selv på telefonen via VPN) skal kunne ramme den, sæt en reverse proxy foran med authentication. Eksempel med Caddy:
aula.dithjem.dk {
basicauth {
familie $2a$14$<bcrypt-hash>
}
reverse_proxy 127.0.0.1:7878
}AULA_MCP_HOST forbliver 127.0.0.1 — Caddy står for TLS, basic auth, rate limit. Det er Caddy der er på det offentlige internet, ikke selve MCP-serveren.
⚠️ Hvis du skal exposé serveren direkte (springe proxy-laget over) skal du eksplicit sætte
AULA_MCP_ALLOW_REMOTE=1— det er en kontrolleret, tilsigtet handling, ikke et uheld.
Mulighed 3: Home Assistant add-on
Den nemmeste vej for HA-brugere. Add-on'en pakker aula-mcp ind så den kører som en del af din HA-installation og er tilgængelig fra HA's Voice/Assist + alle dine HA-automatiseringer. Hvis du har Nabu Casa, åbner det også for sikker fjernadgang via deres tunnel.
👉 Fuld guide: docs/home-assistant.md — installation, MitID-login, MCP-integration, valg af LLM, og stemmeopsætning.
Korte stik:
Et-klik install:
aula-mcptaler både Streamable HTTP (/mcp) og den ældre SSE-dialekt (/sse) — HA's officiellemcp(client) integration bruger SSE.Login sker inde i add-on'ens egen sidebar-UI (MitID-QR + identitetsvalg).
Mulighed 4: VPS i Tyskland (Hetzner, Coolify)
Hvis du allerede har en europæisk VPS (Hetzner, Scaleway, OVH) og en domæne — så er det bare en git clone + bun install + systemd-unit som mulighed 1.
Backup & nøgle-håndtering
Token-store: gem en kryptert kopi af
~/.config/aula-mcp/tokens.json+.key(eller Keychain-eksport på macOS). Mister du dem, skal du logge ind igen — ingen panik, men irriterende.AULA_MCP_KEY: hvis du bruger fil-backenden i produktion, sæt en stærk
AULA_MCP_KEY(env-var) og lad være med at committe den. Roterer du den, skal du re-loginne.Nye Aula-versioner: Aula bumper deres API-version 1-2 gange om året.
aula-mcpprober selv den nye version ved næste kald (intet manuelt arbejde), men hold et øje på release-noter for breaking changes der dukker op.
Hvad er der i manifestet
Agenter kalder aula.discover én gang og genbruger resultatet resten af sessionen. Manifestet fortæller agenten hvem brugeren er, hvilke børn man kan handle på vegne af, hvilke tredjeparts-widgets skolerne har konfigureret, og hvilke MCP-tools der skal kaldes:

Form:
{
user: { name, username, identityName? },
children: [{ id, name, userId?, institution: { id, name?, code? } }],
apiVersion: 23,
tokens: { expires_at, seconds_remaining },
detectedWidgets: ['0001', '0029', '0030'], // fra Aula's pageConfiguration
capabilities: {
profiles: { summary, tools: ['aula.profiles.list'] },
presence: { summary, tools: ['aula.presence.today', 'aula.presence.templates'] },
calendar: { summary, tools: ['aula.calendar.events'] },
messages: { summary, tools: ['aula.messages.list_threads', 'aula.messages.get_thread'] },
notifications: { summary, tools: ['aula.notifications.list'] },
posts: { summary, tools: ['aula.posts.list'] },
ugeplan: { summary, tools: ['aula.ugeplan.easyiq'] }, // kun den detekterede vendor
opgaver: { summary, tools: ['aula.opgaver.minuddannelse'] },
ugebrev: { summary, tools: ['aula.ugebrev.minuddannelse'] },
huskelisten: { summary, tools: ['aula.huskelisten.systematic'] }
},
usage: {
cache, nameResolution, pickOne, timeWindows, language
},
rawRequestEnabled: false,
writeEnabled: false
}capabilities[area].tools[0] er altid det rigtige tool at kalde — når en skoles widgets detekteres, listes kun den matchende vendor, så agenten ikke famler ud over flere providers. Det inline usage-blok fortæller agenten hvordan den skal opføre sig (cache manifestet, fuzzy-match børnenavne, default til Europe/Copenhagen, svar på brugerens sprog).
Komme/gå — sæt afleverings- og hentetider
aula-mcp er read-only som standard. Sætter du AULA_MCP_WRITE=1, registreres ét ekstra tool — aula.presence.set_template — der kan oprette eller overskrive et barns komme/gå-skabelon for én dag: afleveringstid, hentetid, henteform (picked_up_by "Hentes af", self_decider "Selvbestemmer", send_home "Sendes hjem", go_home_with "Går hjem med") og evt. en ugentlig gentagelse. Læse-toolet aula.presence.templates viser den nuværende plan og er altid slået til. Skrive-toolet rører rigtige data i Aula, så det sidder bevidst bag et flag — en agent skal ikke kunne omlægge dit barns hentetid uden at du har slået det til. writeEnabled i manifestet afspejler om flaget er sat.
CLI-kommandoer
aula login [--username <user>] [--method APP|CODE_TOKEN] [--debug] [--transcript <file>]
aula status [--json]
aula whoami [--json]
aula doctor [--json] [--verbose]
aula log [--last N] [--json]
aula transcript {list|view <file>|prune} [--json] [--keep N] [--dry-run]
aula logout
aula --helpKommando | Hvad den gør |
| Kører hele MitID-flowet (APP-metoden er default — scan QR med MitID-appen). Gemmer tokens. |
| Viser om der er tokens, deres udløbstid og den aktive identitet. Kontakter ikke netværket. Exit-kode 1 hvis der ingen tokens er. |
| Indlæser tokens (refresher hvis nødvendigt), kalder |
| Kører hvert read-endpoint igennem og rapporterer per-call status med svartid. Det hurtigste "virker det her?"-tjek. |
| Seneste login-forsøg (success/failure, timestamps, fejlklasse). |
| Inspicér opfangede |
| Sletter de gemte tokens. Krypteringsnøglen beholdes så næste login genbruger den. |
Komplet hjælp med eksempler: pnpm aula --help

Konfiguration
Hvor tokens gemmes
Platform | Default | Override | |
macOS | Keychain ( |
| |
Linux / Windows | AES-256-GCM-krypteret fil i | `AULA_MCP_KEY=<hex | passphrase> |
Server-miljøvariabler
Variabel | Default | Effekt |
|
| Bind-port. |
|
| Bind-interface. Nægter ikke-loopback medmindre |
|
| Konfig-mappe (fil-backend + transcripts + login-log). |
| off | Aktiverer |
| off | Aktiverer skrive-tools ( |
| off | Verbose console-logs fra auth/client-lagene. |
| off | Tillader at binde til ikke-loopback adresser (fx bag en reverse proxy). |
Wire-transcripts
--debug-tilstand tee'r en JSONL-transcript af hvert HTTP-request/response til ~/.config/aula-mcp/transcripts/login-<timestamp>.jsonl. Cookies, OAuth/SAML-payloads, MitID-auth-koder, adgangskoder, M1, flowValueProof, access_token-query-parameter og andre hemmelige felter bliver alle redaktet (<redacted N chars>). Transcripten kan trygt vedhæftes en GitHub-issue.
aula transcript view <file> pretty-printer en af dem.
Arkitektur
packages/
aula-auth/ — MitID + 3072-bit SRP-6a + OAuth/SAML-kæde + token-store + wire-trace
aula-client/ — Aula REST API + version-probing + integrations-plugins
mcp-server/ — Hono + @modelcontextprotocol/sdk + aula.discover + 11 capability-tools
apps/
cli/ — aula login/status/whoami/doctor/log/transcript/logoutCross-package-imports bruger workspace-navnet (@aula-mcp/aula-auth); Bun resolver .ts direkte, så der er intet build-trin i dev. tsc -p tsconfig.json --noEmit kører i CI til ren type-checking.
Lag | Status | Noter |
| ✅ unit-testet + live-verificeret | MitID APP + CODE_TOKEN + PASSWORD; macOS Keychain eller AES-GCM-fil. |
| ✅ unit-testet | Native Aula API + EasyIQ / EasyIQ SkolePortal / Meebook / Min Uddannelse / Systematic-plugins. |
| ✅ unit-testet + live-verificeret med Claude Code | Streamable HTTP-transport, stateful session. Single-user, loopback by default. |
| ✅ unit-testet | QR-rendering, debug-transcripts, JSONL login-log. |
@aula-mcp/aula-auth og @aula-mcp/aula-client bruger kun Web-standarder + node:crypto + node:child_process — de kører på Node ≥ 20 såvel som Bun. MCP-serveren bruger Bun.serve og er Bun-only. CLI'en bruger Bun's TS-support og shipper via bun build --compile. For at bruge libraries fra et Node-script, se examples/script/.
Detaljeret design-rationale: docs/architecture.md.
Rettelser fra Aula-issues
Et par issues fra scaarup/aulas tracker som jeg har taget højde for:
Upstream issue / PR | Hvad koden gør |
#311 — sensor dør når widget-JWT'en udløber |
|
#246, #248 — Aula API-version drifter (v22 → v23 mid-life) |
|
#310 — RelayState mangler i Level-3 SAML-svar |
|
#306, #287 — |
|
#290, #351 — |
|
PR #352 — EasyIQ SkolePortal (widget 0128) | Implementeret som |
Følsomme beskeder ( | Surfaced som typed |
Fejlfinding
Symptom | Sandsynlig årsag / fix |
| MitID-appen er ikke åbnet endnu, eller QR-koderne er ikke renderet (terminal for smal). Sørg for at terminalen er ≥ 80 kolonner. |
| nemlog-in.mitid.dk er ikke tilgængelig eller returnerede en fejl. Kør igen med |
| MitID-appen afviste eller annullerede. Tjek at MitID-appen er logget ind på din konto. |
| Sjælden — MitID afviste SRP-proof'et. Kør igen med |
| En specifik tråd er følsom (Aula returnerer 403). Kør |
| API-versionen er bumpet. Kør |
| Tokens er udløbet siden sidste brug. Et hvilket som helst read-kald (eller |
MCP-server: | Du har sat |
Når noget fejler er JSONL-transcripten i ~/.config/aula-mcp/transcripts/login-<timestamp>.jsonl (efter --debug) det første sted at kigge. aula transcript view <file> pretty-printer den.
Udvikling
pnpm install # installér alt
pnpm typecheck # tsc -p tsconfig.json --noEmit
pnpm lint # biome check .
pnpm lint:fix # biome check --write .
pnpm test # bun:test-suiterne (248 cases)
pnpm test:watch # re-run ved ændringAlle andre top-level-scripts: pnpm aula <cmd>, pnpm mcp, plus per-kommando-genvejene (pnpm login, pnpm doctor, pnpm whoami, pnpm status, pnpm logout).
Bidrag
Se CONTRIBUTING.md for repo-layout, konventioner og en guide til at tilføje integrations-plugins. Bidragydere accepterer at følge Code of Conduct. Sikkerhedsproblemer: skriv venligst til info@casperjuel.dk i stedet for at åbne en offentlig issue — se SECURITY.md.
Privatliv & jura
MitID-credentials og OAuth-tokens bliver på din maskine. Serveren binder kun til localhost som default. Ingen telemetri. Wire-tracen er opt-in (--debug) og hvert kendt-hemmeligt felt redaktes inden noget skrives til disk.
Selve dataen (beskeder, ugeplaner, børnenavne osv.) går videre til den MCP-klient du tilkobler. Hvor klienten sender den hen er klientens sag, ikke serverens — se top-disclaimeren.
Brug projektet til dine egne børns data — log ind som dig selv med din egen MitID; brug det ikke til at tilgå nogen andens konto.
Forbehold. Dette projekt er ikke tilknyttet, godkendt af eller sponsoreret af KMD A/S, Netcompany A/S eller Aula-konsortiet. Aula er et varemærke tilhørende sin respektive ejer; navnet bruges her udelukkende til at identificere hvad denne software taler med.
Licens
MIT.
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.
Latest Blog Posts
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/Casperjuel/aula-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server