@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.
Files changed (4) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +273 -0
  3. package/dist/index.js +830 -0
  4. 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.