THU-MAIC/OpenMAIC
Open Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click
About THU-MAIC/OpenMAIC
THU-MAIC/OpenMAIC is an open-source project on GitHub, mainly written in TypeScript. Open Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click It currently holds 39,988 stars and 6,187 forks with 181 open issues, and was last pushed on 2026-10-05 (repository created 2026-03-11).
Project Overview
Git Homed tracks it on the Today's Trending board.
GitHub Repository Details
README
Get an immersive, multi-agent learning experience in just one click
English | Simplified Chinese
Live Demo · Quick Start · Lemonade · FunASR · Features · Use Cases · OpenClaw
🗞️ News
- 2026-10-04 — v1.2.0-rc.1 (pre-release): server-first. Until 1.1.x, the browser drove course generation step by step and kept courses, keys and model settings itself, so closing the tab stopped a course halfway, every browser had to be configured on its own, and the headless API ran a separate pipeline. In 1.2.0 the server owns all of it: generation runs on the server and survives closed tabs and restarts, models are configured once in
openmaic.yml(with defaults, locks and an option to forbid user keys), materials are parsed as soon as they are attached, and the web app and the API share one pipeline. It needs PostgreSQL and a long-running server; Vercel deployments stay on 1.1.x. Read the changelog before upgrading. - 2026-09-28 — v1.1.2: security — provider requests connect only to validated addresses and refuse redirects (GHSA-g87c-cm4q-cw5x).
- 2026-09-27 — v1.1.1: security — hardened MinerU Cloud parsing (GHSA-cpjc-vgjh-c5jp).
- 2026-09-24 — v1.1.0: agentic classroom chat (ask about any slide element, interactive, or whiteboard drawing); settings rebuilt around the course workflow; Token Plan connections.
- 2026-09-15 — v1.0.3: security — access-code tokens expire, render-service network policy, pinned audio connections, Next.js RCE patch.
- 2026-09-14 — v1.0.2: security — SSRF and DNS-rebinding fixes, classroom overwrite fix.
- 2026-09-06 — v1.0.1: security and stability; tightens two defaults.
- 2026-08-27 — v1.0.0: agent workbench, durable sessions, reusable skills, session materials, provider-neutral capabilities.
Earlier releases
- 2026-08-14 — v0.3.2: video export hardening, server-backed persistence and asset registry,
@openmaic/generation, four new locales, FunASR. - 2026-07-21 — v0.3.1: one-click MP4 export, direct slide editing, smarter "Edit with AI", expanded document parsing.
- 2026-06-28 — v0.3.0: PBL v2, "Edit with AI" editor agent,
@openmaic/*SDKs on npm, relicensed to MIT. - 2026-06-02 — v0.2.2: MAIC Editor Pro Mode, editable outlines, offline classroom export.
- 2026-04-26 — v0.2.1: VoxCPM2 TTS with voice cloning, per-model thinking config, course completion page.
- 2026-04-20 — v0.2.0: Deep Interactive Mode — 3D, simulations, games, mind maps, online programming.
- 2026-04-14 — v0.1.1: language inference, ACCESS_CODE, classroom ZIP export/import, Ollama.
- 2026-03-26 — v0.1.0: discussion TTS, immersive mode, keyboard shortcuts.
Full history in the changelog.
📖 Overview
OpenMAIC (Open Multi-Agent Interactive Classroom) is an open-source AI platform that turns any topic or document into a rich, interactive classroom experience. Powered by multi-agent orchestration, it generates slides, quizzes, interactive simulations, and project-based learning activities — all delivered by AI teachers and AI classmates who can speak, draw on a whiteboard, and engage in real-time discussions with you. The built-in OpenMAIC Skill works with OpenClaw as well as agent workbenches such as Codex, DeepSeek, and WorkBuddy, so you can generate classrooms from messaging apps like Feishu, Slack, or Telegram, or right inside your IDE.
https://github.com/user-attachments/assets/8f3f1e5f-1468-4e93-8054-afeeea683a61
Highlights
- One-click lesson generation — Describe a topic or attach your materials; the AI builds a full lesson in minutes
- Multi-agent classroom — AI teachers and peers lecture, discuss, and interact with you in real time
- Rich scene types — Slides, quizzes, interactive HTML simulations, and project-based learning (PBL)
- Whiteboard & TTS — Agents draw diagrams, write formulas, and explain out loud
- Export anywhere — Download editable
.pptxslides or interactive.htmlpages - Agent workbench integration — The OpenMAIC Skill supports OpenClaw, Codex, DeepSeek, WorkBuddy, and more — generate classrooms from Feishu, Slack, Telegram, 20+ messaging apps, or your IDE
🚀 Quick Start
Prerequisites
- Node.js >= 22.19
- pnpm >= 10
- PostgreSQL 16 — courses are stored on the server. For local development
pnpm db:up starts one in Docker for you.
1. Clone & Install
git clone https://github.com/THU-MAIC/OpenMAIC.git
cd OpenMAIC
pnpm install
2. Configure
cp .env.example .env.local # API keys and server options
cp openmaic.example.yml openmaic.yml # which models the server uses
The copied example needs only OPENAI_API_KEY in .env.local (or change its provider to one you have a key for); everything else in it is commented out until you want it. openmaic.yml declares providers (accounts the server can call) and gives each slot (a use of AI: the outline, slide content, text to speech, web search, …) a model. Keys stay in .env.local and are referenced as ${VAR}:
providers:
openai:
preset: openai
apiKey: ${OPENAI_API_KEY} # OPENAI_API_KEY=sk-... in .env.local
anthropic:
preset: anthropic
apiKey: ${ANTHROPIC_API_KEY}
slots:
llm: openai:gpt-5.5 # the default chat model
course.outline: anthropic:claude-sonnet-4-6
video: null # turn a capability off
The slots you write are the server's defaults; users can change them, or connect services of their own, in the app's model settings unless you lock them or set allowUserKeys: false. The server validates the file at startup and names every mistake by its field (or, for broken YAML, its line).
| To learn about | Read |
| --- | --- |
| Slots, presets, fallbacks, lock, allowUserKeys, OPENMAIC_SECRET_KEY | Configuration |
| Every provider preset and model ID | Supported models |
| Upgrading: provider variables, server-providers.yml, DEFAULT_MODEL and MODEL_FALLBACK still work without openmaic.yml; MODEL_ROUTES must become slots | Migrating from the legacy configuration |
Providers: OpenAI, Azure OpenAI, Anthropic, Amazon Bedrock, Google Gemini, DeepSeek, Qwen, Kimi, MiniMax, Grok (xAI), OpenRouter, TokenDance, Doubao, Tencent Hunyuan/TokenHub, Xiaomi MiMo, GLM (Zhipu), Ollama, Lemonade and FunASR (local), and any OpenAI-compatible API.
[!TIP]
Recommended setup: OpenMAIC is at its best with every modality turned on — generated illustrations, narration, video clips, and web-grounded research. The least friction is a single key that covers all of them (see the token plan examples below), with a fast long-context model such as deepseek-v4.1-flash as the default.
More examples: token plans, Xiaomi MiMo and GLM, Amazon Bedrock
Token plan quick example (one key for chat, image, video, TTS and web search; tokendance works the same way):
providers:
minimax:
preset: minimax
apiKey: ${MINIMAX_API_KEY}
slots:
llm: minimax:MiniMax-M3
image: minimax # a provider id alone: the plan's default model
video: minimax
tts: minimax
webSearch: minimax
TokenDance quick example with a fast long-context default model:
providers:
tokendance:
preset: tokendance
apiKey: ${TOKENDANCE_API_KEY}
slots:
llm: tokendance:deepseek-v4.1-flash
image: tokendance
video: tokendance
tts: tokendance
webSearch: tokendance
Xiaomi MiMo Token Plan and GLM (Zhipu) quick example:
providers:
mimo:
preset: xiaomi
apiKey: ${MIMO_API_KEY}
baseUrl: https://token-plan-cn.xiaomimimo.com/v1
glm:
preset: glm
apiKey: ${GLM_API_KEY}
baseUrl: https://open.bigmodel.cn/api/paas/v4 # or https://api.z.ai/api/paas/v4
slots:
llm: mimo:mimo-v2.5-pro
course.content: glm:glm-5.1
Use https://token-plan-sgp.xiaomimimo.com/v1 or https://token-plan-ams.xiaomimimo.com/v1 for the Singapore or Europe Token Plan clusters.
Amazon Bedrock quick example:
providers:
bedrock:
preset: bedrock
models: [us.anthropic.claude-sonnet-5, us.anthropic.claude-opus-4-8]
slots:
llm: bedrock:us.anthropic.claude-sonnet-5
Bedrock uses AWS environment credentials or the AWS SDK credential provider chain, with the region from BEDROCK_REGION (for example BEDROCK_REGION=us-east-1 in .env.local). For temporary credentials, set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN, or use an AWS profile / role available to the runtime.
3. Start the database
pnpm db:up
Then uncomment the local DATABASE_URL line in .env.local:
DATABASE_URL=postgres://openmaic:[email protected]:5432/openmaic
pnpm db:up starts a development PostgreSQL on 127.0.0.1:5432 (set OPENMAIC_DB_PORT for another port). It is its own Compose project, openmaic-dev-db, shared by every checkout on this machine, with its own container and volume, so it never touches the database of a docker compose up stack. pnpm db:down stops it and keeps the data. Any other PostgreSQL works too.
4. Run
pnpm dev
Open http://localhost:3000 and start learning! Without a DATABASE_URL the
server refuses to start and tells you how to provide one (see
Server-backed persistence).
5. Build for Production
pnpm build && DATABASE_URL=postgres://... pnpm start
Keep the server running as a long-running process (a process manager or a container): course generation runs inside it and continues after the browser leaves the page. See the Deployment guide for the required configuration and for upgrading from 1.1.x.
Docker Deployment
cp .env.example .env.local
Edit .env.local with your API keys, then:
docker compose up --build
Open http://localhost:3000. The stack is two containers, the app and PostgreSQL. Courses, generated media and runtime sessions live in the named volumes openmaic-postgres and openmaic-data, which survive docker compose down and rebuilds; docker compose down -v deletes them. To configure models with openmaic.yml, create it from openmaic.example.yml and uncomment its mount in docker-compose.yml; otherwise connect a model service in the model settings once the app is running.
The Compose file is a personal installation: it runs in single-user mode (every browser sees one shared library) and listens on 127.0.0.1:3000 only. To serve other machines, protect it first:
1. Set a long random ACCESS_CODE in .env.local (details). Without it, anyone who can reach the port owns, edits and can delete the whole library.
2. Before the first start, set PERSISTENCE_POSTGRES_PASSWORD to a random value of letters and digits.
3. Publish on the network address:
OPENMAIC_PUBLISH_ADDRESS=0.0.0.0 docker compose up -d --build
OPENMAIC_PUBLISH_ADDRESS, OPENMAIC_PORT and PERSISTENCE_POSTGRES_PASSWORD come from your shell or a .env file next to docker-compose.yml, not from .env.local. Overriding the Compose defaults, rotating the database password and the full upgrade notes are in Hosting and identity.
[!IMPORTANT]
Upgrading a Compose deployment? PostgreSQL now always starts, the app is published on127.0.0.1only, and every visitor is the same single owner. If.env.localsetsPERSISTENCE_SHARED_OWNER_ID, also setOWNER_SINGLE_USER=false, or the app refuses to start. Read Upgrading a Compose deployment first.
Slow-network / China build acceleration
Docker builds support two optional build arguments. Both are empty by default, so the standard command above keeps using the upstream Alpine and npm registries.
ALPINE_MIRRORis an Alpine mirror hostname withouthttps://.NPM_REGISTRYis a complete npm registry URL.
With Docker Compose:
ALPINE_MIRROR=mirrors.tuna.tsinghua.edu.cn \
NPM_REGISTRY=https://registry.npmmirror.com \
docker compose up --build
For a direct image build:
docker build \
--build-arg ALPINE_MIRROR=mirrors.tuna.tsinghua.edu.cn \
--build-arg NPM_REGISTRY=https://registry.npmmirror.com \
-t openmaic:local .
These arguments do not accelerate Docker Hub pulls, including the Dockerfile
frontend and the node:22-alpine base image. Configure a Docker daemon registry
mirror separately if those pulls are slow. The pnpm store cache is reused by the
same BuildKit builder across builds, subject to normal cache garbage collection;
the cache only improves performance and is not required for a correct build.
Vercel Deployment (up to 1.1.x)
Serverless deployment is supported up to OpenMAIC 1.1.x. From 1.2.0, course
generation runs on the server in a process that outlives requests, so OpenMAIC
needs a long-running Node.js process with PostgreSQL (the
Docker deployment or pnpm start); Vercel and other
serverless hosts are not supported, and the repository no longer ships a
vercel.json. To deploy 1.1.x on Vercel:
1. Fork this repository on GitHub, unchecking Copy the main branch only.
2. In the fork, set the default branch to release/1.1.x (Settings → General → Default branch).
3. In Vercel, Add New → Project and import the fork. Vercel builds its default branch; configure at least one LLM provider key as described in that branch's .env.example.
Such a deployment can move to a long-running host later without losing data:
point the new host's DATABASE_URL at the database it used, if it used one,
and serve it at the same address, since browsers keep their data per site; the
courses visitors kept in their browsers are imported the first time each
browser opens the upgraded app. See
Upgrading from 1.1.x
for every kind of deployment.
Server-backed persistence (PostgreSQL)
OpenMAIC keeps courses on the server. Course documents, folders, chat history, learner sessions and generated media live in PostgreSQL (media optionally in S3), served by the app itself at /api/persistence. The browser keeps only what belongs to the device, such as settings, playback position and caches; Settings → Clear Local Cache never touches the server.
DATABASE_URLis required. Without it the server prints the fix and exits with code1. Compose sets it for you; for development,pnpm db:upstarts a database.- Courses an older build kept in the browser are imported once per browser, automatically, the first time it opens the upgraded app. The browser copy is left untouched.
- Invalid settings stop the server at startup with a one-line
[boot]reason instead of a server that answers every request with500.
| Mode | Set | Library |
| --- | --- | --- |
| Single user (Compose default) | OWNER_SINGLE_USER=true | One library for everyone who can reach the server; guard it with ACCESS_CODE or loopback |
| Shared team | PERSISTENCE_SHARED_OWNER_ID= together with ACCESS_CODE | One library for the team behind the access code |
| Anonymous (default without either) | nothing | One library per browser cookie; a second browser sees an empty one |
| Your own accounts | owner auth methods registered in instrumentation.ts | One library per signed-in account |
Set the mode before the first start of 1.2.0: classrooms that 1.1.x saved as files are imported for the owner configured then. See Upgrading from 1.1.x for every kind of deployment.
Running OpenMAIC for other people, or embedding it in your own product? Hosting and identity covers:
- who can read and write stored data, and the removed
PERSISTENCE_DEV_TOKEN; - asset collection, quotas and S3 egress (
ASSET_*); - every startup check;
- owner identity: single-user mode, registering auth methods, a signed-JWT gateway recipe and claiming anonymous work;
- host extension hooks for course creation, the library, uploads and asset byte stores.
Optional: ACCESS_CODE (Shared Deployments)
Protect a deployment with a site-level password in .env.local:
ACCESS_CODE=your-secret-code
Use a long random value, at least 16 characters from a random generator: it is the only secret guarding the deployment. Visitors then see a password prompt, and every API route is gated too. When it is unset (the default in .env.example), middleware.ts checks no credential and every route, the API included, is reachable: an unconfigured deployment is not gated, and there is no second enforcement point. The code is remembered for 7 days in a signed HTTP-only cookie; attempts are rate limited only behind a trusted proxy with TRUST_PROXY_HEADERS=true. See Configuration → ACCESS_CODE.
Optional: Agent workbench and runtime
The Pro workbench, a course-building surface entered from the home page, is off by default. Turn on its build-time entry point and the server runtime; it uses the same PostgreSQL as the rest of the app:
NEXT_PUBLIC_PRO_WORKBENCH_ENABLED=true
OPENMAIC_AGENT_RUNTIME_ENABLED=true
DATABASE_URL=postgres://openmaic:openmaic-dev@postgres:5432/openmaic
The agent runs on the agent slot, which follows the default chat model unless assigned and needs a model with tool calling:
slots:
llm: openai:gpt-5.5
agent:
model: openai:gpt-5.5
api: openai-completions # or openai-responses
The agent slot must not set thinking.effort. Its routes, the DEFAULT_MODEL caveat and runner tuning are in Hosting and identity.
Optional: Lemonade (Local AI Provider)
OpenMAIC supports Lemonade as a local, OpenAI-compatible provider for LLMs, image generation, TTS, and ASR. No API key is required.
Run Lemonade locally, then point OpenMAIC to it:
```yaml providers: lemonade: preset: lemonade baseUrl: http://localhost:13305/v1 lemonade-tts: preset: lemonade-tts baseUrl: http://localhost:13305/v1 lemonade-asr: preset: lemonade-asr