Atlas / MCP servers / casperjuel / Aula

AulaSAFE

mcp/casperjuel/aula

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.

Verdict
SAFE
Grade
B
Trust score
89 /100
Exposed tools
25 24r · 1w · 0d
Transport
sse · stdio · streamable-http
License
MIT
Stars
62
01

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
Read from source at commit c6b2104ff031OBSERVED · 2026-10-08
02

Connect

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-code
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
claude-desktop
{
  "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}"
      }
    }
  }
}
03

Exposed tools (25)

24 read · 1 write · 0 destructive.

ToolRiskDescription
MatematikreadSider 12-15
aula.calendar.eventsread
aula.discoverread
aula.huskelisten.systematicread
aula.lektier.easyiqread
aula.messages.get_attachmentread
aula.messages.get_threadread
aula.messages.list_threadsread
aula.messages.mark_readread
aula.notifications.listread
aula.opgaver.minuddannelseread
aula.posts.get_attachmentread
aula.posts.listread
aula.presence.report_sickread
aula.presence.set_templatewrite
aula.presence.templatesread
aula.presence.todayread
aula.profiles.listread
aula.raw_requestread
aula.ugebrev.minuddannelseread
aula.ugeplan.easyiqread
aula.ugeplan.easyiq_skoleportalread
aula.ugeplan.meebookread
aula.utils.extract_pdf_textread
echoread
04

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.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codePASS
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (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)

LOWInventory / provenance · inv.hidden_file · CWE-1104
.release-please-manifest.json
.release-please-manifest.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
.github/ISSUE_TEMPLATE/bug_report.yml:9
Before filing: if this is a token-handling or MitID-flow vulnerability, do **not** open a public issue — see [SECURITY.md](../../SECURITY.md).
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/mcp-server/src/server.test.ts:65
{ file: { name: '../../etc/pas swd.pdf', url: 'https://cdn.test/c' } },
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/mcp-server/src/server.test.ts:607
expect(out.filename).toBe('../../etc/pas swd.pdf');
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:87
# 4. Start MCP-serveren (http://127.0.0.1:7878/mcp)
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:114
claude mcp add --transport http aula http://127.0.0.1:7878/mcp
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:153
cloudflared tunnel --url http://127.0.0.1:7878
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/home-assistant.md:142
hostname): brug HA's IP-adresse, fx `http://192.168.1.50:7878/sse`.
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
examples/claude-config/README.md:3
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,
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
packages/aula-auth/src/srp.test.ts:13
'12a4c4852c2b41cd9e3e456df7b79ba4e8296b35afd9614da9784c0af98776bb229da72acf6f7c3ccce1332aaed44d68aa0013ce76046dc581b039923f318c877fd63654e25539d507000b568d51fa25944179fa920ba96754464d9c05208ec76b6bacd
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
apps/cli/package.json
qrcode-terminal, @types/qrcode-terminal
Why it matters. 2 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@biomejs/biome, @types/bun, @types/node, bun-types, typescript
Why it matters. 5 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
packages/aula-auth/package.json
cheerio, tough-cookie
Why it matters. 2 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
packages/mcp-server/package.json
@modelcontextprotocol/sdk, hono, pdf-parse, qrcode, zod, @types/qrcode
Why it matters. 6 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
SECURITY.md:7
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.
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/architecture.md:62
1. an explicit `Buffer` passed to the constructor — strongest, intended for callers that read from a system keychain,
Why it matters. asks the agent to read credentials
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/architecture.md:72
- **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.
Why it matters. asks the agent to read credentials

Gates applied: no_behavioural_pass.

Audited 2026-10-08 · audit v0.4.1 · source sha c6b2104ff031full audit observations/trust-audit/mcp-server/casperjuel__aula.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-08c6b2104ff031SAFEB89first audit
06

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.

Advertisement