@chalksurf/cli 0.3.1 → 0.3.3
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/README.md +9 -0
- package/dist/bin/chalksurf.js +6962 -1660
- package/docs/agents.md +125 -70
- package/docs/exit-codes.md +6 -1
- package/docs/manual.md +10 -0
- package/docs/mcp.md +110 -40
- package/package.json +1 -1
package/docs/agents.md
CHANGED
|
@@ -64,7 +64,11 @@ The CLI and MCP surface are backed by the same agent resource contracts in `pack
|
|
|
64
64
|
- Write tools return a `receipt` with `resource`, `operation`, `changedPaths`, `precondition`, `warnings`, and `details`.
|
|
65
65
|
- Patch-style writes require `expectedUpdatedAt` from a fresh `get` call.
|
|
66
66
|
- Exercise updates require shared-usage care. Use `exercise usage` first when the exercise might appear outside the target sheet.
|
|
67
|
-
- Validate proposed LaTeX with `exercise validate-latex` before applying content updates.
|
|
67
|
+
- Agent exercise create/update writes are stricter than the human UI: invalid LaTeX is rejected with `agentErrorCode: "invalid_latex"` instead of being saved with a warning. Validate proposed LaTeX with `exercise validate-latex` before applying content updates.
|
|
68
|
+
- For exercise creates, the server validates all submitted normalized translation fields. For exercise updates, the server validates only translation fields explicitly present in `patch.translations`; omitted invalid fields do not block unrelated partial updates.
|
|
69
|
+
- Successful exercise create/update receipts include `details.latexValidation`. The scope is `all_translation_fields`, `changed_translation_fields`, or `none` when no translation content changed.
|
|
70
|
+
- Failed invalid-LaTeX writes include `error.agentErrorDetails.results[].patchPath`, `validation.issues[].code`, `message`, `snippet`, offsets, and optional `hint` values so agents can repair and retry without guessing.
|
|
71
|
+
- Use figure tools to create and attach figures to exercises. Use `figure capabilities` before drafting, visually review `figure render-draft`, then upload and attach only after the figure looks correct.
|
|
68
72
|
- Use `exercise labels` / `list_exercise_labels` before writing labels. Exercise create and update reject labels outside the canonical taxonomy.
|
|
69
73
|
- Delete and visibility tools are exposed, but destructive writes require exact resource-ID confirmation and current `expectedUpdatedAt` values where applicable.
|
|
70
74
|
- No transfer-between-organization agent primitive is intentionally exposed.
|
|
@@ -75,34 +79,42 @@ Write receipts are the agent audit log. Preserve them in run notes or user-visib
|
|
|
75
79
|
|
|
76
80
|
Use these commands after authentication and organization selection:
|
|
77
81
|
|
|
78
|
-
| Goal
|
|
79
|
-
|
|
|
80
|
-
| Fetch one sheet
|
|
81
|
-
| List owned sheet versions
|
|
82
|
-
| Fetch one owned sheet version
|
|
83
|
-
| Get a sheet repair queue
|
|
84
|
-
| Create a sheet
|
|
85
|
-
| Copy a sheet
|
|
86
|
-
| Create an editable variant sheet
|
|
87
|
-
| Append existing exercises to a sheet | `chalksurf sheet append SHEET_ID EXERCISE_ID... --json`
|
|
88
|
-
| Patch sheet metadata
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
|
|
|
101
|
-
|
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
82
|
+
| Goal | CLI command |
|
|
83
|
+
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| Fetch one sheet | `chalksurf sheet get SHEET_ID --json` |
|
|
85
|
+
| List owned sheet versions | `chalksurf sheet versions SHEET_ID --json` |
|
|
86
|
+
| Fetch one owned sheet version | `chalksurf sheet version SHEET_ID VERSION_ID --json` |
|
|
87
|
+
| Get a sheet repair queue | `chalksurf sheet issues SHEET_ID --json` |
|
|
88
|
+
| Create a sheet | `chalksurf sheet create --input-json JSON --json` |
|
|
89
|
+
| Copy a sheet | `chalksurf sheet copy SHEET_ID "New name" --exercise-copy-mode keep_references --json` |
|
|
90
|
+
| Create an editable variant sheet | `chalksurf sheet copy SHEET_ID "Variant name" --exercise-copy-mode copy_all_exercises --json` |
|
|
91
|
+
| Append existing exercises to a sheet | `chalksurf sheet append SHEET_ID EXERCISE_ID... --json` |
|
|
92
|
+
| Patch sheet metadata | `chalksurf sheet update SHEET_ID --expected-updated-at ISO --patch-json JSON --json` |
|
|
93
|
+
| List valid sheet-series paths | `chalksurf sheet series list --json` |
|
|
94
|
+
| Validate/apply bulk sheet patches | `chalksurf sheet bulk-update --input-json JSON --json` |
|
|
95
|
+
| Set sheet visibility | `chalksurf sheet set-visibility SHEET_ID --public --expected-updated-at ISO --confirm-make-public-resource-id SHEET_ID --json` |
|
|
96
|
+
| Delete a sheet | `chalksurf sheet delete SHEET_ID --expected-updated-at ISO --confirm-resource-id SHEET_ID --json` |
|
|
97
|
+
| List folders | `chalksurf sheet folder list --json` |
|
|
98
|
+
| Create a folder | `chalksurf sheet folder create "Folder name" --parent-id FOLDER_ID --json` |
|
|
99
|
+
| Rename a folder | `chalksurf sheet folder rename FOLDER_ID "New name" --json` |
|
|
100
|
+
| Delete an empty folder | `chalksurf sheet folder delete FOLDER_ID --confirm-resource-id FOLDER_ID --json` |
|
|
101
|
+
| Fetch one exercise | `chalksurf exercise get EXERCISE_ID --json` |
|
|
102
|
+
| List valid exercise labels | `chalksurf exercise labels --json` |
|
|
103
|
+
| Inspect exercise usage | `chalksurf exercise usage EXERCISE_ID --json` |
|
|
104
|
+
| Inspect figure building blocks | `chalksurf figure capabilities --json` |
|
|
105
|
+
| Render a draft figure | `chalksurf figure render-draft --input-json JSON --output figure.png --json` |
|
|
106
|
+
| Upload a figure image | `chalksurf exercise figure upload ./figure.png --figure-type text --json` |
|
|
107
|
+
| Attach figures to an exercise | `chalksurf exercise figure attach EXERCISE_ID --expected-updated-at ISO --figure-json JSON --json` |
|
|
108
|
+
| Create an exercise | `chalksurf exercise create --input-json JSON --json` |
|
|
109
|
+
| Copy one exercise | `chalksurf exercise copy EXERCISE_ID --json` |
|
|
110
|
+
| Patch exercise fields | `chalksurf exercise update EXERCISE_ID --expected-updated-at ISO --patch-json JSON --json` |
|
|
111
|
+
| Set exercise visibility | `chalksurf exercise set-visibility EXERCISE_ID --public --expected-updated-at ISO --confirm-make-public-resource-id EXERCISE_ID --json` |
|
|
112
|
+
| Delete an unused exercise | `chalksurf exercise delete EXERCISE_ID --expected-updated-at ISO --confirm-resource-id EXERCISE_ID --json` |
|
|
113
|
+
| Validate LaTeX snippets | `chalksurf exercise validate-latex --snippet "path=value" --json` |
|
|
114
|
+
| Send user-consented feedback | `chalksurf feedback user --message "..." --user-consent --json` |
|
|
115
|
+
| Send agent-observed feedback | `chalksurf feedback agent --message "..." --json` |
|
|
116
|
+
|
|
117
|
+
Pass `folderId` in the `sheet create --input-json` payload to place a new sheet in a target folder. Omit it or pass `null` to create the sheet at the organization root.
|
|
106
118
|
|
|
107
119
|
When appending private exercises to a public sheet, the CLI requires `--confirm-make-exercises-public` because the append makes those exercises public.
|
|
108
120
|
|
|
@@ -128,7 +140,7 @@ chalksurf --profile prod-codex exercise validate-latex \
|
|
|
128
140
|
--json
|
|
129
141
|
```
|
|
130
142
|
|
|
131
|
-
4. Patch the owning exercise or sheet with the `updated_at` value from the latest `get` result
|
|
143
|
+
4. Patch the owning exercise or sheet with the `updated_at` value from the latest `get` result. Exercise update validation is scoped to the translation fields explicitly present in `patch.translations`:
|
|
132
144
|
|
|
133
145
|
```bash
|
|
134
146
|
chalksurf --profile prod-codex exercise update EXERCISE_ID \
|
|
@@ -142,6 +154,43 @@ chalksurf --profile prod-codex exercise update EXERCISE_ID \
|
|
|
142
154
|
|
|
143
155
|
Do not pass `--allow-shared-exercise-update` unless the user has acknowledged that the same exercise is used outside the target sheet.
|
|
144
156
|
|
|
157
|
+
## Figure Workflow: Draft, Review, Attach
|
|
158
|
+
|
|
159
|
+
1. Inspect available building blocks:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
chalksurf --profile prod-codex figure capabilities --json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
2. Render a semantic draft and save the PNG for visual inspection:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
chalksurf --profile prod-codex figure render-draft \
|
|
169
|
+
--input-json '{"canvas":{"width":320,"height":240},"objects":[{"id":"A","type":"point","at":{"x":0,"y":0}}]}' \
|
|
170
|
+
--output figure.png \
|
|
171
|
+
--json
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
3. Upload the reviewed image:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
chalksurf --profile prod-codex exercise figure upload figure.png \
|
|
178
|
+
--figure-type text \
|
|
179
|
+
--json
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
4. Fetch the exercise, then attach the returned `result.figure` with the latest `updated_at`:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
chalksurf --profile prod-codex exercise get EXERCISE_ID --json
|
|
186
|
+
chalksurf --profile prod-codex exercise figure attach EXERCISE_ID \
|
|
187
|
+
--expected-updated-at 2026-01-01T00:00:00.000Z \
|
|
188
|
+
--figure-json '{"type":"text","url":"https://...","widthInCm":6}' \
|
|
189
|
+
--json
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Use `--mode replace_type --figure-type text` to replace only exercise-text figures, or `--mode replace_all` to replace the full figure list. Attach uses the same shared-exercise acknowledgement rules as `exercise update`.
|
|
193
|
+
|
|
145
194
|
## Variant Workflow: Create A Slightly Easier Sheet
|
|
146
195
|
|
|
147
196
|
Use `copy_all_exercises` when the target is an editable variant. Shared public exercises often cannot be edited by the selected organization, so keeping references usually blocks variant edits.
|
|
@@ -160,46 +209,52 @@ Use `keep_references` only when the user wants a new sheet arrangement that stil
|
|
|
160
209
|
|
|
161
210
|
MCP clients should use tool discovery from the client. The ChalkSurf MCP endpoint exposes the same resource primitives under snake_case names:
|
|
162
211
|
|
|
163
|
-
| CLI command
|
|
164
|
-
|
|
|
165
|
-
| `auth status`
|
|
166
|
-
| `org list`
|
|
167
|
-
| `exercise search`
|
|
168
|
-
| `exercise get`
|
|
169
|
-
| `exercise labels`
|
|
170
|
-
| `exercise usage`
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `exercise
|
|
174
|
-
| `exercise
|
|
175
|
-
| `exercise
|
|
176
|
-
| `exercise
|
|
177
|
-
| `exercise
|
|
178
|
-
| `exercise
|
|
179
|
-
| `exercise
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
| `sheet
|
|
185
|
-
| `sheet
|
|
186
|
-
| `sheet
|
|
187
|
-
| `sheet
|
|
188
|
-
| `sheet
|
|
189
|
-
| `sheet
|
|
190
|
-
| `sheet
|
|
191
|
-
| `sheet
|
|
192
|
-
| `sheet
|
|
193
|
-
| `sheet
|
|
194
|
-
| `sheet
|
|
195
|
-
| `sheet
|
|
196
|
-
| `sheet
|
|
197
|
-
| `sheet
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
200
|
-
| `
|
|
201
|
-
| `
|
|
202
|
-
| `
|
|
212
|
+
| CLI command | MCP tool |
|
|
213
|
+
| -------------------------- | ----------------------------------- |
|
|
214
|
+
| `auth status` | `get_auth_status` |
|
|
215
|
+
| `org list` | `list_organizations` |
|
|
216
|
+
| `exercise search` | `search_exercises` |
|
|
217
|
+
| `exercise get` | `get_exercise` |
|
|
218
|
+
| `exercise labels` | `list_exercise_labels` |
|
|
219
|
+
| `exercise usage` | `get_exercise_usage` |
|
|
220
|
+
| `figure capabilities` | `figure_get_capabilities` |
|
|
221
|
+
| `figure render-draft` | `figure_render_draft` |
|
|
222
|
+
| `exercise figure upload` | `upload_exercise_figure` |
|
|
223
|
+
| `exercise figure attach` | `attach_exercise_figures` |
|
|
224
|
+
| `exercise create` | `create_exercise` |
|
|
225
|
+
| `exercise copy` | `copy_exercise` |
|
|
226
|
+
| `exercise update` | `update_exercise` |
|
|
227
|
+
| `exercise set-visibility` | `set_exercise_visibility` |
|
|
228
|
+
| `exercise translate` | `generate_exercise_translation_job` |
|
|
229
|
+
| `exercise delete` | `delete_exercise` |
|
|
230
|
+
| `exercise validate-latex` | `validate_latex_snippets` |
|
|
231
|
+
| `exercise import` | `import_exercise` |
|
|
232
|
+
| `exercise import-solution` | `import_exercise_solution` |
|
|
233
|
+
| `sheet search` | `search_sheets` |
|
|
234
|
+
| `sheet get` | `get_sheet` |
|
|
235
|
+
| `sheet versions` | `list_sheet_versions` |
|
|
236
|
+
| `sheet version` | `get_sheet_version` |
|
|
237
|
+
| `sheet issues` | `get_sheet_issues` |
|
|
238
|
+
| `sheet create` | `create_sheet` |
|
|
239
|
+
| `sheet copy` | `copy_sheet` |
|
|
240
|
+
| `sheet append` | `append_exercises_to_sheet` |
|
|
241
|
+
| `sheet update` | `update_sheet` |
|
|
242
|
+
| `sheet series list` | `list_sheet_series` |
|
|
243
|
+
| `sheet bulk-update` | `bulk_update_sheets` |
|
|
244
|
+
| `sheet set-visibility` | `set_sheet_visibility` |
|
|
245
|
+
| `sheet translate` | `generate_sheet_translation_job` |
|
|
246
|
+
| `sheet delete` | `delete_sheet` |
|
|
247
|
+
| `sheet import` | `import_sheet` |
|
|
248
|
+
| `sheet import-solutions` | `import_sheet_solutions` |
|
|
249
|
+
| `sheet folder list` | `list_folders` |
|
|
250
|
+
| `sheet folder create` | `create_folder` |
|
|
251
|
+
| `sheet folder rename` | `rename_folder` |
|
|
252
|
+
| `sheet folder delete` | `delete_folder` |
|
|
253
|
+
| `job list` | `list_jobs` |
|
|
254
|
+
| `job get` | `get_job` |
|
|
255
|
+
| `job wait` | `wait_for_jobs` |
|
|
256
|
+
| `feedback user` | `send_user_feedback` |
|
|
257
|
+
| `feedback agent` | `send_agent_feedback` |
|
|
203
258
|
|
|
204
259
|
MCP calls authenticate through ChalkSurf OAuth, not CLI tokens. Read tools require `chalksurf:read`; write tools require `chalksurf:write` plus a write grant for the requested `organizationId`. Each organization-scoped MCP call must pass `organizationId`.
|
|
205
260
|
|
package/docs/exit-codes.md
CHANGED
|
@@ -17,7 +17,10 @@ The CLI uses stable exit codes so automation can branch without parsing human te
|
|
|
17
17
|
|
|
18
18
|
These same codes are mirrored in `error.exitCode` and `error.code` inside the JSON envelope.
|
|
19
19
|
|
|
20
|
-
API errors may also include
|
|
20
|
+
API errors may also include:
|
|
21
|
+
|
|
22
|
+
- `error.agentErrorCode`: a stable ChalkSurf agent error code such as `precondition_failed`, `confirmation_required`, `invalid_label`, `invalid_latex`, or `resource_in_use`.
|
|
23
|
+
- `error.agentErrorDetails`: structured repair details for errors that need more context. For `invalid_latex`, this includes a summary, affected patch paths, issue codes, snippets, offsets, messages, and hints when available.
|
|
21
24
|
|
|
22
25
|
## JSON Envelope
|
|
23
26
|
|
|
@@ -51,6 +54,8 @@ Known failures also return JSON on stdout:
|
|
|
51
54
|
}
|
|
52
55
|
```
|
|
53
56
|
|
|
57
|
+
Invalid agent-written exercise LaTeX returns exit code `5` with `error.agentErrorCode = "invalid_latex"`. In JSON mode, inspect `error.agentErrorDetails.results[].patchPath` and `error.agentErrorDetails.results[].validation.issues[]` to repair the submitted fields and retry.
|
|
58
|
+
|
|
54
59
|
## Contract Notes
|
|
55
60
|
|
|
56
61
|
- `warnings` contains informational messages that would otherwise be printed for humans.
|
package/docs/manual.md
CHANGED
|
@@ -234,6 +234,16 @@ chalksurf exercise update 00000000-0000-4000-8000-000000000002 \
|
|
|
234
234
|
|
|
235
235
|
Write commands return a receipt with the affected resource, changed paths, warnings, and operation-specific details. Fetch the resource first and use its current `updated_at` value for patch commands.
|
|
236
236
|
|
|
237
|
+
Admin-only sheet-series labeling supports a two-step bulk flow:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
chalksurf sheet series list --json
|
|
241
|
+
chalksurf sheet bulk-update --input-json '{"mode":"dry_run","updates":[...]}' --json
|
|
242
|
+
chalksurf sheet bulk-update --input-json '{"mode":"apply","updates":[...],"confirmationDigest":"..."}' --json
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The exact same update list must be submitted in both calls. A batch contains at most 100 sheets, applies atomically, and cannot update sheets outside the selected organization.
|
|
246
|
+
|
|
237
247
|
Manage folders:
|
|
238
248
|
|
|
239
249
|
```bash
|
package/docs/mcp.md
CHANGED
|
@@ -28,53 +28,123 @@ Read tools return structured resource data. Write tools return a structured `rec
|
|
|
28
28
|
|
|
29
29
|
Treat write receipts as an agent audit log. They are suitable for user-visible summaries after an agent edits a sheet.
|
|
30
30
|
|
|
31
|
+
Exercise content writes are stricter for agents than for the human UI. `create_exercise` validates all submitted normalized exercise translation fields before writing. `update_exercise` validates only translation fields explicitly present in `patch.translations`; omitted invalid fields do not block unrelated partial updates.
|
|
32
|
+
|
|
33
|
+
Successful exercise create/update receipts include `details.latexValidation` with one of these scopes:
|
|
34
|
+
|
|
35
|
+
- `all_translation_fields` for exercise creates.
|
|
36
|
+
- `changed_translation_fields` for exercise updates that submitted translation fields.
|
|
37
|
+
- `none` when an exercise update changed no translation content.
|
|
38
|
+
|
|
39
|
+
If `create_exercise` or `update_exercise` rejects invalid LaTeX, the tool result has `isError: true` and structured content shaped like:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"isError": true,
|
|
44
|
+
"error": {
|
|
45
|
+
"code": "invalid_latex",
|
|
46
|
+
"message": "invalid_latex: translations.english.exercise_text",
|
|
47
|
+
"agentErrorDetails": {
|
|
48
|
+
"type": "invalid_latex",
|
|
49
|
+
"summary": {
|
|
50
|
+
"checkedSnippetCount": 1,
|
|
51
|
+
"invalidSnippetCount": 1,
|
|
52
|
+
"affectedPathCount": 1
|
|
53
|
+
},
|
|
54
|
+
"results": []
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Use `error.agentErrorDetails.results[].patchPath` and `validation.issues[]` to repair the submitted fields and retry. The text content also starts with `[invalid_latex]` and names affected paths for clients that only display text.
|
|
61
|
+
|
|
31
62
|
## Tool Surface
|
|
32
63
|
|
|
33
|
-
| Tool
|
|
34
|
-
|
|
|
35
|
-
| `get_auth_status`
|
|
36
|
-
| `list_organizations`
|
|
37
|
-
| `search_exercises`
|
|
38
|
-
| `get_exercise`
|
|
39
|
-
| `list_exercise_labels`
|
|
40
|
-
| `get_exercise_usage`
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
64
|
+
| Tool | Permission | Purpose |
|
|
65
|
+
| ----------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `get_auth_status` | read | Confirm the authenticated ChalkSurf user and selected organization. |
|
|
67
|
+
| `list_organizations` | read | List organizations granted to the MCP client. |
|
|
68
|
+
| `search_exercises` | read | Search exercises by text, labels, status, ownership, age, difficulty, or semantic query. |
|
|
69
|
+
| `get_exercise` | read | Fetch full details for one visible exercise. |
|
|
70
|
+
| `list_exercise_labels` | read | List the canonical exercise label taxonomy agents may write to exercises. |
|
|
71
|
+
| `get_exercise_usage` | read | Inspect which sheets use one visible exercise. |
|
|
72
|
+
| `figure_get_capabilities` | read | Inspect supported semantic 2D figure objects, construction definitions, assertions, limits, and snippets. |
|
|
73
|
+
| `figure_render_draft` | read | Render a semantic figure draft to SVG/PNG metadata, PNG image content, diagnostics, assertions, and review hints. |
|
|
74
|
+
| `upload_exercise_figure` | write | Upload one reviewed image from a ChatGPT file parameter, HTTPS image, base64 image, or rendered figure into exercise-image storage. |
|
|
75
|
+
| `attach_exercise_figures` | write | Append, replace one figure type, or replace all figures on one writable exercise with an `updated_at` precondition. |
|
|
76
|
+
| `create_exercise` | write | Create one exercise in the selected organization. |
|
|
77
|
+
| `copy_exercise` | write | Copy one visible exercise into the selected organization. |
|
|
78
|
+
| `delete_exercise` | write | Soft-delete one unused writable exercise after `updated_at` and exact-ID confirmation checks. |
|
|
79
|
+
| `update_exercise` | write | Patch exercise fields with an `updated_at` precondition and shared-usage acknowledgement. |
|
|
80
|
+
| `set_exercise_visibility` | write | Make one writable exercise public or private when visibility controls are enabled. |
|
|
81
|
+
| `generate_exercise_translation_job` | write | Queue translation generation for one writable exercise. |
|
|
82
|
+
| `import_exercise` | write | Queue an exercise import from ChatGPT file parameters or HTTPS URLs. |
|
|
83
|
+
| `import_exercise_solution` | write | Queue a solution import for one exercise. |
|
|
84
|
+
| `search_sheets` | read | Search visible sheets, optionally by readiness issues. |
|
|
85
|
+
| `get_sheet` | read | Fetch full details for one visible sheet. |
|
|
86
|
+
| `list_sheet_series` | read | List the authoritative sheet-series hierarchy and valid assignment paths. |
|
|
87
|
+
| `list_sheet_versions` | read | List version history for one sheet owned by the granted organization. |
|
|
88
|
+
| `get_sheet_version` | read | Fetch one owned sheet version snapshot with referenced exercise details. |
|
|
89
|
+
| `get_sheet_issues` | read | Fetch actionable sheet issues: invalid LaTeX, missing translations, missing solutions, and missing scores. |
|
|
90
|
+
| `create_sheet` | write | Create one exercise sheet in the selected organization. |
|
|
91
|
+
| `copy_sheet` | write | Copy a visible sheet, either keeping exercise references or copying all visible exercises. |
|
|
92
|
+
| `delete_sheet` | write | Soft-delete one writable sheet after `updated_at` and exact-ID confirmation checks. |
|
|
93
|
+
| `update_sheet` | write | Patch sheet metadata with an `updated_at` precondition. |
|
|
94
|
+
| `bulk_update_sheets` | write | Dry-run or atomically apply up to 100 sheet patches using a confirmation digest. |
|
|
95
|
+
| `set_sheet_visibility` | write | Make one writable sheet public or private when visibility controls are enabled. |
|
|
96
|
+
| `append_exercises_to_sheet` | write | Append existing visible exercises to the end of one writable sheet. |
|
|
97
|
+
| `generate_sheet_translation_job` | write | Queue translation generation for one writable exercise sheet. |
|
|
98
|
+
| `list_folders` | read | List sheet folders in the selected organization. |
|
|
99
|
+
| `create_folder` | write | Create a sheet folder. |
|
|
100
|
+
| `rename_folder` | write | Rename a sheet folder. |
|
|
101
|
+
| `delete_folder` | write | Delete one empty sheet folder after exact-ID confirmation. |
|
|
102
|
+
| `validate_latex_snippets` | read | Validate proposed LaTeX snippets before writing. |
|
|
103
|
+
| `import_sheet` | write | Queue sheet imports from ChatGPT file parameters or HTTPS URLs. |
|
|
104
|
+
| `import_sheet_solutions` | write | Queue solution import for an existing sheet. |
|
|
105
|
+
| `list_jobs` | read | List jobs in the granted organization. |
|
|
106
|
+
| `get_job` | read | Fetch one job. |
|
|
107
|
+
| `wait_for_jobs` | read | Wait for one or more jobs to complete. |
|
|
108
|
+
| `send_user_feedback` | read | Send user-consented product feedback, bug reports, or blocked-request reports. |
|
|
109
|
+
| `send_agent_feedback` | read | Send agent-observed API, MCP, CLI, or documentation feedback. |
|
|
110
|
+
|
|
111
|
+
For `create_sheet`, pass `folderId` to create the sheet in a target folder. Omit it or pass `null` to create the sheet at the organization root.
|
|
112
|
+
|
|
113
|
+
Sheet-series writes are currently restricted to admin users and sheets owned by the selected organization. Use `list_sheet_series`, then call `bulk_update_sheets` with `mode: "dry_run"`. Apply the unchanged batch with the returned `confirmationDigest`; no idempotency key or separate idempotency table is used.
|
|
73
114
|
|
|
74
115
|
Delete tools require exact `confirmResourceId` matching the target ID. Exercise and sheet deletes also require the latest `expectedUpdatedAt`. Exercise deletes fail while the exercise is used by an active sheet, and folder deletes fail unless the folder is empty.
|
|
75
116
|
|
|
76
117
|
Visibility tools respect the existing ChalkSurf visibility feature flag. If visibility controls are disabled, they return `feature_disabled`. Publicization requires `confirmMakePublicResourceId`; private visibility changes do not.
|
|
77
118
|
|
|
119
|
+
Figure tools are available for agents to create and attach figures to exercises. The recommended flow is `figure_get_capabilities`, then one or more `figure_render_draft` calls with visual review, then `upload_exercise_figure`, then `attach_exercise_figures` using a fresh `get_exercise.updated_at` value. Figure drafts support semantic 2D constructions such as midpoints, projections, selected intersections, triangle centers, parallel/perpendicular lines, angle bisectors, incircles, diameter circles, and tangent circles; use assertions such as `angleBisected`, `tangent`, `pointOnSegment`, and `concurrent` to verify the intended relationships before upload.
|
|
120
|
+
|
|
121
|
+
### File Parameters
|
|
122
|
+
|
|
123
|
+
ChatGPT file uploads are advertised with `_meta["openai/fileParams"]`. For `import_exercise`, `import_exercise_solution`, `import_sheet`, and `import_sheet_solutions`, ChatGPT should pass uploaded files in top-level `file_id_N` arguments. The field names are model-facing: ChatGPT receives file IDs for those fields, then the harness passes ChalkSurf resolved file objects:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"organizationId": "00000000-0000-0000-0000-000000000000",
|
|
128
|
+
"sourceUrls": ["https://example.com/worksheet-part-1.pdf"],
|
|
129
|
+
"file_id_1": {
|
|
130
|
+
"download_url": "https://...",
|
|
131
|
+
"file_id": "file_...",
|
|
132
|
+
"mime_type": "application/pdf",
|
|
133
|
+
"file_name": "worksheet.pdf"
|
|
134
|
+
},
|
|
135
|
+
"file_id_2": {
|
|
136
|
+
"download_url": "https://...",
|
|
137
|
+
"file_id": "file_...",
|
|
138
|
+
"mime_type": "application/pdf",
|
|
139
|
+
"file_name": "worksheet-solution.pdf"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`download_url` and `file_id` are required by ChatGPT. `mime_type` and `file_name` are optional. The import tools declare `file_id_1` through `file_id_20`; `upload_exercise_figure` declares only `file_id_1`. `sourceUrls` and `file_id_N` fields can be used together in one import call. ChalkSurf downloads every temporary `download_url` immediately and queues the existing import job with copied storage files; ChatGPT download URLs are not persisted for later job processing.
|
|
145
|
+
|
|
146
|
+
Generic MCP clients should pass absolute HTTPS URLs in `sourceUrls` for import tools, or use `source.kind = "https_url"`, `"base64_image"`, or `"rendered_figure"` for `upload_exercise_figure`. The older import `sources` object-array shape is accepted temporarily for compatibility, but it is no longer the advertised MCP input shape.
|
|
147
|
+
|
|
78
148
|
No MCP tool currently transfers resources between organizations.
|
|
79
149
|
|
|
80
150
|
`send_user_feedback` and `send_agent_feedback` are not read-only operations, but they require only the `chalksurf:read` OAuth scope because they do not mutate ChalkSurf exercises, sheets, or folders. Use `send_user_feedback` only after the user explicitly agrees to send feedback. Use `send_agent_feedback` when the agent itself observes inconsistent behavior, inaccurate docs, or missing agent-facing API coverage.
|