4.5 KiB
ClassroomIO MCP Server
Thin stdio MCP server for ClassroomIO course-draft authoring.
Architecture
Teacher
|
v
Claude Desktop / Claude Code / other MCP client
|
| 1. Reads prompt or PDF content
| 2. Produces normalized course JSON
v
ClassroomIO MCP Server (stdio)
|
| 3. Forwards validated tool calls
| - Authorization: Bearer <cio_mcp_...>
v
ClassroomIO API
|
| 4. Validates payload
| 5. Resolves org from the key
| 6. Stores draft or publishes course
v
ClassroomIO DB
How It Comes Together
- The agent owns reasoning and extraction.
- The MCP server does not parse PDFs or generate course structure.
- The MCP server only exposes tools and forwards structured payloads into ClassroomIO.
- ClassroomIO API remains the trust boundary for auth, validation, and persistence.
- Draft creation and publish are explicit separate steps.
Tool Surface
create_course_draftget_course_draftupdate_course_draftpublish_course_draft
Required Environment Variables
CLASSROOMIO_API_URLCLASSROOMIO_API_KEY
Auth Model
Current implementation uses an org-scoped automation key created in ClassroomIO under Automation -> MCP.
The MCP server sends that key as a bearer token on every request.
ClassroomIO API:
- hashes and verifies the key
- resolves the owning organization
- checks the key scopes
- persists the draft or publish request
The MCP server does not decide permissions. ClassroomIO API remains the source of truth.
Run
pnpm --filter @classroomio/mcp build
CLASSROOMIO_API_URL=http://localhost:3081 \
CLASSROOMIO_API_KEY=<cio_mcp_key> \
node packages/mcp/dist/index.js
Claude Code Example
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 Example
codex mcp add classroomio \
--env CLASSROOMIO_API_URL=https://api.classroomio.com \
--env CLASSROOMIO_API_KEY=<cio_mcp_key> \
-- npx -y @classroomio/mcp
Cursor Example
{
"mcpServers": {
"classroomio": {
"command": "npx",
"args": ["-y", "@classroomio/mcp"],
"env": {
"CLASSROOMIO_API_URL": "https://api.classroomio.com",
"CLASSROOMIO_API_KEY": "<cio_mcp_key>"
}
}
}
}
User Flow Examples
This package uses the same org-scoped automation key system that will later power the public API.
Different integrations get different keys and scope presets. The infrastructure is shared, the secrets should not be.
Flow 1: Prompt to draft to publish
User says:
Create a complete course on exponential functions for high school students in ClassroomIO.
Expected agent behavior:
- Claude plans the course structure.
- Claude calls
create_course_draftwith:- course title and description
- sections
- lessons
- lesson language content
- Claude reviews the returned draft ID and summary.
- User requests changes.
- Claude calls
update_course_draft. - When the user approves, Claude calls
publish_course_draft.
Result:
- a real ClassroomIO course
- sections created
- lessons created
- lesson language content inserted
Flow 2: PDF to draft
User says:
I have my course in a PDF. Extract it and turn it into a structured ClassroomIO course draft.
Expected agent behavior:
- Claude reads the PDF itself.
- Claude extracts and restructures the material into normalized course JSON.
- Claude calls
create_course_draft. - Claude returns a summary of:
- detected sections
- detected lessons
- warnings or ambiguous splits
- User asks for revisions.
- Claude calls
update_course_draft. - User approves publish.
- Claude calls
publish_course_draft.
Important:
- the PDF never needs to be uploaded to the MCP server
- the MCP server only receives structured JSON
Flow 3: Human-in-the-loop revision
User says:
Move logarithmic review before growth models and shorten lesson 2.
Expected agent behavior:
- Claude calls
get_course_draft. - Claude computes the revised structure.
- Claude calls
update_course_draftwith the modified payload. - Claude summarizes what changed before publish.
Normalized Payload Shape
The core payload sent through the MCP server is:
draft
course
sections[]
lessons[]
lessonLanguages[]
warnings[]
sourceReferences[] optional
exercises[] optional
This keeps prompt-based creation and PDF-based extraction on the same ingestion path.