Files
classroomio/apps/docs/content/docs/mcp.mdx
T
Abdulmuizz HamzatandRotimi Best b599f1a017 chore(docs): migrate the docs site from Fumadocs to Blume (#753)
* Update documentation for ClassroomIO: change Fumadocs to Blume, revise MDX format conventions, and clarify sidebar navigation requirements.

* docs: update README and scripts for improved preview and error handling

* docs: update Discord link in configuration and documentation

* docs: add token-auth route and update documentation formatting

* Fix formatting in auto-comment-issues.yml

* Fix JSON syntax by adding a comma

* fix(docs): declare Blume's Astro build deps so Cloudflare build resolves them

blume build generates an Astro project under apps/docs/.blume/ that imports
astro, @astrojs/mdx, @tailwindcss/vite, tailwindcss, @tailwindcss/typography,
@shikijs/twoslash and @scalar/astro. Under pnpm's isolated node_modules these
are nested inside blume and not resolvable from the docs app, so a clean
--frozen-lockfile build (Cloudflare) fails at 'Cannot find module astro/config'.
Declare them directly in @cio/docs, pinned to blume's resolved versions.

* refactor(docs): update API reference paths and documentation for clarity

* fix: change platofrm url to docs home page

* Refactor documentation for self-hosting ClassroomIO

- Removed the Supabase Cloud setup guide as it is no longer needed.
- Updated the Enterprise SSO documentation to include a reference link for SSO & licensing.
- Added new documentation for Content Security Policy (CSP) configuration.
- Created a new section for configuring SMTP for email notifications.
- Introduced a comprehensive configuration index for self-hosted ClassroomIO, detailing environment variables and their usage.
- Added documentation for optional integrations including Google OAuth, OpenAI, and Unsplash.
- Documented the generation and usage of required secrets for ClassroomIO.
- Created a section for SSO & licensing, detailing the requirements for Enterprise features.
- Added object storage configuration documentation, covering both bundled MinIO and external S3-compatible services.
- Documented versioning and upgrade processes for ClassroomIO.
- Updated the Coolify and Docker self-hosting guides to streamline configuration references and upgrade instructions.
- Enhanced the Railway self-hosting guide with links to relevant configuration sections.
- Updated token authentication documentation to reference SSO & licensing.

* Add comprehensive guides for ClassroomIO features and functionalities

- Introduced a new guide for the Student Dashboard, detailing navigation and features available to students.
- Added a guide on using Tags for organizing and filtering courses within ClassroomIO.
- Created a guide on how to take attendance in courses, including marking attendance and related functionalities.
- Developed a Terminology guide to clarify key terms used throughout ClassroomIO.
- Implemented a Token Auth guide for signing users into ClassroomIO from external applications using JWT.
- Added instructions for using math in the editor with LaTeX support.
- Created a guide for customizing the welcome email sent to students upon enrollment in courses.
- Added a guide explaining what ClassroomIO is and its key features.
- Updated the home documentation to provide a clearer overview of ClassroomIO and its resources.
- Enhanced self-hosted configuration documentation with a new guide for deploying ClassroomIO on Dokploy.
- Updated links in the self-hosted configuration documentation for better navigation.
- Added new images to support the Dokploy deployment guide.
- Updated asset packaging script to handle redirects for the new guide structure.
- Fixed footer link to point to the correct Getting Started guide.

* chore: uprage version

* feat(docs): add DigitalOcean deployment guide and flatten guides structure

- Add a guide for deploying ClassroomIO on DigitalOcean using Docker Compose
  and Caddy for automatic HTTPS.
- List DigitalOcean as a deployment option in the self-hosting index.
- Move guides out of content/docs/guides into content/docs (student-dashboard,
  tags, terminology, token-auth, what-is-classroomio, audience, cohorts,
  community, course, enterprise-sso, mcp, organization, quickstart/*).
- Rename home.mdx to index.mdx.
- Update package-assets script to emit redirects for the old guides paths.

---------

Co-authored-by: Rotimi Best <[email protected]>
2026-07-22 22:30:10 +01:00

481 lines
12 KiB
Plaintext

---
title: MCP
description: Connect Claude Code, Codex, Cursor, OpenCode, and other MCP clients to ClassroomIO for draft-based course authoring.
---
`@classroomio/mcp` is a thin stdio MCP server for ClassroomIO course authoring.
It does not parse PDFs or generate course structures itself. The agent does that work. The MCP
server exposes tools, validates tool input, and forwards authenticated requests to the
ClassroomIO API.
## Architecture
```text
Teacher / Admin
|
v
Claude Code / Codex / Cursor / OpenCode / other MCP client
|
| 1. Reads prompt, PDF, or existing course goal
| 2. Produces or edits normalized course JSON
v
@classroomio/mcp (stdio)
|
| 3. Sends authenticated tool calls
| Authorization: Bearer <cio_mcp_...>
v
ClassroomIO API
|
| 4. Validates payloads
| 5. Resolves the organization from the key
| 6. Creates drafts or applies changes to a course
v
ClassroomIO DB
```
## Core Principles
1. The agent owns reasoning.
2. The MCP package owns transport and input validation.
3. ClassroomIO API remains the trust boundary for auth, validation, and persistence.
4. Draft creation and publish are separate operations.
5. Updating an existing course is done through a seeded draft, not blind writes to the live
course.
## Authentication
Generate an org-scoped MCP key from `Automation -> MCP` in the ClassroomIO dashboard.
The MCP process sends that key as a bearer token on every request.
ClassroomIO API:
1. hashes and verifies the key
2. resolves the owning organization
3. checks the key scopes
4. executes the requested action
The MCP package never decides permissions.
## Required Environment Variables
- `CLASSROOMIO_API_URL`
- `CLASSROOMIO_API_KEY`
- `CLASSROOMIO_USER_AGENT` optional
## Run the MCP Server
Published package:
```bash
CLASSROOMIO_API_URL=https://api.classroomio.com \
CLASSROOMIO_API_KEY=<cio_mcp_key> \
npx -y @classroomio/mcp
```
From the monorepo:
```bash
pnpm build --filter=@classroomio/mcp
CLASSROOMIO_API_URL=http://localhost:3081 \
CLASSROOMIO_API_KEY=<cio_mcp_key> \
node packages/mcp/dist/index.js
```
## Client Setup
### Claude Code
```bash
claude mcp add-json classroomio '{
"command": "npx",
"args": ["-y", "@classroomio/mcp"],
"env": {
"CLASSROOMIO_API_URL": "https://api.classroomio.com",
"CLASSROOMIO_API_KEY": "<cio_mcp_key>"
}
}'
```
### Codex
```bash
codex mcp add classroomio \
--env CLASSROOMIO_API_URL=https://api.classroomio.com \
--env CLASSROOMIO_API_KEY=<cio_mcp_key> \
-- npx -y @classroomio/mcp
```
### OpenCode
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"classroomio": {
"type": "local",
"command": ["npx", "-y", "@classroomio/mcp"],
"enabled": true,
"environment": {
"CLASSROOMIO_API_URL": "https://api.classroomio.com",
"CLASSROOMIO_API_KEY": "<cio_mcp_key>"
}
}
}
}
```
### Cursor
```json
{
"mcpServers": {
"classroomio": {
"command": "npx",
"args": ["-y", "@classroomio/mcp"],
"env": {
"CLASSROOMIO_API_URL": "https://api.classroomio.com",
"CLASSROOMIO_API_KEY": "<cio_mcp_key>"
}
}
}
}
```
## Tool Surface
Current tools:
- `list_org_courses`
- `get_course_structure`
- `reorder_course_content`
- `update_course_landing_page`
- `create_course_draft`
- `create_course_draft_from_course`
- `get_course_draft`
- `update_course_draft`
- `publish_course_draft`
- `publish_course_draft_to_existing_course`
- `tag_course_draft`
- `tag_courses`
- `list_course_exercises`
- `get_course_exercise`
- `create_course_exercise`
- `create_course_exercise_from_template`
- `update_course_exercise`
## Draft Model
A draft is a saved, structured course proposal. It is not the live course.
Draft payload shape:
```text
draft
course
tags[]
sections[]
lessons[]
lessonLanguages[]
warnings[]
sourceReferences[] optional
exercises[] optional
```
Drafts support:
- review before publish
- iterative edits from the agent
- safer updates to existing courses
- auditability of AI-generated structure
Lesson authoring rule:
- `lessonLanguages[].content` should contain only the lesson body HTML
- do not include the lesson title
- do not use `h1` or `h2` in lesson content
- start headings at `h3`
- ClassroomIO already renders the lesson title in the course UI
## After Publish
Once a draft has been published, the live course becomes the safer source of truth.
Recommended agent rule:
- if the draft is still `DRAFT`, continue editing that draft
- if the draft is `PUBLISHED`, do not keep reusing it for major follow-up edits
- instead, read the live course and create a fresh draft from that course
Recommended post-publish sequence:
1. `get_course_structure`
2. `create_course_draft_from_course`
3. `update_course_draft`
4. `publish_course_draft_to_existing_course`
Why:
- teachers may edit the live course in the UI after publish
- another agent session may have changed the course
- reusing an old published draft can overwrite newer live changes
For exercises on an already-published course, prefer the direct exercise tools instead of creating a whole new draft when the user only wants to add or revise exercises.
## User Flows
### Flow 1: Create a new course from a prompt
Typical flow:
1. Agent plans the course.
2. Agent calls `create_course_draft`.
3. User asks for revisions.
4. Agent calls `update_course_draft`.
5. User approves.
6. Agent calls `publish_course_draft`.
Publish returns:
- `courseId`
- `courseUrl`
- `bannerImageUrl` when a banner was explicitly provided or generated
- `tagNames`
`publish_course_draft` can also:
- use an explicit `bannerImageUrl`
- generate a random Unsplash-based banner from the course title or a custom query
### Flow 2: Update a landing page with AI-generated copy and media
User says:
```text
Rewrite this course landing page to feel more premium, generate a new cover image, and add three believable reviews.
```
Expected tool sequence:
1. Agent calls `list_org_courses` if it needs to resolve the course ID by name first.
2. Agent calls `update_course_landing_page`.
What the landing-page tool can update:
- title
- short description
- overview
- requirements
- goals
- pricing fields
- instructor section
- reviews
- landing page image
The tool can either:
- use an explicit `imageUrl`
- or generate a random Unsplash-based image with `generateImage` and `imageQuery`
### Flow 3: Create a draft from a PDF
User says:
```text
I have my course in a PDF. Extract it and turn it into a ClassroomIO course draft.
```
Expected tool sequence:
1. Agent reads the PDF itself.
2. Agent restructures the content into normalized JSON.
3. Agent calls `create_course_draft`.
4. User reviews the draft.
5. Agent calls `update_course_draft` if needed.
6. User approves.
7. Agent calls `publish_course_draft`.
Important:
- the PDF does not need to be uploaded to MCP
- the MCP package only receives structured JSON
### Flow 4: Tag a draft before publish
User says:
```text
Add tags for algebra, beginner, and exponential growth to this draft.
```
Expected tool sequence:
1. Agent calls `tag_course_draft`.
2. User reviews the updated draft tags.
3. Agent later calls `publish_course_draft`.
Result:
- the draft stores tag names
- publish ensures the tags exist in ClassroomIO
- publish assigns those tags to the live course
### Flow 5: Update an existing course safely
User says:
```text
Take my existing Algebra course, reorganize it, and rewrite the lesson content for a beginner audience.
```
When the course already exists, use the live course as the source of truth.
Expected tool sequence:
1. `list_org_courses` if the agent needs to resolve the course ID by name
2. Agent calls `get_course_structure` with the existing `courseId`.
3. Agent optionally calls `create_course_draft_from_course` to persist a seeded draft.
4. Agent updates the draft with the new structure and content using `update_course_draft`.
5. User reviews the changes.
6. Agent calls `publish_course_draft_to_existing_course`.
What this publish does today:
- updates the existing course title, description, type, and metadata
- can set a generated course cover from Unsplash
- returns the public `courseUrl`
- updates existing sections when the draft keeps their IDs
- updates existing lessons when the draft keeps their IDs
- creates new sections and lessons for draft items without matching live IDs
- upserts lesson language content
- merges draft tags into the existing course
### Flow 6: Reorder live course content
User says:
```text
Move the quiz before lesson 2 and put the recap lesson into the last section.
```
Use `reorder_course_content` when the live course only needs structural moves:
- reorder sections
- reorder lessons or exercises within a section
- move lessons or exercises between sections
This is the fast path for live structure edits and avoids creating a draft when lesson content is not changing.
Expected tool sequence:
1. Agent calls `reorder_course_content`.
Use this direct path when the live course only needs section ordering or lesson or exercise moves between sections.
It avoids the full draft round-trip for simple structural changes.
### Flow 7: Add exercises to a live course
User says:
```text
Add a 5-question multiple-choice exercise to lesson 3.
```
Expected tool sequence:
1. Agent calls `list_course_exercises` if it needs current context.
2. Agent calls `create_course_exercise` for a brand new exercise.
3. Agent calls `update_course_exercise` for later revisions.
Use this direct path when the course is already live and the change is exercise-specific.
What it does not do today:
- automatically delete sections or lessons that are absent from the draft
- automatically delete lesson locales that are absent from the draft
That behavior is intentional. The current update path is non-destructive by default.
## How Existing-Course Updates Work
When a draft is seeded from a live course:
- section `externalId` values are the real section IDs
- lesson `externalId` values are the real lesson IDs
As long as the agent preserves those IDs while editing the draft, publish-to-existing-course can map draft items back to the live records and update them safely.
If the agent adds a brand new section or lesson, it should assign a new synthetic `externalId`. ClassroomIO will create that record on publish.
## Input Contract Notes
For large updates, the agent should:
1. call `get_course_structure`
2. keep existing `externalId` values for records it wants to update
3. only generate new `externalId` values for new records
4. avoid deleting records from the draft unless the user explicitly wants omitted content to remain untouched
Publish input also supports:
- `bannerImageUrl`: use this exact course cover
- `bannerImageQuery`: search Unsplash with this query
- `generateBannerImage`: fetch a random Unsplash image using the course title or query
Tagging tools use:
- `tagNames`: human-readable tag names, not tag IDs
- `mode: "merge" | "replace"`
- `groupName` optional, defaults to `Automation`
The API creates missing tags automatically when needed.
Exercise tools use the live course directly:
- `list_course_exercises`
- `get_course_exercise`
- `create_course_exercise`
- `create_course_exercise_from_template`
- `update_course_exercise`
Supported `questionTypeId` values for exercise payloads:
- `1` `RADIO` - Single answer
- `2` `CHECKBOX` - Multiple answers
- `3` `TEXTAREA` - Paragraph
- `4` `TRUE_FALSE` - True/False
- `5` `SHORT_ANSWER` - Short answer
- `6` `NUMERIC` - Numeric answer
- `7` `FILL_BLANK` - Fill in the blank
- `8` `FILE_UPLOAD` - File upload
- `9` `MATCHING` - Matching
- `10` `ORDERING` - Ordering
- `11` `HOTSPOT` - Hotspot
- `12` `LINK` - Links
## Operational Notes
- `create_course_draft_from_course` may add warnings if a live course uses legacy lesson notes instead of localized lesson content
- if a course has ungrouped lessons, the seeded draft may add a synthetic `Ungrouped` section so the structure stays valid
- published drafts are treated as finalized snapshots
## Recommended Agent Behavior
For small edits, an agent can still read the course structure and modify only the affected items in the draft.
For broad revisions, prefer this sequence:
1. `get_course_structure`
2. `create_course_draft_from_course`
3. `update_course_draft`
4. `publish_course_draft_to_existing_course`
That keeps major AI-assisted edits reviewable and explicit.
:::note[Operational Rule]
Keep published drafts for history and auditability. Do not treat omission from a draft as an
instruction to delete live sections or lessons. Destructive changes should only happen through
explicit user intent.
:::