@classroomio/mcp 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +273 -0
- package/dist/index.js +830 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# @classroomio/mcp
|
|
2
|
+
|
|
3
|
+
Thin stdio MCP server for ClassroomIO course authoring.
|
|
4
|
+
|
|
5
|
+
The package does not parse PDFs or generate course structures. The agent does that work. `@classroomio/mcp` only exposes tools, validates tool input, and forwards requests to the ClassroomIO API.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
Teacher / Admin
|
|
11
|
+
|
|
|
12
|
+
v
|
|
13
|
+
Claude Code / Codex / Cursor / other MCP client
|
|
14
|
+
|
|
|
15
|
+
| 1. Reads prompt, PDF, or existing course goal
|
|
16
|
+
| 2. Produces or edits normalized course JSON
|
|
17
|
+
v
|
|
18
|
+
@classroomio/mcp (stdio)
|
|
19
|
+
|
|
|
20
|
+
| 3. Sends authenticated tool calls
|
|
21
|
+
| Authorization: Bearer <cio_mcp_...>
|
|
22
|
+
v
|
|
23
|
+
ClassroomIO API
|
|
24
|
+
|
|
|
25
|
+
| 4. Validates payloads
|
|
26
|
+
| 5. Resolves the organization from the key
|
|
27
|
+
| 6. Creates drafts or applies changes to a course
|
|
28
|
+
v
|
|
29
|
+
ClassroomIO DB
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Principles
|
|
33
|
+
|
|
34
|
+
1. The agent owns reasoning.
|
|
35
|
+
2. The MCP package owns transport and input validation.
|
|
36
|
+
3. ClassroomIO API remains the trust boundary for auth, validation, and persistence.
|
|
37
|
+
4. Draft creation and publish are separate operations.
|
|
38
|
+
5. Updating an existing course is done through a seeded draft, not blind writes to the live course.
|
|
39
|
+
|
|
40
|
+
## Tool Surface
|
|
41
|
+
|
|
42
|
+
Current tools:
|
|
43
|
+
|
|
44
|
+
- `get_course_structure`
|
|
45
|
+
- `create_course_draft`
|
|
46
|
+
- `create_course_draft_from_course`
|
|
47
|
+
- `get_course_draft`
|
|
48
|
+
- `update_course_draft`
|
|
49
|
+
- `publish_course_draft`
|
|
50
|
+
- `publish_course_draft_to_existing_course`
|
|
51
|
+
|
|
52
|
+
## Auth Model
|
|
53
|
+
|
|
54
|
+
The package expects an org-scoped ClassroomIO automation key generated from `Automation -> MCP` in the ClassroomIO dashboard.
|
|
55
|
+
|
|
56
|
+
The MCP process sends the key as a bearer token on every request.
|
|
57
|
+
|
|
58
|
+
ClassroomIO API:
|
|
59
|
+
|
|
60
|
+
1. hashes and verifies the key
|
|
61
|
+
2. resolves the owning organization
|
|
62
|
+
3. checks the key scopes
|
|
63
|
+
4. executes the requested action
|
|
64
|
+
|
|
65
|
+
The MCP package never decides permissions.
|
|
66
|
+
|
|
67
|
+
## Required Environment Variables
|
|
68
|
+
|
|
69
|
+
- `CLASSROOMIO_API_URL`
|
|
70
|
+
- `CLASSROOMIO_API_KEY`
|
|
71
|
+
- `CLASSROOMIO_USER_AGENT` optional
|
|
72
|
+
|
|
73
|
+
## Run Locally
|
|
74
|
+
|
|
75
|
+
From the repo root:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pnpm build --filter=@classroomio/mcp
|
|
79
|
+
CLASSROOMIO_API_URL=http://localhost:3081 \
|
|
80
|
+
CLASSROOMIO_API_KEY=<cio_mcp_key> \
|
|
81
|
+
node packages/mcp/dist/index.js
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Published package:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
CLASSROOMIO_API_URL=https://api.classroomio.com \
|
|
88
|
+
CLASSROOMIO_API_KEY=<cio_mcp_key> \
|
|
89
|
+
npx -y @classroomio/mcp
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Client Setup
|
|
93
|
+
|
|
94
|
+
### Claude Code
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
claude mcp add-json classroomio '{
|
|
98
|
+
"command": "npx",
|
|
99
|
+
"args": ["-y", "@classroomio/mcp"],
|
|
100
|
+
"env": {
|
|
101
|
+
"CLASSROOMIO_API_URL": "https://api.classroomio.com",
|
|
102
|
+
"CLASSROOMIO_API_KEY": "<cio_mcp_key>"
|
|
103
|
+
}
|
|
104
|
+
}'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Codex
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
codex mcp add classroomio \
|
|
111
|
+
--env CLASSROOMIO_API_URL=https://api.classroomio.com \
|
|
112
|
+
--env CLASSROOMIO_API_KEY=<cio_mcp_key> \
|
|
113
|
+
-- npx -y @classroomio/mcp
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Cursor
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"mcpServers": {
|
|
121
|
+
"classroomio": {
|
|
122
|
+
"command": "npx",
|
|
123
|
+
"args": ["-y", "@classroomio/mcp"],
|
|
124
|
+
"env": {
|
|
125
|
+
"CLASSROOMIO_API_URL": "https://api.classroomio.com",
|
|
126
|
+
"CLASSROOMIO_API_KEY": "<cio_mcp_key>"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Draft Model
|
|
134
|
+
|
|
135
|
+
A draft is a saved, structured course proposal. It is not the live course.
|
|
136
|
+
|
|
137
|
+
Draft payload shape:
|
|
138
|
+
|
|
139
|
+
```text
|
|
140
|
+
draft
|
|
141
|
+
course
|
|
142
|
+
sections[]
|
|
143
|
+
lessons[]
|
|
144
|
+
lessonLanguages[]
|
|
145
|
+
warnings[]
|
|
146
|
+
sourceReferences[] optional
|
|
147
|
+
exercises[] optional
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Drafts support:
|
|
151
|
+
|
|
152
|
+
- review before publish
|
|
153
|
+
- iterative edits from the agent
|
|
154
|
+
- safer updates to existing courses
|
|
155
|
+
- auditability of AI-generated structure
|
|
156
|
+
|
|
157
|
+
## User Flows
|
|
158
|
+
|
|
159
|
+
### Flow 1: Create a new course from a prompt
|
|
160
|
+
|
|
161
|
+
User says:
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
Create a complete course on exponential functions for high school students.
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Expected tool sequence:
|
|
168
|
+
|
|
169
|
+
1. Agent plans the course.
|
|
170
|
+
2. Agent calls `create_course_draft`.
|
|
171
|
+
3. User asks for revisions.
|
|
172
|
+
4. Agent calls `update_course_draft`.
|
|
173
|
+
5. User approves.
|
|
174
|
+
6. Agent calls `publish_course_draft`.
|
|
175
|
+
|
|
176
|
+
Result:
|
|
177
|
+
|
|
178
|
+
- a new course is created
|
|
179
|
+
- sections and lessons are created
|
|
180
|
+
- localized lesson content is written
|
|
181
|
+
|
|
182
|
+
### Flow 2: Create a draft from a PDF
|
|
183
|
+
|
|
184
|
+
User says:
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
I have my course in a PDF. Extract it and turn it into a ClassroomIO course draft.
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Expected tool sequence:
|
|
191
|
+
|
|
192
|
+
1. Agent reads the PDF itself.
|
|
193
|
+
2. Agent restructures the content into normalized JSON.
|
|
194
|
+
3. Agent calls `create_course_draft`.
|
|
195
|
+
4. User reviews the draft.
|
|
196
|
+
5. Agent calls `update_course_draft` if needed.
|
|
197
|
+
6. User approves.
|
|
198
|
+
7. Agent calls `publish_course_draft`.
|
|
199
|
+
|
|
200
|
+
Important:
|
|
201
|
+
|
|
202
|
+
- the PDF does not need to be uploaded to MCP
|
|
203
|
+
- the MCP package only receives structured JSON
|
|
204
|
+
|
|
205
|
+
### Flow 3: Update an existing course safely
|
|
206
|
+
|
|
207
|
+
User says:
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
Take my existing Algebra course, reorganize it, and rewrite the lesson content for a beginner audience.
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Expected tool sequence:
|
|
214
|
+
|
|
215
|
+
1. Agent calls `get_course_structure` with the existing `courseId`.
|
|
216
|
+
2. Agent optionally calls `create_course_draft_from_course` to persist a seeded draft.
|
|
217
|
+
3. Agent updates the draft with the new structure and content using `update_course_draft`.
|
|
218
|
+
4. User reviews the changes.
|
|
219
|
+
5. Agent calls `publish_course_draft_to_existing_course`.
|
|
220
|
+
|
|
221
|
+
What this publish does today:
|
|
222
|
+
|
|
223
|
+
- updates the existing course title, description, type, and metadata
|
|
224
|
+
- updates existing sections when the draft keeps their IDs
|
|
225
|
+
- updates existing lessons when the draft keeps their IDs
|
|
226
|
+
- creates new sections and lessons for draft items without matching live IDs
|
|
227
|
+
- upserts lesson language content
|
|
228
|
+
|
|
229
|
+
What it does not do today:
|
|
230
|
+
|
|
231
|
+
- automatically delete sections or lessons that are absent from the draft
|
|
232
|
+
- automatically delete lesson locales that are absent from the draft
|
|
233
|
+
|
|
234
|
+
That behavior is intentional. The current update path is non-destructive by default.
|
|
235
|
+
|
|
236
|
+
## How Existing-Course Updates Work
|
|
237
|
+
|
|
238
|
+
When a draft is seeded from a live course:
|
|
239
|
+
|
|
240
|
+
- section `externalId` values are the real section IDs
|
|
241
|
+
- lesson `externalId` values are the real lesson IDs
|
|
242
|
+
|
|
243
|
+
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.
|
|
244
|
+
|
|
245
|
+
If the agent adds a brand new section or lesson, it should assign a new synthetic `externalId`. ClassroomIO will create that record on publish.
|
|
246
|
+
|
|
247
|
+
## Input Contract Notes
|
|
248
|
+
|
|
249
|
+
For large updates, the agent should:
|
|
250
|
+
|
|
251
|
+
1. call `get_course_structure`
|
|
252
|
+
2. keep existing `externalId` values for records it wants to update
|
|
253
|
+
3. only generate new `externalId` values for new records
|
|
254
|
+
4. avoid deleting records from the draft unless the user explicitly wants omitted content to remain untouched
|
|
255
|
+
|
|
256
|
+
## Operational Notes
|
|
257
|
+
|
|
258
|
+
- `create_course_draft_from_course` may add warnings if a live course uses legacy lesson notes instead of localized lesson content
|
|
259
|
+
- if a course has ungrouped lessons, the seeded draft may add a synthetic `Ungrouped` section so the structure stays valid
|
|
260
|
+
- published drafts are treated as finalized snapshots
|
|
261
|
+
|
|
262
|
+
## Recommended Agent Behavior
|
|
263
|
+
|
|
264
|
+
For small edits, an agent can still read the course structure and modify only the affected items in the draft.
|
|
265
|
+
|
|
266
|
+
For broad revisions, prefer this sequence:
|
|
267
|
+
|
|
268
|
+
1. `get_course_structure`
|
|
269
|
+
2. `create_course_draft_from_course`
|
|
270
|
+
3. `update_course_draft`
|
|
271
|
+
4. `publish_course_draft_to_existing_course`
|
|
272
|
+
|
|
273
|
+
That keeps major AI-assisted edits reviewable and explicit.
|