AulaSAFE
MCP server for Denmark's Aula school platform — TypeScript MitID auth, no headless browser. Exposes profiles, calendar, messages, ugeplaner to AI agents (Claude/Cursor/etc) via Model Context Protocol.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://github.com/Casperjuel/aula-mcp/actions) [](./LICENSE) [](https://bun.sh) [](https://pnpm.io) [](https://modelcontextprotocol.io) [](#udvikling)
*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
c6b2104ff031OBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mcp-server --env AULA_MCP_KEY=${AULA_MCP_KEY} --env AULA_MCP_NO_KEYCHAIN=${AULA_MCP_NO_KEYCHAIN} -- npx -y @aula-mcp/mcp-server{
"mcpServers": {
"mcp-server": {
"command": "npx",
"args": [
"-y",
"@aula-mcp/mcp-server"
],
"env": {
"AULA_MCP_KEY": "${AULA_MCP_KEY}",
"AULA_MCP_NO_KEYCHAIN": "${AULA_MCP_NO_KEYCHAIN}"
}
}
}
}Exposed tools (25)
24 read · 1 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
Matematik | read | Sider 12-15 |
aula.calendar.events | read | |
aula.discover | read | |
aula.huskelisten.systematic | read | |
aula.lektier.easyiq | read | |
aula.messages.get_attachment | read | |
aula.messages.get_thread | read | |
aula.messages.list_threads | read | |
aula.messages.mark_read | read | |
aula.notifications.list | read | |
aula.opgaver.minuddannelse | read | |
aula.posts.get_attachment | read | |
aula.posts.list | read | |
aula.presence.report_sick | read | |
aula.presence.set_template | write | |
aula.presence.templates | read | |
aula.presence.today | read | |
aula.profiles.list | read | |
aula.raw_request | read | |
aula.ugebrev.minuddannelse | read | |
aula.ugeplan.easyiq | read | |
aula.ugeplan.easyiq_skoleportal | read | |
aula.ugeplan.meebook | read | |
aula.utils.extract_pdf_text | read | |
echo | read |
Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (1 observation(s))
- Network
- declared (5 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (17)
.release-please-manifest.json
Before filing: if this is a token-handling or MitID-flow vulnerability, do **not** open a public issue — see [SECURITY.md](../../SECURITY.md).
{ file: { name: '../../etc/pas swd.pdf', url: 'https://cdn.test/c' } },expect(out.filename).toBe('../../etc/pas swd.pdf');# 4. Start MCP-serveren (http://127.0.0.1:7878/mcp)
claude mcp add --transport http aula http://127.0.0.1:7878/mcp
cloudflared tunnel --url http://127.0.0.1:7878
hostname): brug HA's IP-adresse, fx `http://192.168.1.50:7878/sse`.
The MCP server ships two transports. **Streamable HTTP** listens on `http://127.0.0.1:7878/mcp` by default and suits setups where the server runs somewhere other than the client (Home Assistant, a Pi,
'12a4c4852c2b41cd9e3e456df7b79ba4e8296b35afd9614da9784c0af98776bb229da72acf6f7c3ccce1332aaed44d68aa0013ce76046dc581b039923f318c877fd63654e25539d507000b568d51fa25944179fa920ba96754464d9c05208ec76b6bacd
qrcode-terminal, @types/qrcode-terminal
@biomejs/biome, @types/bun, @types/node, bun-types, typescript
cheerio, tough-cookie
@modelcontextprotocol/sdk, hono, pdf-parse, qrcode, zod, @types/qrcode
Email **[email protected]** privately. Do **not** open a public GitHub issue for anything that touches token handling, the MitID flow, or wire-trace sanitisation — wait until a fix is shipped.
1. an explicit `Buffer` passed to the constructor — strongest, intended for callers that read from a system keychain,
- **Composability.** A caller _can_ already read from the keychain themselves and pass the result via option 1. We aren't blocking that path; we're just not bundling a keychain dependency.
Gates applied: no_behavioural_pass.
c6b2104ff031full audit observations/trust-audit/mcp-server/casperjuel__aula.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | c6b2104ff031 | SAFE | B | 89 | first audit |
Questions
What is the Aula MCP server?
MCP server for Denmark's Aula school platform — TypeScript MitID auth, no headless browser. Exposes profiles, calendar, messages, ugeplaner to AI agents (Claude/Cursor/etc) via Model Context Protocol.
What tools does Aula expose?
25 in total: 24 read-only, 1 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is Aula safe to connect to an agent?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B.
What credentials does Aula need?
It reads AULA_MCP_KEY and AULA_MCP_NO_KEYCHAIN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Aula run?
It speaks sse, stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as @aula-mcp/mcp-server.
How current is this page?
The grade is for one exact copy of the source (c6b2104ff031), read on 2026-10-08. The repository is watched and re-audited when it changes.