@attentionform/astra-mcp-server 0.0.0-stage → 0.2.0

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 CHANGED
@@ -1,3 +1,501 @@
1
- # Temporary Holding Version
1
+ # @attentionform/astra-mcp-server
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Official Model Context Protocol (MCP) server for the ASTra document engine.
4
+
5
+ `@attentionform/astra-mcp-server` exposes a comprehensive, 19-tool agentic interface over standard I/O (`stdio`). It enables AI coding assistants, including **Claude Desktop**, **Cursor**, **Windsurf**, **Cline**, and custom LLM agents, to inspect, query, mutate, and export Microsoft Word (`.docx`) documents with transactional integrity and zero schema corruption.
6
+
7
+ ---
8
+
9
+ ## Quickstart
10
+
11
+ ### Run with `npx` (Recommended)
12
+
13
+ No installation required. Pass your document directory via `--allowed-dir`:
14
+
15
+ ```bash
16
+ npx -y @attentionform/astra-mcp-server --allowed-dir /path/to/your/documents
17
+ ```
18
+
19
+ > **Security Note:** ASTra enforces strict directory sandboxing. The server will only read and write files within directories explicitly declared via `--allowed-dir` (or the `ASTRA_EXTRA_DOC_ROOTS` environment variable). The path must be absolute and exist on disk. The named folders are the whole boundary: the system temp folder is not added. A symbolic link at or above a named folder is followed; a link below it that points outside it is refused.
20
+
21
+ **Validation.** `open_document` checks the file and reports `valid`, `invalid`, `timed-out` or `skipped`; it never refuses the open. A save is allowed when it adds no validator error beyond the ones the file had. Server flags: `--strict-validation` (also `ASTRA_STRICT_VALIDATION=1`) refuses every error; `--open-validation-timeout <ms>` (also `ASTRA_OPEN_VALIDATION_TIMEOUT_MS`) sets the wait at open, default 5000.
22
+
23
+ **Macros and size limits.** `open_document` takes `allowMacros` (keep macro parts) or `stripMacros` (remove the parts and every reference to them). The zip-bomb ceilings are `ASTRA_MAX_RATIO` (default 100) and `ASTRA_MAX_UNCOMPRESSED_BYTES`, read from the environment.
24
+
25
+ ### Global Installation
26
+
27
+ ```bash
28
+ npm install -g @attentionform/astra-mcp-server
29
+ astra-mcp-server --allowed-dir /path/to/your/documents
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Client Integration
35
+
36
+ Add ASTra to your AI agent with a simple JSON snippet:
37
+
38
+ ### 1. Claude Desktop
39
+ Add ASTra to your Claude Desktop configuration file:
40
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
41
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
42
+ - **Linux:** `~/.config/Claude/claude_desktop_config.json`
43
+
44
+ ```json
45
+ {
46
+ "mcpServers": {
47
+ "astra": {
48
+ "command": "npx",
49
+ "args": [
50
+ "-y",
51
+ "@attentionform/astra-mcp-server",
52
+ "--allowed-dir",
53
+ "/absolute/path/to/your/documents"
54
+ ],
55
+ "env": {
56
+ "NODE_ENV": "production"
57
+ }
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### 2. Cursor IDE
64
+ Create or edit `.cursor/mcp.json` in your project root:
65
+
66
+ ```json
67
+ {
68
+ "mcpServers": {
69
+ "astra": {
70
+ "command": "npx",
71
+ "args": [
72
+ "-y",
73
+ "@attentionform/astra-mcp-server",
74
+ "--allowed-dir",
75
+ "${workspaceFolder}"
76
+ ]
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### 3. Windsurf
83
+ Add to your Windsurf MCP configuration (`~/.codeium/windsurf/mcp_config.json`):
84
+
85
+ ```json
86
+ {
87
+ "mcpServers": {
88
+ "astra": {
89
+ "command": "npx",
90
+ "args": [
91
+ "-y",
92
+ "@attentionform/astra-mcp-server",
93
+ "--allowed-dir",
94
+ "/absolute/path/to/your/documents"
95
+ ]
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### 4. Cline (VS Code Extension)
102
+ In Cline's MCP settings tab, configure:
103
+ - **Server Name:** `astra`
104
+ - **Command:** `npx`
105
+ - **Args:** `["-y", "@attentionform/astra-mcp-server", "--allowed-dir", "${workspaceFolder}"]`
106
+
107
+ ### Schema freshness (when tools change)
108
+
109
+ Every served tool ships a version-stamped JSON copy under `schemas/mcp/` (`x-generated-from` names the server build). Clients cache those shapes:
110
+
111
+ - **Memory caches** (Claude Desktop for the app lifespan, Cursor and Zed per session): restart the host app to pick up new tools.
112
+ - **Disk caches** (file-based setups that vendor the JSON copies): re-run the dump, then point the client at the fresh dir:
113
+
114
+ ```bash
115
+ npx -y @attentionform/astra-mcp-server --dump-schemas ./fresh-schemas
116
+ npx -y @attentionform/astra-mcp-server --check-schemas ./fresh-schemas
117
+ ```
118
+
119
+ `--check-schemas` exits `0` when every stamp matches the installed server and prints a stale-file warning with exit `1` otherwise. CI regenerates and diffs `schemas/mcp/` on every push, so a schema change without refreshed copies fails the build.
120
+
121
+ ---
122
+
123
+ ## The 19 MCP Tools
124
+
125
+ ASTra provides a complete set of 19 tools organized by capability. The server returns all 19 tools over `tools/list`:
126
+
127
+ ### `open_document`
128
+ Opens a `.docx` file into an isolated in-memory editing session.
129
+
130
+ **Parameters:**
131
+ | Parameter | Type | Required | Description |
132
+ |---|---|:---:|---|
133
+ | `path` | `string` | Yes | Absolute path to `.docx` file inside an allowed directory. |
134
+ | `sessionId` | `string` | No | Server-minted session id (deprecated to supply; test-only). |
135
+ | `summaryOnly` | `boolean` | No | Return structural and style palette summary only. |
136
+ | `allowMacros` | `boolean` | No | Preserve macro parts byte-for-byte. |
137
+ | `stripMacros` | `boolean` | No | Strip macro parts upon loading. |
138
+ | `author` | `string` | No | Default author for tracked changes and comments in this session that do not name one (falls back to the server's `ASTRA_AUTHOR`, then `ASTra`). An operation's own `author` wins. |
139
+ | `validationTimeoutMs` | `integer` | No | How long to wait for the validator when the file is opened, in milliseconds. `0` skips the check. Default 5000, or the server flag `--open-validation-timeout` / `ASTRA_OPEN_VALIDATION_TIMEOUT_MS`. |
140
+
141
+ **Returns:** `{ ok: true, sessionId, revision, summary, evicted, validation }`. `validation` is `{ status: "valid" }`, `{ status: "invalid", preExistingErrors, messages, baselineComparable, note }` when the file already has validator errors, `{ status: "timed-out" }` or `{ status: "skipped" }`.
142
+
143
+ ---
144
+
145
+ ### `inspect_document`
146
+ Inspects document structure using Token-Optimized Outline Notation (TOON).
147
+
148
+ **Parameters:**
149
+ | Parameter | Type | Required | Description |
150
+ |---|---|:---:|---|
151
+ | `sessionId` | `string` | Yes | Active session identifier. |
152
+ | `fidelity` | `string` | No | `"compact"` (default), `"standard"`, or `"full"`. |
153
+ | `sectionId` | `string` | No | Restrict outline to a specific section. |
154
+ | `maxTextLength` | `number` | No | Truncate run text at character limit. |
155
+ | `offset` | `number` | No | Pagination start row (default: 0). |
156
+ | `limit` | `number` | No | Maximum rows to return (default: 50, max: 200). |
157
+ | `aroundNode` | `string` | No | Node ID to center the inspection window around. |
158
+ | `window` | `number` | No | Half-width of rows around `aroundNode` (default: 5). |
159
+ | `maxTokens` | `number` | No | Token budget cutoff on clean row boundary (200–8000). |
160
+
161
+ **Returns:** `{ ok: true, sessionId, revision, fidelity, palette, toonText, rowCount }`
162
+
163
+ ---
164
+
165
+ ### `search_content`
166
+ Fast text search returning matching stable node IDs and text snippets.
167
+
168
+ **Parameters:**
169
+ | Parameter | Type | Required | Description |
170
+ |---|---|:---:|---|
171
+ | `sessionId` | `string` | Yes | Active session identifier. |
172
+ | `query` | `string` | Yes | Search query string (1–500 characters). |
173
+ | `regex` | `boolean` | No | Treat query as regular expression (default: `false`). |
174
+
175
+ **Returns:** `{ ok: true, sessionId, matches: [{ id, preview, cells? }] }`. A table hit lists `cells`, up to five cell addresses such as `t_001:r3c1`, that you can pass as the `target` of `replace`, `style`, `namedStyle`, `clearFormat`, `hyperlink`, `bookmark` or `comment`. Cell addresses are `<tableId>:r<row>c<col>`, 1-based as `inspect_document` prints the grid (add `:p<n>` for a cell with several paragraphs).
176
+
177
+ ---
178
+
179
+ ### `execute_batch`
180
+ Executes an atomic array of typed operations with schema validation and rollback guarantees.
181
+
182
+ **Parameters:**
183
+ | Parameter | Type | Required | Description |
184
+ |---|---|:---:|---|
185
+ | `sessionId` | `string` | Yes | Active session identifier. |
186
+ | `operations` | `array` | Yes | Array of 1 to 500 typed operation objects. |
187
+ | `sequential` | `boolean` | No | Apply operations sequentially in order (default: `true`). |
188
+ | `rollbackOnError` | `boolean` | No | Roll back entire batch if any operation fails (default: `true`). |
189
+ | `maxSteps` | `number` | No | Maximum execution steps before aborting. |
190
+ | `allowedDir` | `string` | No | Jail directory for image `filePath` reads. |
191
+ | `styleGuide` | `string` | No | Per-batch style guide override (name or `.md` path). |
192
+
193
+ **Returns:** `{ ok: true, sessionId, appliedCount, revision, createdNodeIds }`
194
+
195
+ ---
196
+
197
+ ### `save_document`
198
+ Validates all modified XML parts against ECMA-376 schema and commits changes to disk.
199
+
200
+ **Parameters:**
201
+ | Parameter | Type | Required | Description |
202
+ |---|---|:---:|---|
203
+ | `sessionId` | `string` | Yes | Active session identifier. |
204
+ | `outPath` | `string` | No | Target path (defaults to original session path). |
205
+ | `message` | `string` | No | Commit log message for document history. |
206
+ | `author` | `string` | No | Author name for document history. |
207
+ | `allowMacros` | `boolean` | No | Explicit macro policy to keep macros on save. |
208
+ | `stripMacros` | `boolean` | No | Explicit macro policy to strip macros on save. |
209
+ | `strict` | `boolean` | No | Refuse every validator error, including errors the file already had when it was opened. Also refuses paragraphs that share a `w14:paraId`, which a save otherwise renumbers. Default: off, or the server flag `--strict-validation` / `ASTRA_STRICT_VALIDATION=1`. |
210
+
211
+ **Returns:** `{ ok: true, sessionId, path, revision, commitOid, validation }`. When the file already had validator errors and the edit added none, `validation` is `{ ok: false, tolerated: true, preExistingErrors, introducedErrors: 0, messages }`; otherwise `{ ok: true }`.
212
+
213
+ ---
214
+
215
+ ### `close_document`
216
+ Closes the active session and releases all in-memory resources.
217
+
218
+ **Parameters:**
219
+ | Parameter | Type | Required | Description |
220
+ |---|---|:---:|---|
221
+ | `sessionId` | `string` | Yes | Active session identifier. |
222
+
223
+ **Returns:** `{ ok: true, sessionId }`
224
+
225
+ ---
226
+
227
+ ### `new_document`
228
+ Creates a fresh `.docx` file from an executive template and opens it into a session.
229
+
230
+ **Parameters:**
231
+ | Parameter | Type | Required | Description |
232
+ |---|---|:---:|---|
233
+ | `outPath` | `string` | Yes | Destination file path inside an allowed directory. |
234
+ | `template` | `string` | No | Template type: `"report"`, `"memo"`, or `"blank"` (default: `"blank"`). |
235
+ | `force` | `boolean` | No | Overwrite existing file if it exists (default: `false`). |
236
+ | `styleGuide` | `string` | No | Bundled guide name or guide `.md` path to attach. |
237
+ | `author` | `string` | No | Default author for tracked changes and comments in this session that do not name one (falls back to the server's `ASTRA_AUTHOR`, then `ASTra`). An operation's own `author` wins. |
238
+ | `sessionId` | `string` | No | Server-minted session id (deprecated to supply; test-only). |
239
+
240
+ **Returns:** `{ ok: true, path, sessionId, revision, template, bytes }`
241
+
242
+ ---
243
+
244
+ ### `compose_document`
245
+ Compiles a Markdown string into OOXML structures and applies them cleanly to the document.
246
+
247
+ **Parameters:**
248
+ | Parameter | Type | Required | Description |
249
+ |---|---|:---:|---|
250
+ | `sessionId` | `string` | Yes | Active session identifier. |
251
+ | `markdown` | `string` | Yes | Markdown source text to compile and apply. |
252
+ | `allowedDir` | `string` | No | Jail directory for resolving relative images and charts. |
253
+ | `template` | `string` | No | Replace seed content for `"report"`, `"memo"`, or `"blank"`. |
254
+ | `styleGuide` | `string` | No | Bundled guide name or guide `.md` path to skin composition. |
255
+ | `dollarMath` | `boolean` | No | Treat `$...$` syntax as inline math (default: `false`). |
256
+
257
+ **Returns:** `{ ok: true, sessionId, appliedCount, revision, createdNodeIds, persistentIds? }`. `createdNodeIds` (`md_0001…`) work for the whole session; `persistentIds` maps each created paragraph to the id the saved file carries, for addressing it after the file is reopened (tables are renumbered by position, so they are not listed).
258
+
259
+ ---
260
+
261
+ An unchanged built-in template created in the current session has its sample content replaced when composed. If the template was edited, loaded from an external template, or reopened in a later session, compose preserves its existing content and appends the new content.
262
+
263
+ ### `import_document`
264
+ Ingests an on-disk Markdown file into an open session under directory sandboxing.
265
+
266
+ **Parameters:**
267
+ | Parameter | Type | Required | Description |
268
+ |---|---|:---:|---|
269
+ | `sessionId` | `string` | Yes | Active session identifier. |
270
+ | `path` | `string` | Yes | Path to on-disk Markdown file inside allowed directory. |
271
+ | `allowedDir` | `string` | No | Jail directory for resolving relative images and charts. |
272
+ | `template` | `string` | No | Verify template seed disposition (`"report"`, `"memo"`, `"blank"`). |
273
+ | `styleGuide` | `string` | No | Style guide attach (bundled name or guide `.md` path). |
274
+ | `dollarMath` | `boolean` | No | Treat `$...$` syntax as inline math (default: `false`). |
275
+
276
+ **Returns:** `{ ok: true, sessionId, appliedCount, revision }`
277
+
278
+ ---
279
+
280
+ ### `export_document`
281
+ Renders the current in-memory state to PDF, HTML, or Markdown.
282
+
283
+ **Parameters:**
284
+ | Parameter | Type | Required | Description |
285
+ |---|---|:---:|---|
286
+ | `sessionId` | `string` | Yes | Active session identifier. |
287
+ | `format` | `string` | Yes | Export format: `"pdf"`, `"html"`, or `"markdown"`. |
288
+ | `outPath` | `string` | No | Target destination file path inside allowed directory. |
289
+ | `tagged_pdf` | `boolean` | No | PDF only: tagged (accessible) render (default: `true`). |
290
+ | `tagged` | `boolean` | No | Alias of `tagged_pdf`. |
291
+ | `strict` | `boolean` | No | PDF only: fail closed on preflight blockers (default: `false`). |
292
+ | `imageMode` | `string` | No | Markdown only: `"file"` (requires `outPath`; extracts images into a unique generation under the asset directory, default when `outPath` is provided) or `"embed"` (base64 data URI). |
293
+ | `assetPrefix` | `string` | No | Markdown only: custom asset directory name/prefix when `imageMode` is `"file"`. |
294
+
295
+ **Returns:** `{ ok: true, format, path, bytes, content }`
296
+
297
+ ---
298
+
299
+ ### `visual_inspect`
300
+ Generates 2D spatial layout telemetry and optional headless page renders.
301
+
302
+ **Parameters:**
303
+ | Parameter | Type | Required | Description |
304
+ |---|---|:---:|---|
305
+ | `sessionId` | `string` | Yes | Active session identifier. |
306
+ | `pages` | `array` | No | 1-indexed page numbers to inspect/render (max 4). |
307
+ | `withVisual` | `boolean` | No | Generate headless rendered images (default: `false`). |
308
+ | `format` | `string` | No | Image format: `"png"` (default) or `"jpeg"`. |
309
+ | `jpegQuality` | `number` | No | JPEG quality factor (1–100). |
310
+ | `dpi` | `number` | No | Render resolution (72–300, default: `150`). |
311
+ | `outputDir` | `string` | No | With `withVisual`, write the images to this folder (created if missing) as `<document>-page-<n>.png`, for clients that cannot read the server's temp folder. Must be inside the allowed folders, like a document path. Default: the server's temp artifacts folder. |
312
+
313
+ **Returns:** `{ ok: true, sessionId, telemetry, images: [{ page, path }], outDir }`
314
+
315
+ The wireframe in `telemetry` shows `[TABLE: n cols]` with the header row and the first rows, `- ` and `1.` list markers, and `[CALLOUT]` for a shaded one-cell table.
316
+
317
+ ---
318
+
319
+ ### `get_document_history`
320
+ Retrieves past committed versions of the document.
321
+
322
+ **Parameters:**
323
+ | Parameter | Type | Required | Description |
324
+ |---|---|:---:|---|
325
+ | `sessionId` | `string` | Yes | Active session identifier. |
326
+ | `limit` | `number` | No | Max commit entries to retrieve (default: `20`, max: `100`). |
327
+ | `offset` | `number` | No | Pagination offset for commit log. |
328
+
329
+ **Returns:** `{ ok: true, history: [{ oid, message, author, timestamp }] }`
330
+
331
+ ---
332
+
333
+ ### `preview_revert`
334
+ Simulates a rollback without applying changes.
335
+
336
+ **Parameters:**
337
+ | Parameter | Type | Required | Description |
338
+ |---|---|:---:|---|
339
+ | `sessionId` | `string` | Yes | Active session identifier. |
340
+ | `steps` | `number` | No | Number of commits to roll back. |
341
+ | `commitOid` | `string` | No | Specific commit hash target to preview reversion. |
342
+
343
+ **Returns:** `{ ok: true, targetOid, affectedFiles, dirty }`
344
+
345
+ ---
346
+
347
+ ### `revert_document`
348
+ Rolls back the document state to a previous commit, creating an append-only restore commit.
349
+
350
+ **Parameters:**
351
+ | Parameter | Type | Required | Description |
352
+ |---|---|:---:|---|
353
+ | `sessionId` | `string` | Yes | Active session identifier. |
354
+ | `steps` | `number` | No | Number of commits to roll back. |
355
+ | `commitOid` | `string` | No | Specific commit hash target to restore. |
356
+ | `discardUnsaved` | `boolean` | No | Drop uncommitted changes (default: `false`). |
357
+ | `message` | `string` | No | Revert commit message (≤ 500 chars). |
358
+ | `author` | `string` | No | Author identifier for revert commit (≤ 100 chars). |
359
+ | `reason` | `string` | No | Audit reason string for revert log (≤ 500 chars). |
360
+
361
+ **Returns:** `{ ok: true, sessionId, path, revertedToCommit, revision }`
362
+
363
+ ---
364
+
365
+ ### `redo_document`
366
+ Re-applies the version undone by the last revert.
367
+
368
+ **Parameters:**
369
+ | Parameter | Type | Required | Description |
370
+ |---|---|:---:|---|
371
+ | `sessionId` | `string` | Yes | Active session identifier. |
372
+ | `message` | `string` | No | Redo commit message (≤ 500 chars). |
373
+ | `author` | `string` | No | Author identifier for redo commit (≤ 100 chars). |
374
+ | `reason` | `string` | No | Audit reason string for redo log (≤ 500 chars). |
375
+
376
+ **Returns:** `{ ok: true, sessionId, revision, commitOid }`
377
+
378
+ ---
379
+
380
+ ### `validate_document`
381
+ Preflight read-only OOXML schema audit for a session before committing changes.
382
+
383
+ **Parameters:**
384
+ | Parameter | Type | Required | Description |
385
+ |---|---|:---:|---|
386
+ | `sessionId` | `string` | Yes | Active session identifier. |
387
+
388
+ **Returns:** `{ ok: true, sessionId, revision, dirty, validation: { valid, errorCount, errors } }`
389
+
390
+ ---
391
+
392
+ ### `get_stats`
393
+ Token-cheap document census returning word, paragraph, table, image, and page counts.
394
+
395
+ **Parameters:**
396
+ | Parameter | Type | Required | Description |
397
+ |---|---|:---:|---|
398
+ | `sessionId` | `string` | Yes | Active session identifier. |
399
+
400
+ **Returns:** `{ ok: true, sessionId, revision, dirty, words, paragraphs, tables, images, pages }`
401
+
402
+ ---
403
+
404
+ ### `sanitize_document`
405
+ Scrub metadata, revision IDs, authors, comments, and PII from a document session.
406
+
407
+ **Parameters:**
408
+ | Parameter | Type | Required | Description |
409
+ |---|---|:---:|---|
410
+ | `sessionId` | `string` | Yes | Active session identifier. |
411
+ | `zeroRetention` | `boolean` | No | Purge all tracking metadata, revision IDs, authors, and EXIF. |
412
+ | `purgeRSIDs` | `boolean` | No | Strip revision save IDs (`w:rsidR`, `w:rsidRPr`, etc.). |
413
+ | `purgeAuthors` | `boolean` | No | Strip author identity metadata. |
414
+ | `purgeExif` | `boolean` | No | Strip metadata and EXIF profiles from embedded images. |
415
+ | `purgePII` | `boolean` | No | Redact potential PII patterns from text and comments. |
416
+ | `acceptAllRevisions` | `boolean` | No | Accept all tracked changes before scrubbing. |
417
+ | `stripComments` | `boolean` | No | Remove all comments and comment references. |
418
+ | `replacementAuthor` | `string` | No | Author replacement string (≤ 256 chars). |
419
+ | `allowMacros` | `boolean` | No | Preserve macro parts byte-for-byte during scrub. |
420
+ | `stripMacros` | `boolean` | No | Strip macro parts during scrub. |
421
+
422
+ **Returns:** `{ ok: true, sessionId, revision, dirty, removedRSIDs, purgedAuthors, strippedExifBytes, purgedPII, bodyPII, acceptedRevisions, strippedComments, strippedMacros, macroParts, filesTouched, droppedRogue }`
423
+
424
+ ---
425
+
426
+ ### `normalize_document`
427
+ Canonical repair for an open session. Runs the allowlist normalizer (schema sequence sorts and tag normalizations), then repairs known validator error kinds one rule at a time: element order, decimal sizes, on/off values, smart tags, duplicate shape types and a few others. A repair that changes the visible text or adds a validator error is dropped and listed in `rolledBack`. The tool does not claim the file is valid: `remaining` counts the validator errors left.
428
+
429
+ When the document has a history repository and the state before the repairs differs from the head, that state is committed first (`preStateCommit`). The next `save_document` records the result, so one `revert_document` with `steps: 1` returns to the state before the repairs.
430
+
431
+ **Parameters:**
432
+ | Parameter | Type | Required | Description |
433
+ |---|---|:---:|---|
434
+ | `sessionId` | `string` | Yes | Active session identifier. |
435
+
436
+ **Returns:** `{ ok: true, sessionId, revision, dirty, normalized, remaining, rolledBack, preStateCommit?, validation }`. `normalized` lists every rewrite. `remaining` is the number of validator errors left, or `-1` when the validator did not run. `rolledBack` is `[{ rule, reason }]`.
437
+
438
+ ---
439
+
440
+ ## Recommended Agent Lifecycle Flow
441
+
442
+ AI agents should follow this standard execution sequence:
443
+
444
+ ```text
445
+ open_document (or new_document)
446
+ ↓
447
+ inspect_document (get TOON outline & node IDs)
448
+ ↓
449
+ search_content (optional: pinpoint exact target text)
450
+ ↓
451
+ execute_batch (apply atomic mutations with rollback protection)
452
+ ↓
453
+ visual_inspect / export_document (verify visual presentation)
454
+ ↓
455
+ save_document (validate ECMA-376 schema & commit to disk)
456
+ ↓
457
+ close_document (release session memory)
458
+ ```
459
+
460
+ ---
461
+
462
+ ## Error Handling & Remediation
463
+
464
+ When a tool operation cannot be completed, ASTra responds with structured error details:
465
+
466
+ ```json
467
+ {
468
+ "ok": false,
469
+ "code": "E_VALIDATION",
470
+ "message": "Invalid child element sequence in w:pPr",
471
+ "remedy": "Ensure paragraph property tags follow ISO/IEC 29500 ordering rules.",
472
+ "isError": true
473
+ }
474
+ ```
475
+
476
+ ### Common Error Codes
477
+ - `E_SANDBOX`: Requested file path lies outside declared `--allowed-dir` directories.
478
+ - `E_VALIDATION`: Operation parameters failed Zod schema checks or OOXML validation.
479
+ - `E_SESSION`: Session ID does not exist or has timed out.
480
+ - `E_CONFLICT`: Operation would overwrite an existing file without `force: true`.
481
+ - `E_DEPENDENCY`: External dependency (e.g. LibreOffice for PDF export) is not found in `PATH`.
482
+
483
+ ---
484
+
485
+ ## Local Development
486
+
487
+ To run or debug `@attentionform/astra-mcp-server` locally from this repository:
488
+
489
+ ```bash
490
+ # Build package bundles
491
+ npm run build:packages
492
+
493
+ # Run local MCP server directly with node
494
+ node packages/mcp-server/dist/index.js --allowed-dir /path/to/docs
495
+ ```
496
+
497
+ ---
498
+
499
+ ## License
500
+
501
+ Business Source License 1.1 (`BUSL-1.1`): source-available, free for individuals, education, non-profits, public bodies and small businesses; other production use needs a commercial license. Each version converts to Apache-2.0 four years after release. See [LICENSE](LICENSE) and write to astra@attentionform.com for a commercial license.
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @attentionform/astra-mcp-server — Track-B lean-6 MCP server over stdio.
4
+ *
5
+ * Exposes 19 tools (lean-6 + new_document + compose_document + export + visual + git history + document audit):
6
+ * open_document / inspect_document / search_content /
7
+ * execute_batch / save_document / close_document / new_document /
8
+ * compose_document /
9
+ * export_document / visual_inspect /
10
+ * get_document_history / preview_revert / revert_document / redo_document /
11
+ * validate_document / get_stats / sanitize_document / normalize_document / import_document
12
+ *
13
+ * Engine wiring:
14
+ * the session store + lean-6 handlers live in the local lib
15
+ * (`./lib/session-store.ts`, `./lib/mcp-tool-adapter.ts`).
16
+ * Tool names, input shapes and the {ok:false,code,message,remedy} error contract
17
+ * stay identical across refactors (clients pin them).
18
+ *
19
+ * Transport notes:
20
+ * - stdio only (stdout is the JSON-RPC wire — NEVER log to stdout).
21
+ * - every handler result is serialized as a single text content frame;
22
+ * {ok:false,...} results are additionally flagged isError:true
23
+ * (fail-closed: the model must fix-and-retry per `remedy`, never assume
24
+ * the mutation landed).
25
+ */
26
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
27
+ import { type McpSessionStore } from './lib/session-store';
28
+ import { GIT_HISTORY_TOOL_NAMES, LEAN6_TOOL_NAMES, PARITY_TOOL_NAMES, type GitHistoryToolName, type Lean6ToolName, type ParityToolName } from './lib/mcp-tool-adapter';
29
+ export declare const SERVER_NAME = "astra-mcp-server";
30
+ export declare const SERVER_VERSION: string;
31
+ /** Re-exported so smoke tests can pin the locked tool set without transport. */
32
+ export { LEAN6_TOOL_NAMES, GIT_HISTORY_TOOL_NAMES, PARITY_TOOL_NAMES };
33
+ export type { Lean6ToolName, GitHistoryToolName, ParityToolName };
34
+ /**
35
+ * Ordered tool names served on stdio (lean-6 + new_document + compose_document +
36
+ * export + visual + git history + document audit). Single list so --help and the serving line agree.
37
+ */
38
+ export declare function getServedToolNames(): string[];
39
+ /** Usage text for --help and unknown-flag errors. Built from live constants. */
40
+ export declare function buildUsageText(): string;
41
+ /** Exit code for unknown flags / missing option values (usage goes to stderr). */
42
+ export declare const CLI_USAGE_ERROR = 2;
43
+ /**
44
+ * Parse CLI arguments and environment variables for allowed directories (--allowed-dir / ASTRA_EXTRA_DOC_ROOTS).
45
+ * Appends valid directories to ASTRA_EXTRA_DOC_ROOTS so the sandbox session store and export tools permit access.
46
+ * Dash-leading --allowed-dir values are rejected (never added); parsing stops
47
+ * at the first `--` end-of-options marker so flags after it stay positional.
48
+ */
49
+ export declare function initAllowedDirs(argv?: string[]): void;
50
+ /**
51
+ * Read a `--flag <dir>` / `--flag=<dir>` value from argv (first win).
52
+ * Returns undefined when the flag is absent. Validation (missing or
53
+ * dash-leading value) happens in main() before this runs.
54
+ */
55
+ export declare function takeDirFlag(argv: readonly string[], flag: string): string | undefined;
56
+ /**
57
+ * Builds the MCP server bound to `store` (19 tools: lean-6 + new_document + compose_document + export + visual + git history + document audit).
58
+ * A fresh store is created per call when omitted (no module-level singleton —
59
+ * matches the backend session-store ownership rule).
60
+ */
61
+ export declare function createAstraMcpServer(store?: McpSessionStore): McpServer;
62
+ /** stdio entrypoint: handle --help/--version/unknown flags, else connect and serve until the transport closes. */
63
+ export declare function main(argv?: string[]): Promise<number>;