core preset is an actions-only LLM surface: instead of many low-level tools, the model gets exactly two —
Every action wraps the underlying Document API operations with product semantics: it resolves targets deterministically, applies the edit, re-inspects the document, and returns a receipt with real pre/post evidence — so your agent loop (and your users) can trust what actually happened.
The default preset is still
legacy (the grouped intent tools documented in the overview). The core preset is opt-in: pass preset: 'core' everywhere.
Quick start
- Node.js
- Python
Reading: superdoc_inspect
superdoc_inspect returns a stable snapshot the model can target edits against. Prefer the narrowest inspect that answers the question:
blocks, lists, tables, comments, trackedChanges, sections, headerFooters, styles, contentControls, fields, hyperlinks, bookmarks, permissionRanges, images.
Large documents: windowed reads
For long documents, read blocks in contiguous windows instead of one giant snapshot. Ordinals are absolute, so windows line up across calls:omitEmptyBlocks and dropTextPreview trim the payload for a pure reading pass; blockTextLimit caps per-block text length. This keeps a single inspect call from dominating your context window (every tool result lives in conversation history and is re-billed as prompt tokens on every later turn).
All ordinals shown by
superdoc_inspect (blockOrdinal, paragraphOrdinal, headingOrdinal, tableOrdinal, …) are 1-based, and selectors accept the same 1-based values.Editing: superdoc_perform_action
One tool, one action argument, flat parameters. The dispatcher statically validates arguments against the action’s declared schema (unknown keys are rejected with a descriptive error) before anything touches the document.
Targeting: selectors
Actions that operate on a specific block accept aselector:
Placement
Insert-style actions accept aplacement:
Tracked changes: changeMode
Most mutating actions accept changeMode: "tracked". In tracked mode the edit is recorded as a redline suggestion — a tracked insert/delete/format change the user (or the model) can accept or reject later — instead of being applied directly. This is the backbone of review workflows:
- Suggest (tracked)
- Apply directly
changeMode on every mutating call. Review then happens with the same action surface:
accept_tracked_changes/reject_tracked_changes— optionally filtered byauthororchangeType(insert|delete|replacement|format)undo_changes/redo_changes— deterministic history recovery (untilMarkerrestores until a rendered clause marker like"2.1."reappears)
move_range, split_list, set_paragraph_spacing, insert_page_break, add_hyperlink, style_table. Requesting changeMode:"tracked" on move_range fails with nothing changed — use move_text for tracked text-span moves.
Receipts
Every action returns a receipt — not just “ok”, but evidence:status—partialmeans some of the requested work landed (the receipt says which part);failedmeans nothing changed unless the receipt explicitly says otherwise.verification— post-edit checks the action ran against a fresh snapshot (counts deltas, placement adjacency, text presence).verificationPassedis the roll-up.errors[]— failures carry acode, a human-readablemessagewritten for the model to act on, and often a structuredrecovery({kind: "reinspect" | "retry" | "revert", call?}) plus a paste-readyrevertHint.formattingMatched— insert actions that blend new content into its surroundings (e.g.add_list_items) report the font/size/style they copied from neighbors, so the model knows not to re-format.- List caps — long per-item lists (
executedOperations,selectedTargets) are capped at 8 entries with a*Countfield preserving the true total, to keep receipts from bloating your conversation history.
Action reference
Forty actions, grouped. Arguments marked? are optional; most mutating actions also accept changeMode.
Text & structure
Lists & numbering
History
Moving text
Comments
Tracked-change review
Formatting
Layout, links, media
Tables
Narrowing the surface: excludeActions
Hide actions you don’t want the model to see. The exclusion narrows everything coherently: the action enum, the argument schema, the per-action documentation lines in the system prompt, and the dispatch guard (an excluded action is refused even if the model guesses its name).
The safest way to use it is createAgentToolkit — one options object, all three surfaces guaranteed to agree:
- Node.js
- Python
- CLI
The system prompt
getSystemPrompt('core') returns the prompt the action surface was evaluated with: document-model vocabulary (visual sections, rendered markers, effective formatting), the full per-action argument documentation, targeting conventions, tracked-changes rules, and receipt-reading discipline (trust the receipt, re-inspect on partial, use revertHint on failures).
- Use it as-is for the best out-of-the-box behavior — the eval suite scores this exact prompt.
- Extend it by appending your domain instructions (tone, house style, what to never touch) at the end.
- Replacing it entirely is not recommended: the per-action lines teach argument shapes the schema alone can’t convey. If you do, keep the action documentation block.
Creating custom actions
UsedefineAction to add a named action with built-in steps or a native run function. createAgentToolkit keeps the resulting tool schema, system prompt, and dispatcher aligned. See Custom actions for the SDK workflow and the optional coding-agent skill.
Over MCP
The core preset is also available through the SuperDoc MCP server: start it withMCP_PRESET=core and clients get the session lifecycle tools (superdoc_open / superdoc_save / superdoc_close) plus superdoc_inspect and superdoc_perform_action, registered from the same catalog chooseTools() serves — the MCP surface cannot drift from the SDK surface. Server instructions use the core MCP prompt automatically.
Experimental: superdoc_execute_code
The SDK can dispatch a third tool, superdoc_execute_code (model-authored JavaScript against a synchronous in-process Document API). It is work-in-progress and deliberately not advertised: it is absent from chooseTools() results and from the served system prompt, and its behavior may change. It will ship behind an explicit safety flag in a future release. Don’t build on it yet.
Related
- Overview & agent loops: providers, token budget, error codes, troubleshooting
- Best practices
- Document API: the operations the actions wrap

