Casperjuel/aula-mcp
요약
aula-mcp는 MCP 클라이언트와 Aula 사이를 연결하는 서버로, MitID 및 학교 데이터에 접근할 수 있는 인터페이스를 제공합니다. 데이터 보안은 사용자가 선택한 LLM 클라이언트의 유형(클라우드 vs 로컬)에 따라 결정됨을 강조합니다.
핵심 포인트
- MCP 클라이언트와 Aula 간의 데이터 연결 인터페이스 제공
- MitID 및 OAuth 토큰은 로컬(Keychain/AES-256)에 안전하게 저장
- 데이터의 외부 유출 여부는 사용자가 선택한 LLM 클라이언트에 달려 있음
- 100% 로컬 환경을 위해 Ollama, LM Studio 등 로컬 LLM 사용 권장
- TypeScript, Bun, Hono 기반의 실험적 프로젝트
이것이 무엇인지 — 그리고 무엇이 아닌지에 대하여:
aula-mcp는 MCP 클라이언트 (LLM)와 Aula 사이를 연결하는 서버로, 하나의 인터페이스일 뿐 그 이상의 기능은 없습니다. LLM은 이 프로젝트의 일부가 아닙니다. 클라이언트(Claude Code, Claude Desktop, ChatGPT, Cursor, Ollama, LM Studio 등)는 사용자가 직접 선택하며, 해당 클라이언트는 Anthropic/OpenAI의 클라우드에서 실행되거나, Ollama 등을 사용하는 경우 로컬에서 실행됩니다.
따라서 이 프로젝트는 자녀의 데이터가 오직 로컬에만 머문다는 것을 보장하지 않습니다. 데이터가 로컬에 유지되는지 여부는 연결하는 클라이언트가 무엇인지에 따라 100% 결정됩니다. 이는 사용자의 책임이며, aula-mcp 자체에서 약속할 수 있는 부분이 아닙니다.
⚠️ 주의해서 사용하십시오. 취미로 진행하는 실험이며, 어떠한 보장도 제공하지 않습니다. 이 프로젝트는 MitID 및 자녀의 학교 데이터에 접근합니다. LLM을 연결하기 전에 코드를 검토하십시오 (또는 개발자 지인에게 검토를 요청하십시오). 모든 책임은 사용자에게 있습니다.
⚠️ 데이터를 보는 것은 서버가 아니라 클라이언트입니다. 이 서버는 로컬에서 실행되며 스스로 데이터를 전달하지 않습니다.
하지만 연결된 MCP 클라이언트(Claude, ChatGPT, 기타 클라우드 LLM)는 사용자에게 답변하기 위해 읽어들인 모든 데이터를 제공업체(Anthropic, OpenAI 등)로 전달합니다. 서버가 로컬에 있다고 해서 "모든 것이 로컬"인 것은 아닙니다. MCP의 작동 방식은 다음과 같습니다: 클라이언트가 추론하고, 서버가 데이터를 가져옵니다.
데이터의 행방
- MitID 자격 증명 및 OAuth 토큰: 로컬에 유지됩니다 — macOS Keychain 또는 AES-256-GCM으로 암호화된 파일로 저장됩니다. Aula에서 데이터를 가져오는 용도로만 사용됩니다.
- 실제 데이터 (메시지, 주간 계획, 자녀 이름 등): 사용자가 선택한 MCP 클라이언트로 전송됩니다.
- 클라우드 LLM → 제공업체의 서버(일반적으로 미국)로 전송됩니다.
- 로컬 LLM → 로컬에 유지됩니다.
100% 로컬 환경을 원하시나요?
클라이언트로 Ollama, LM Studio, llama.cpp, Hugging Face를 통한 Mistral 등과 같은 로컬 LLM을 사용하십시오. 이들은 모두 MCP를 지원하며 사용자의 자체 하드웨어에서 실행됩니다.
TypeScript + Bun + Hono를 사용합니다. scaarup/aula (Python/Home Assistant)를 기반으로 구축되었습니다. 현재 개발 진행 중입니다 — 도구(tools)의 시그니처가 변경될 수 있고, 명령어가 재명명될 수 있으며, 일부 벤더 통합은 단 하나의 학교 세트에 대해서만 테스트되었습니다.
- 서버가 다루는 것
- 시작하기
- Claude Code (또는 claude.ai) 연결
- Home Assistant (Assist + Voice)
- 셀프 호스팅 (Self-hosting)
- 매니페스트(manifest)에 포함된 내용
- CLI 명령어
- 설정 (Configuration)
- 아키텍처 (Architecture)
- Aula 이슈를 통한 수정 사항
- 트러블슈팅 (Troubleshooting)
- 개발
- 기여하기
- 개인정보 보호 및 법률
aula-mcp 자체에 대하여
- 서버가 수행하는 것(및 수행하지 않는 것). 데이터가 이후 어디로 향하는지는 클라이언트의 영역입니다 — 상단의 면책 조항을 참조하세요.
MitID 자격 증명 및 OAuth 토큰은 로컬에 저장됩니다. macOS: 키체인 (Keychain, security CLI). Linux/Windows: ~/.config/aula-mcp/ 내의 AES-256-GCM으로 암호화된 파일. 이 정보들은 귀하의 컴퓨터를 떠나지 않습니다.
서버는 바인딩(bind)만 수행합니다. AULA_MCP_ALLOW_REMOTE=1을 설정하지 않는 한 루프백(non-loopback) 주소에 바인딩하는 것을 거부하며, 기본값은 127.0.0.1입니다. 즉, 귀하의 컴퓨터에 있는 프로그램만 서버에 접속할 수 있습니다.
텔레메트리(telemetry) 없음, 제3자 전송 없음. 프로그램은 Aula의 자체 서버(api.aula.dk, login.aula.dk), MitID(nemlog-in.mitid.dk), 그리고 벤더 API(EasyIQ, Meebook 등 — 학교에서 사용하는 경우)와만 통신합니다.
MitID 인증은 MitID 자체 인프라를 통해 진행됩니다. 프로토콜은 TypeScript로 다시 작성되었지만, 인증 자체(MitID 앱의 QR 코드)는 항상 귀하의 장치와 nemlog-in.dk 사이에서 이루어집니다. 쿠키, OAuth 코드, MitID 페이로드, M1 값, flowValueProof, 액세스 토큰 등은 --debug 트레이스(trace)가 선택(opt-in)된 경우에도 디스크에 기록되기 전에 자동으로 편집(redacted)됩니다. 따라서 GitHub 이슈에 첨부해도 안전합니다.
루프백 전용(Loopback-only) = 가족이 자신의 장치에서 서버에 접속할 수 없습니다. 가구 내의 여러 장치에서 질문할 수 있어야 한다면, 리버스 프록시(reverse proxy, 셀프 호스팅 섹션 참조)를 사용하거나 향후 Home Assistant 통합을 사용해야 합니다.
Bun ≥ 1.3 및 pnpm ≥ 10이 필요합니다. macOS 또는 Linux 환경에서 작동합니다.
git clone git@github.com:Casperjuel/aula-mcp.git
cd aula-mcp
pnpm install
...
대부분의 CLI 명령어는 짧은 단축키를 제공합니다: pnpm login, pnpm doctor, pnpm whoami, pnpm status, pnpm logout. 그 외의 모든 명령은 pnpm aula <command>로 전달됩니다.
CLI 도구(fx pnpm aula transcript list, pnpm aula log --last 5)를 통해 확인할 수 있습니다.
doctor 명령은 모든 Read-endpoint (읽기 엔드포인트)를 실행하여 각 엔드포인트의 상태와 응답 시간(Response time)을 보고합니다. 이는 "이게 정말 작동하는가?"를 확인하는 가장 빠른 방법입니다.
whoami는 귀하의 토큰(Tokens)이 어떤 신원에 속하는지, 그리고 getProfilesByLogin에 의해 어떤 자식(Children) 데이터들이 반환되는지 보여줍니다:
# 1. 하나의 터미널 창에서 서버 실행
pnpm mcp
# 2. Claude Code에 서버 등록 (단 한 번만 수행)
...
이제 자연스럽게 질문할 수 있습니다. 자식들의 이름을 알 필요 없이 discover 매니페스트 (Manifest)와 퍼지 매칭 (Fuzzy-matched)되므로 다음과 같이 물어볼 수 있습니다:
"theo의 다음 주 주간 계획표에 무엇이 있나요?"
Claude는 aula.discover를 한 번 호출하고, detectedWidgets를 기반으로 귀하의 학교에 맞는 올바른 주간 계획표 벤더 (Vendor)를 선택한 뒤, 덴마크어로 형식화된 날짜와 함께 덴마크어로 답변합니다.
examples/claude-config/claude-desktop.json에 있는 스니펫 (Snippet)을 ~/Library/Application Support/Claude/claude_desktop_config.json에 복사하여 붙여넣으세요.
Web-UI (웹 UI)는 공개된 HTTPS URL이 필요합니다. 127.0.0.1은 Anthropic의 클라우드로부터 서버 측 (Server-side)에서 연결이 이루어지기 때문에 작동하지 않습니다. 빠른 테스트를 위해서는 다음과 같이 하세요:
cloudflared tunnel --url http://127.0.0.1:7878
# → https://<random>.trycloudflare.com — 끝에 `/mcp`를 붙여서 입력하세요
⚠️ 터널 URL은 실행되는 동안 공개적으로 접근 가능합니다. 누군가 이 URL을 알아내면 귀하의 Aula 토큰을 제어할 수 있습니다. 빠른 데모용으로는 괜찮지만, 계속 열어두지는 마세요. 영구적인 설정을 원하시면 다음 섹션을 참조하세요.
노트북을 켜두지 않고도 서버를 실행하고 싶다면 몇 가지 방법이 있습니다. 모든 방법은 서버를 로컬 (Local)에 유지합니다. 클라이언트 (Client)가 어디에서 실행될지는 여전히 별개의 선택 사항입니다 (상단 면책 조항 참조).
가장 간단한 방법입니다. 단일 바이너리 (Binary)로 컴파일하여 systemd 아래에서 실행하세요.
# 스탠드얼론 (Standalone) 바이너리 빌드 (~50 MB)
bun build --compile --outfile dist/aula-mcp packages/mcp-server/src/server.ts
# 서버(Pi, NAS, VPS)로 복사
...
서버의 토큰 (Tokens on the server) — 두 가지 방법이 있으니 귀하에게 적합한 것을 선택하세요:
A. SSH를 통해 서버에 직접 로그인합니다. QR 코드가 SSH 세션 내에 렌더링되므로, 휴대폰의 MitID 앱으로 스캔하세요. 일반적인 TTY로 SSH 접속이 가능한 모든 머신에서 실행됩니다.
ssh aula
aula login
B. Mac(또는 이미 로그인되어 있는 곳)에서 토큰을 내보냅니다 (Export). macOS Keychain은 머신 간에 이동할 수 없으므로, aula tokens export를 사용하여 휴대 가능한 파일 번들(file-bundle)로 재암호화합니다.
# Mac에서
aula tokens export ~/aula-bundle
# 서버로 이동 — 번들에는 라이브 자격 증명(live credentials)이 포함되어 있으므로, 다음과 같이 취급하세요
...
또는 서버에서: CLI가 파일을 올바른 위치에 배치하도록 하려면 aula tokens import ~/aula-bundle을 실행하세요.
systemd 유닛 예시 (/etc/systemd/system/aula-mcp.service):
[Unit]
Description=aula-mcp server
After=network.target
...
systemctl enable --now aula-mcp로 활성화하세요. 로그는 journalctl -u aula-mcp -f로 확인합니다.
기본적으로 서버는 127.0.0.1에만 바인딩됩니다. 가족(또는 VPN을 통한 휴대폰의 사용자 본인)이 접속할 수 있게 하려면, 인증(authentication) 기능이 포함된 리버스 프록시(reverse proxy)를 앞에 설정하세요. Caddy를 사용한 예시:
aula.dithjem.dk {
basicauth {
familie $2a$14$<bcrypt-hash>
...
}
reverse_proxy localhost:8080
}
AULA_MCP_HOST는 127.0.0.1로 유지됩니다. Caddy가 TLS, 기본 인증(basic auth), 속도 제한(rate limit)을 담당합니다. 공용 인터넷에 노출되는 것은 Caddy이며, MCP 서버 자체가 아닙니다.
⚠️ 만약 서버를 직접 노출(프록시 계층을 건너뜀)하려면 AULA_MCP_ALLOW_REMOTE=1을 명시적으로 설정해야 합니다. 이는 실수에 의한 것이 아니라 통제된 의도적인 동작이어야 합니다.
HA(Home Assistant) 사용자를 위한 가장 쉬운 방법입니다. 애드온(Add-on)은 aula-mcp를 패키징하여 HA 설치의 일부로 실행하며, HA의 Voice/Assist 및 모든 HA 자동화에서 사용할 수 있도록 합니다. Nabu Casa를 사용 중이라면, 해당 터널을 통해 안전한 원격 접속도 가능해집니다.
👉 전체 가이드: docs/home-assistant.md — 설치, MitID 로그인, MCP 통합, LLM 선택 및 음성 설정 안내.
요약:
- 원클릭 설치:
aula-mcp는 Streamable HTTP (/mcp)와 이전 방식인 SSE 방언 (/sse)을 모두 지원합니다.
) — HA의 공식 mcp
(클라이언트) 통합은 SSE를 사용합니다. - 로그인은 애드온(add-on) 자체의 사이드바 UI(MitID-QR + 신원 선택) 내에서 이루어집니다.
이미 유럽 VPS (Hetzner, Scaleway, OVH)와 도메인을 보유하고 있다면, 단지 다음 과정만 거치면 됩니다:
git clone
bun install- 옵션 1로 systemd-unit 설정.
Token-store: ~/.config/aula-mcp/tokens.json 및 .key 파일의 암호화된 복사본을 저장합니다 (또는 macOS의 Keychain 내보내기 사용). 토큰을 분실하면 다시 로그인해야 합니다. 패닉에 빠질 필요는 없지만 번거로울 수 있습니다.
AULA_MCP_KEY: 프로덕션 환경에서 파일 백엔드(file-backend)를 사용하는 경우, 강력한 AULA_MCP_KEY (환경 변수)를 설정하고 이를 커밋하지 마세요. 키를 교체(rotate)하면 다시 로그인해야 합니다.
새로운 Aula 버전: Aula는 연 1~2회 API 버전을 업데이트합니다. aula-mcp는 다음 호출 시 새로운 버전을 스스로 탐지하므로(별도의 수동 작업 불필요), Breaking Changes(파괴적 변경 사항)가 나타날 수 있으니 릴리스 노트를 주시하십시오.
에이전트(Agents)는 aula.discover를 한 번 호출하고 세션이 남은 동안 그 결과를 재사용합니다. 매니페스트(Manifest)는 에이전트에게 사용자가 누구인지, 누구를 대신하여 거래할 수 있는 자녀가 있는지, 학교가 구성한 어떤 제3자 위젯(third-party widgets)이 있는지, 그리고 어떤 MCP 도구(tools)를 호출해야 하는지를 알려줍니다:
형식:
{
user: { name, username, identityName? },
children: [{ id, name, userId?, institution: { id, name?, code? } }],
...
}
capabilities[area].tools[0]은 항상 호출해야 할 올바른 도구입니다. 학교의 위젯이 감지되면 일치하는 벤더(vendor)만 나열되므로, 에이전트가 여러 제공자 사이에서 헤매지 않도록 합니다. 인라인(inline) usage 블록은 에이전트가 어떻게 행동해야 하는지 알려줍니다 (매니페스트 캐싱, 자녀 이름 퍼지 매칭(fuzzy-match), Europe/Copenhagen 기본 설정, 사용자의 언어로 응답 등).
aula-mcp는 기본적으로 읽기 전용(read-only)입니다. AULA_MCP_WRITE=1로 설정하면 aula.presence.set_template이라는 하나의 추가 도구가 등록되며, 이를 통해 특정 날짜의 자녀 등하교 템플릿을 생성하거나 덮어쓸 수 있습니다: 등교 시간, 하교 시간, 하교 방식 (picked_up_by "~가 데리러 옴", self_decider "자율 결정", send_home "집으로 보냄", go_home_with "~와 함께 귀가")
"~와 함께 귀가") 및 필요한 경우 주간 반복. 읽기 도구 (Read-tool) aula.presence.templates는 현재 계획을 보여주며 항상 활성화되어 있습니다. 쓰기 도구 (Write-tool)는 Aula의 실제 데이터를 수정하므로, 의식적으로 플래그 (flag) 뒤에 배치되어 있습니다. 즉, 사용자가 활성화하지 않는 한 에이전트가 자녀의 하원 시간을 임의로 변경할 수 없습니다. writeEnabled가 매니페스트 (manifest)에서 설정되어 있는지 여부를 반영합니다.
aula login [--username <user>] [--method APP|CODE_TOKEN] [--debug] [--transcript <file>]
aula status [--json]
aula whoami [--json]
...
| 명령 (Command) | 기능 |
|---|---|
aula login | 전체 MitID 흐름을 실행합니다 (APP 방식이 기본값이며, MitID 앱으로 QR 코드를 스캔합니다). 토큰 (tokens)을 저장합니다. --debug는 오류 진단이 가능하도록 정제된 와이어 트랜스크립트 (wire-transcript)를 캡처합니다. |
aula status | 토큰 존재 여부, 만료 시간 및 활성 신원 (identity)을 보여줍니다. 네트워크에 접속하지 않습니다. 토큰이 없으면 종료 코드 (exit-code) 1을 반환합니다. |
aula whoami | 토큰을 로드하고 (필요 시 갱신), getProfilesByLogin + getProfileContext를 호출합니다. 전체 인증 (auth) 및 클라이언트 파이프라인 (client-pipeline)이 작동하는지 확인하는 스모크 테스트 (Smoke-test)입니다. |
aula doctor | 각 읽기 엔드포인트 (read-endpoint)를 실행하고 응답 시간과 함께 호출별 상태를 보고합니다. 가장 빠른 "이게 작동하는가?" 확인 방법입니다. --verbose는 오류 발생 시 와이어 트랜스크립트 (wire-transcript)를 인라인으로 덤프 (dump)합니다. |
aula log | 최근 로그인 시도 (성공/실패, 타임스탬프, 오류 클래스)를 보여줍니다. |
aula transcript | 캡처된 --debug 트랜스크립트 (transcripts)를 검사합니다; prune은 최근 N개(기본값 10개)를 유지합니다. |
aula logout | 저장된 토큰을 삭제합니다. 암호화 키 (encryption key)는 유지되어 다음 로그인 시 재사용됩니다. |
예제를 포함한 전체 도움말: pnpm aula --help
| 플랫폼 (Platform) | 기본값 (Default) | 재정의 (Override) |
|---|---|---|
| macOS | 키체인 (Keychain) (security CLI; 서비스 aula-mcp, 계정 tokens) | AULA_MCP_NO_KEYCHAIN=1 설정 시 파일 백엔드 (file-backend)로 전환됩니다. |
| Linux / Windows | ~/.config/aula-mcp/tokens.json에 저장된 AES-256-GCM 암호화 파일 | `AULA_MCP_KEY=<hex |
| 변수 | 기본값 | 효과 |
|---|---|---|
AULA_MCP_PORT | 7878 | 바인드 포트 (Bind-port). |
AULA_MCP_HOST | 127.0.0.1 | 바인드 인터페이스 (Bind-interface). AULA_MCP_ALLOW_REMOTE=1이 설정되지 않으면 루프백 (loopback) 이외의 주소를 거부합니다. |
AULA_MCP_DIR | ~/.config/aula-mcp | 설정 폴더 (파일 백엔드 (file-backend) + 트랜스크립트 (transcripts) + 로그인 로그 (login-log)). |
AULA_MCP_RAW=1 | off | aula.raw_request 탈출구 (escape-hatch) 도구를 활성화합니다. |
AULA_MCP_WRITE=1 | off | 쓰기 도구 (write-tools)를 활성화합니다 (aula.presence.set_template — 출근/퇴근 시간 설정). 이 설정이 없으면 서버는 읽기 전용 (read-only) 상태입니다. |
AULA_MCP_LOG=1 | off | 인증/클라이언트 (auth/client) 계층으로부터의 상세한 콘솔 로그 (verbose console-logs). |
AULA_MCP_ALLOW_REMOTE=1 | off | 루프백 이외의 주소(예: 리버스 프록시 (reverse proxy) 뒤)에 바인드하는 것을 허용합니다. |
--debug
- 모드는 각 HTTP 요청/응답 (HTTP request/response)의 JSONL 트랜스크립트 (JSONL-transcript)를
~/.config/aula-mcp/transcripts/login-<timestamp>.jsonl에 생성합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub AI Tools의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기