@chalksurf/cli 0.3.1 → 0.3.4
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 +10 -0
- package/dist/bin/chalksurf.js +7119 -1681
- package/docs/agents.md +119 -72
- package/docs/exit-codes.md +6 -1
- package/docs/manual.md +29 -0
- package/docs/mcp.md +125 -43
- 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,37 +79,47 @@ 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
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
|
|
|
101
|
-
|
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
82
|
+
| Goal | CLI command |
|
|
83
|
+
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| List organization-owned sheets | `chalksurf sheet list --limit 100 --json` |
|
|
85
|
+
| Fetch one sheet | `chalksurf sheet get SHEET_ID --json` |
|
|
86
|
+
| List owned sheet versions | `chalksurf sheet versions SHEET_ID --json` |
|
|
87
|
+
| Fetch one owned sheet version | `chalksurf sheet version SHEET_ID VERSION_ID --json` |
|
|
88
|
+
| Get a sheet repair queue | `chalksurf sheet issues SHEET_ID --json` |
|
|
89
|
+
| Create a sheet | `chalksurf sheet create --input-json JSON --json` |
|
|
90
|
+
| Copy a sheet | `chalksurf sheet copy SHEET_ID "New name" --exercise-copy-mode keep_references --json` |
|
|
91
|
+
| Create an editable variant sheet | `chalksurf sheet copy SHEET_ID "Variant name" --exercise-copy-mode copy_all_exercises --json` |
|
|
92
|
+
| Append existing exercises to a sheet | `chalksurf sheet append SHEET_ID EXERCISE_ID... --json` |
|
|
93
|
+
| Patch sheet metadata | `chalksurf sheet update SHEET_ID --expected-updated-at ISO --patch-json JSON --json` |
|
|
94
|
+
| List valid sheet-series paths | `chalksurf sheet series list --subject math --json` |
|
|
95
|
+
| Validate/apply bulk sheet patches | `chalksurf sheet bulk-update --input batch.json --json` |
|
|
96
|
+
| Set sheet visibility | `chalksurf sheet set-visibility SHEET_ID --public --expected-updated-at ISO --confirm-make-public-resource-id SHEET_ID --json` |
|
|
97
|
+
| Delete a sheet | `chalksurf sheet delete SHEET_ID --expected-updated-at ISO --confirm-resource-id SHEET_ID --json` |
|
|
98
|
+
| List folders | `chalksurf sheet folder list --json` |
|
|
99
|
+
| Create a folder | `chalksurf sheet folder create "Folder name" --parent-id FOLDER_ID --json` |
|
|
100
|
+
| Rename a folder | `chalksurf sheet folder rename FOLDER_ID "New name" --json` |
|
|
101
|
+
| Delete an empty folder | `chalksurf sheet folder delete FOLDER_ID --confirm-resource-id FOLDER_ID --json` |
|
|
102
|
+
| Fetch one exercise | `chalksurf exercise get EXERCISE_ID --json` |
|
|
103
|
+
| List valid exercise labels | `chalksurf exercise labels --json` |
|
|
104
|
+
| Inspect exercise usage | `chalksurf exercise usage EXERCISE_ID --json` |
|
|
105
|
+
| Inspect figure building blocks | `chalksurf figure capabilities --json` |
|
|
106
|
+
| Render a draft figure | `chalksurf figure render-draft --input-json JSON --output figure.png --json` |
|
|
107
|
+
| Upload and attach a figure image | `chalksurf exercise figure upload EXERCISE_ID ./figure.png --figure-type text --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
|
|
|
121
|
+
For reviewed bulk sheet updates, prefer `--input batch.json` or pipe the same object through `--input -`. Keep `--input-json` for short inline payloads. Submit the unchanged update list in dry-run and apply modes, copy the returned `confirmationDigest` into the apply object, and preserve both outputs and the apply receipt.
|
|
122
|
+
|
|
109
123
|
For `--private`, visibility commands do not require `--confirm-make-public-resource-id`. If visibility controls are disabled for the selected organization/user, the CLI and MCP return `feature_disabled`.
|
|
110
124
|
|
|
111
125
|
For deletes, fetch the resource immediately before deleting, use that `updated_at` as `--expected-updated-at`, and pass the target ID again as `--confirm-resource-id`. Exercise deletes fail while the exercise is used by any active sheet. Folder deletes fail unless the folder has no child folders and no active child sheets.
|
|
@@ -128,7 +142,7 @@ chalksurf --profile prod-codex exercise validate-latex \
|
|
|
128
142
|
--json
|
|
129
143
|
```
|
|
130
144
|
|
|
131
|
-
4. Patch the owning exercise or sheet with the `updated_at` value from the latest `get` result
|
|
145
|
+
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
146
|
|
|
133
147
|
```bash
|
|
134
148
|
chalksurf --profile prod-codex exercise update EXERCISE_ID \
|
|
@@ -142,6 +156,31 @@ chalksurf --profile prod-codex exercise update EXERCISE_ID \
|
|
|
142
156
|
|
|
143
157
|
Do not pass `--allow-shared-exercise-update` unless the user has acknowledged that the same exercise is used outside the target sheet.
|
|
144
158
|
|
|
159
|
+
## Figure Workflow: Draft, Review, Attach
|
|
160
|
+
|
|
161
|
+
1. Inspect available building blocks:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
chalksurf --profile prod-codex figure capabilities --json
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
2. Render a semantic draft and save the PNG for visual inspection:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
chalksurf --profile prod-codex figure render-draft \
|
|
171
|
+
--input-json '{"canvas":{"width":320,"height":240},"objects":[{"id":"A","type":"point","at":{"x":0,"y":0}}]}' \
|
|
172
|
+
--output figure.png \
|
|
173
|
+
--json
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
3. Upload and attach the reviewed image to its exercise:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
chalksurf --profile prod-codex exercise figure upload EXERCISE_ID figure.png \
|
|
180
|
+
--figure-type text \
|
|
181
|
+
--json
|
|
182
|
+
```
|
|
183
|
+
|
|
145
184
|
## Variant Workflow: Create A Slightly Easier Sheet
|
|
146
185
|
|
|
147
186
|
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,48 +199,56 @@ Use `keep_references` only when the user wants a new sheet arrangement that stil
|
|
|
160
199
|
|
|
161
200
|
MCP clients should use tool discovery from the client. The ChalkSurf MCP endpoint exposes the same resource primitives under snake_case names:
|
|
162
201
|
|
|
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
|
-
| `sheet
|
|
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
|
-
| `
|
|
203
|
-
|
|
204
|
-
|
|
202
|
+
| CLI command | MCP tool |
|
|
203
|
+
| -------------------------- | ----------------------------------- |
|
|
204
|
+
| `auth status` | `get_auth_status` |
|
|
205
|
+
| `org list` | `list_organizations` |
|
|
206
|
+
| `exercise search` | `search_exercises` |
|
|
207
|
+
| `exercise get` | `get_exercise` |
|
|
208
|
+
| `exercise labels` | `list_exercise_labels` |
|
|
209
|
+
| `exercise usage` | `get_exercise_usage` |
|
|
210
|
+
| `figure capabilities` | `figure_get_capabilities` |
|
|
211
|
+
| `figure render-draft` | `figure_render_draft` |
|
|
212
|
+
| `exercise figure upload` | `upload_exercise_figure` |
|
|
213
|
+
| `exercise create` | `create_exercise` |
|
|
214
|
+
| `exercise copy` | `copy_exercise` |
|
|
215
|
+
| `exercise update` | `update_exercise` |
|
|
216
|
+
| `exercise set-visibility` | `set_exercise_visibility` |
|
|
217
|
+
| `exercise translate` | `generate_exercise_translation_job` |
|
|
218
|
+
| `exercise delete` | `delete_exercise` |
|
|
219
|
+
| `exercise validate-latex` | `validate_latex_snippets` |
|
|
220
|
+
| `exercise import` | `import_exercise` |
|
|
221
|
+
| `exercise import-solution` | `import_exercise_solution` |
|
|
222
|
+
| `sheet list` | `list_sheets` |
|
|
223
|
+
| `sheet search` | `search_sheets` |
|
|
224
|
+
| `sheet get` | `get_sheet` |
|
|
225
|
+
| `sheet versions` | `list_sheet_versions` |
|
|
226
|
+
| `sheet version` | `get_sheet_version` |
|
|
227
|
+
| `sheet issues` | `get_sheet_issues` |
|
|
228
|
+
| `sheet create` | `create_sheet` |
|
|
229
|
+
| `sheet copy` | `copy_sheet` |
|
|
230
|
+
| `sheet append` | `append_exercises_to_sheet` |
|
|
231
|
+
| `sheet update` | `update_sheet` |
|
|
232
|
+
| `sheet series list` | `list_sheet_series` |
|
|
233
|
+
| `sheet bulk-update` | `bulk_update_sheets` |
|
|
234
|
+
| `sheet set-visibility` | `set_sheet_visibility` |
|
|
235
|
+
| `sheet translate` | `generate_sheet_translation_job` |
|
|
236
|
+
| `sheet delete` | `delete_sheet` |
|
|
237
|
+
| `sheet import` | `import_sheet` |
|
|
238
|
+
| `sheet import-solutions` | `import_sheet_solutions` |
|
|
239
|
+
| `sheet folder list` | `list_folders` |
|
|
240
|
+
| `sheet folder create` | `create_folder` |
|
|
241
|
+
| `sheet folder rename` | `rename_folder` |
|
|
242
|
+
| `sheet folder delete` | `delete_folder` |
|
|
243
|
+
| `job list` | `list_jobs` |
|
|
244
|
+
| `job get` | `get_job` |
|
|
245
|
+
| `job wait` | `wait_for_jobs` |
|
|
246
|
+
| `feedback user` | `send_user_feedback` |
|
|
247
|
+
| `feedback agent` | `send_agent_feedback` |
|
|
248
|
+
|
|
249
|
+
`sheet bulk-update` file/stdin handling is a CLI transport convenience. MCP clients pass the same strict object directly to `bulk_update_sheets`; the dry-run, confirmation-digest, batch limit, and atomic-apply contract is identical.
|
|
250
|
+
|
|
251
|
+
MCP calls authenticate through ChalkSurf OAuth, not CLI tokens. Tools advertise `chalksurf:read` or `chalksurf:write` during authorization, while the editable MCP grant's current per-organization permission is the authoritative runtime read/write boundary. For normal execution, each organization-scoped MCP call must pass a full `organizationId` from `get_auth_status` or `list_organizations`. If it is unknown, pass `organizationId: null`; no operation runs, and the response returns the complete current organization catalog for retry. `organization_selection_required` means a UUID must be selected, while `organization_access_denied` means the supplied UUID is not currently usable. Grant and membership edits take effect on the next HTTP request without reloading tools or issuing a new access token. Never infer the organization from a resource ID. Organization-independent tools omit the field, though `list_exercise_labels`, `list_sheet_series`, and `validate_latex_snippets` temporarily ignore an optional legacy UUID from cached tool definitions. ChalkSurf serves modern MCP `2026-07-28` and stateless legacy `2025-11-25` on the same endpoint.
|
|
205
252
|
|
|
206
253
|
## Feedback
|
|
207
254
|
|
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
|
@@ -175,12 +175,31 @@ Add `--wait` to either translate command to wait for the queued translation job
|
|
|
175
175
|
|
|
176
176
|
Search commands default to `--ownership own`, which means resources in the selected organization.
|
|
177
177
|
|
|
178
|
+
List every sheet owned by the selected organization, including folder paths and current series assignments:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
chalksurf sheet list --limit 100 --json
|
|
182
|
+
chalksurf sheet list --folder-id FOLDER_ID --include-descendants --json
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`sheet list` is for folder-hierarchy inventory. Use `sheet search` for text, subject, ownership, readiness, series, or edition-year predicates.
|
|
186
|
+
|
|
178
187
|
Find exercise sheets by title:
|
|
179
188
|
|
|
180
189
|
```bash
|
|
181
190
|
chalksurf sheet search --text "OKTV 2014"
|
|
182
191
|
```
|
|
183
192
|
|
|
193
|
+
Find sheets from one series and edition-year range:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
chalksurf sheet search \
|
|
197
|
+
--series-path hungary.oktv.mathematics \
|
|
198
|
+
--from-year 1980 \
|
|
199
|
+
--to-year 1990 \
|
|
200
|
+
--json
|
|
201
|
+
```
|
|
202
|
+
|
|
184
203
|
Find exercises by text:
|
|
185
204
|
|
|
186
205
|
```bash
|
|
@@ -234,6 +253,16 @@ chalksurf exercise update 00000000-0000-4000-8000-000000000002 \
|
|
|
234
253
|
|
|
235
254
|
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
255
|
|
|
256
|
+
Admin-only sheet-series labeling supports a two-step bulk flow:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
chalksurf sheet series list --subject math --json
|
|
260
|
+
chalksurf sheet bulk-update --input batch-001.dry-run.json --json
|
|
261
|
+
chalksurf sheet bulk-update --input batch-001.apply.json --json
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Use `--input -` to read the object from stdin, or `--input-json` for short inline JSON. Exactly one input option is required. The exact same update list must be submitted in both calls; only change `mode` and add the returned `confirmationDigest`. A batch contains at most 100 sheets, applies atomically, and cannot update sheets outside the selected organization.
|
|
265
|
+
|
|
237
266
|
Manage folders:
|
|
238
267
|
|
|
239
268
|
```bash
|
package/docs/mcp.md
CHANGED
|
@@ -5,11 +5,23 @@ ChalkSurf exposes a remote MCP endpoint for agent workflows that need the same c
|
|
|
5
5
|
## Endpoint And Auth
|
|
6
6
|
|
|
7
7
|
- Endpoint: `/mcp` on the ChalkSurf API host.
|
|
8
|
+
- Protocols: modern `2026-07-28` and stateless legacy `2025-11-25` are both supported on the same endpoint.
|
|
8
9
|
- Authentication: OAuth access tokens issued through the ChalkSurf MCP authorization flow.
|
|
9
10
|
- CLI tokens and browser session tokens are rejected on `/mcp`.
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
|
|
11
|
+
- Tools advertise `chalksurf:read` or `chalksurf:write` during OAuth authorization. The editable MCP grant's current
|
|
12
|
+
per-organization permission is the authoritative runtime read/write boundary, so changing the grant does not require
|
|
13
|
+
issuing a new access token.
|
|
14
|
+
- Organization-scoped tools require an explicit `organizationId` argument for normal execution.
|
|
15
|
+
|
|
16
|
+
Pass the full organization UUID returned by `get_auth_status` or `list_organizations`. If the organization is unknown,
|
|
17
|
+
pass `organizationId: null`; the tool performs no operation and returns `organization_selection_required` with the
|
|
18
|
+
complete current organization catalog. A supplied UUID that is no longer usable returns `organization_access_denied`
|
|
19
|
+
with the same catalog. Retry the same tool with the selected UUID. Grant and membership changes are loaded on the next
|
|
20
|
+
HTTP request, so clients do not need to reload tool definitions. Never infer an organization from a resource ID.
|
|
21
|
+
|
|
22
|
+
`get_auth_status`, `list_organizations`, `list_exercise_labels`, `list_sheet_series`, `validate_latex_snippets`, and the
|
|
23
|
+
figure capability/rendering tools are organization-independent. The three newly global tools temporarily accept and
|
|
24
|
+
ignore an optional UUID from cached legacy tool definitions.
|
|
13
25
|
|
|
14
26
|
MCP clients should use their built-in tool listing/search. ChalkSurf does not expose a second search abstraction just to rediscover tools.
|
|
15
27
|
|
|
@@ -28,53 +40,123 @@ Read tools return structured resource data. Write tools return a structured `rec
|
|
|
28
40
|
|
|
29
41
|
Treat write receipts as an agent audit log. They are suitable for user-visible summaries after an agent edits a sheet.
|
|
30
42
|
|
|
43
|
+
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.
|
|
44
|
+
|
|
45
|
+
Successful exercise create/update receipts include `details.latexValidation` with one of these scopes:
|
|
46
|
+
|
|
47
|
+
- `all_translation_fields` for exercise creates.
|
|
48
|
+
- `changed_translation_fields` for exercise updates that submitted translation fields.
|
|
49
|
+
- `none` when an exercise update changed no translation content.
|
|
50
|
+
|
|
51
|
+
If `create_exercise` or `update_exercise` rejects invalid LaTeX, the tool result has `isError: true` and structured content shaped like:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"isError": true,
|
|
56
|
+
"error": {
|
|
57
|
+
"code": "invalid_latex",
|
|
58
|
+
"message": "invalid_latex: translations.english.exercise_text",
|
|
59
|
+
"agentErrorDetails": {
|
|
60
|
+
"type": "invalid_latex",
|
|
61
|
+
"summary": {
|
|
62
|
+
"checkedSnippetCount": 1,
|
|
63
|
+
"invalidSnippetCount": 1,
|
|
64
|
+
"affectedPathCount": 1
|
|
65
|
+
},
|
|
66
|
+
"results": []
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
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.
|
|
73
|
+
|
|
31
74
|
## Tool Surface
|
|
32
75
|
|
|
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
|
-
| `
|
|
76
|
+
| Tool | Permission | Purpose |
|
|
77
|
+
| ----------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
78
|
+
| `get_auth_status` | read | Confirm the authenticated user and return the complete current organization catalog. |
|
|
79
|
+
| `list_organizations` | read | Return the complete current organizations usable through the MCP grant and membership. |
|
|
80
|
+
| `search_exercises` | read | Search exercises by text, labels, status, ownership, age, difficulty, or semantic query. |
|
|
81
|
+
| `get_exercise` | read | Fetch full details for one visible exercise. |
|
|
82
|
+
| `list_exercise_labels` | read | List the canonical exercise label taxonomy agents may write to exercises. |
|
|
83
|
+
| `get_exercise_usage` | read | Inspect which sheets use one visible exercise. |
|
|
84
|
+
| `figure_get_capabilities` | read | Inspect supported semantic 2D figure objects, construction definitions, assertions, limits, and snippets. |
|
|
85
|
+
| `figure_render_draft` | read | Render a semantic figure draft to SVG/PNG metadata, PNG image content, diagnostics, assertions, and review hints. |
|
|
86
|
+
| `upload_exercise_figure` | write | Upload and attach one reviewed image from a ChatGPT file parameter, HTTPS image, base64 image, or rendered figure to an exercise. |
|
|
87
|
+
| `create_exercise` | write | Create one exercise in the selected organization. |
|
|
88
|
+
| `copy_exercise` | write | Copy one visible exercise into the selected organization. |
|
|
89
|
+
| `delete_exercise` | write | Soft-delete one unused writable exercise after `updated_at` and exact-ID confirmation checks. |
|
|
90
|
+
| `update_exercise` | write | Patch exercise fields with an `updated_at` precondition and shared-usage acknowledgement. |
|
|
91
|
+
| `set_exercise_visibility` | write | Make one writable exercise public or private when visibility controls are enabled. |
|
|
92
|
+
| `generate_exercise_translation_job` | write | Queue translation generation for one writable exercise. |
|
|
93
|
+
| `import_exercise` | write | Queue an exercise import from ChatGPT file parameters or HTTPS URLs. |
|
|
94
|
+
| `import_exercise_solution` | write | Queue a solution import for one exercise. |
|
|
95
|
+
| `search_sheets` | read | Search visible sheets by text, subject, ownership, readiness, series, or edition year. |
|
|
96
|
+
| `list_sheets` | read | List sheets owned by the selected organization, including folder paths and current series assignments. |
|
|
97
|
+
| `get_sheet` | read | Fetch full details for one visible sheet. |
|
|
98
|
+
| `list_sheet_series` | read | List the authoritative sheet-series hierarchy and valid assignment paths. |
|
|
99
|
+
| `list_sheet_versions` | read | List version history for one sheet owned by the granted organization. |
|
|
100
|
+
| `get_sheet_version` | read | Fetch one owned sheet version snapshot with referenced exercise details. |
|
|
101
|
+
| `get_sheet_issues` | read | Fetch actionable sheet issues: invalid LaTeX, missing translations, missing solutions, and missing scores. |
|
|
102
|
+
| `create_sheet` | write | Create one exercise sheet in the selected organization. |
|
|
103
|
+
| `copy_sheet` | write | Copy a visible sheet, either keeping exercise references or copying all visible exercises. |
|
|
104
|
+
| `delete_sheet` | write | Soft-delete one writable sheet after `updated_at` and exact-ID confirmation checks. |
|
|
105
|
+
| `update_sheet` | write | Patch sheet metadata with an `updated_at` precondition. |
|
|
106
|
+
| `bulk_update_sheets` | write | Dry-run or atomically apply up to 100 sheet patches using a confirmation digest. |
|
|
107
|
+
| `set_sheet_visibility` | write | Make one writable sheet public or private when visibility controls are enabled. |
|
|
108
|
+
| `append_exercises_to_sheet` | write | Append existing visible exercises to the end of one writable sheet. |
|
|
109
|
+
| `generate_sheet_translation_job` | write | Queue translation generation for one writable exercise sheet. |
|
|
110
|
+
| `list_folders` | read | List sheet folders in the selected organization. |
|
|
111
|
+
| `create_folder` | write | Create a sheet folder. |
|
|
112
|
+
| `rename_folder` | write | Rename a sheet folder. |
|
|
113
|
+
| `delete_folder` | write | Delete one empty sheet folder after exact-ID confirmation. |
|
|
114
|
+
| `validate_latex_snippets` | read | Validate proposed LaTeX snippets before writing. |
|
|
115
|
+
| `import_sheet` | write | Queue sheet imports from ChatGPT file parameters or HTTPS URLs. |
|
|
116
|
+
| `import_sheet_solutions` | write | Queue solution import for an existing sheet. |
|
|
117
|
+
| `list_jobs` | read | List jobs in the granted organization. |
|
|
118
|
+
| `get_job` | read | Fetch one job. |
|
|
119
|
+
| `wait_for_jobs` | read | Wait for one or more jobs to complete. |
|
|
120
|
+
| `send_user_feedback` | read | Send user-consented product feedback, bug reports, or blocked-request reports. |
|
|
121
|
+
| `send_agent_feedback` | read | Send agent-observed API, MCP, CLI, or documentation feedback. |
|
|
122
|
+
|
|
123
|
+
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.
|
|
124
|
+
|
|
125
|
+
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. CLI `--input` and stdin support are transport conveniences only: MCP clients pass the same strict bulk object directly.
|
|
73
126
|
|
|
74
127
|
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
128
|
|
|
76
129
|
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
130
|
|
|
131
|
+
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` with the target `exerciseId`. Upload and attachment are one operation. 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.
|
|
132
|
+
|
|
133
|
+
### File Parameters
|
|
134
|
+
|
|
135
|
+
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:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"organizationId": "00000000-0000-0000-0000-000000000000",
|
|
140
|
+
"sourceUrls": ["https://example.com/worksheet-part-1.pdf"],
|
|
141
|
+
"file_id_1": {
|
|
142
|
+
"download_url": "https://...",
|
|
143
|
+
"file_id": "file_...",
|
|
144
|
+
"mime_type": "application/pdf",
|
|
145
|
+
"file_name": "worksheet.pdf"
|
|
146
|
+
},
|
|
147
|
+
"file_id_2": {
|
|
148
|
+
"download_url": "https://...",
|
|
149
|
+
"file_id": "file_...",
|
|
150
|
+
"mime_type": "application/pdf",
|
|
151
|
+
"file_name": "worksheet-solution.pdf"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`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.
|
|
157
|
+
|
|
158
|
+
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.
|
|
159
|
+
|
|
78
160
|
No MCP tool currently transfers resources between organizations.
|
|
79
161
|
|
|
80
162
|
`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.
|