SuperAPI AI Directory

wps-note

General & other

View repository

Updated 10-16 03:12

About this skill

WPS Note MCP Skill

Core operation pattern:locate first (outline / search) → then read (read) → finally edit (write). All content is exchanged in semantic XML format, and all locating is based on block_id(10-character alphanumeric).

When to use

  • The user mentions WPS Notes, WPS Note, cloud notes, or Kingsoft Notes
  • The user asks to read, edit, search, summarize, or translate note content
  • The user needs to create notes, manage tags, or organize the note library
  • Need to troubleshoot MCP tool call failures (BLOCK_NOT_FOUND、EDITOR_NOT_READY and other errors)

Not applicable to: local Markdown file operations, other products such as WPS Documents/Spreadsheets/Presentations, and purely conceptual discussions.

Core concepts

Block model

  • A note is composed of blocks, and each block has a unique block_id。
  • block types:paragraph、heading、blockquote、code_block、list、table、image(single image/image column),horizontal_rule、highlight_block、columns、embed、note_audio_card。
  • embed blocks (spreadsheets, videos, LaTeX, countdowns, etc.) areread-only placeholders, and cannot be edited.
  • note_audio_card blocks are voice recording cards (read-only), displayed in XML as <NoteAudioCard/>, use the get_audio_transcript tool to obtain the transcript content.
  • Tables must bereplaced as a whole table, and individual cells cannot be edited. Table cells only support simple blocks (paragraphs, headings, quotes, code blocks, dividers, images),container blocks such as highlight blocks, columns, and tables cannot be nested within cells.
  • Container nesting restrictions:<highlightBlock> only supports simple blocks (paragraphs, headings, quotes, code blocks, dividers, images) inside,cannot nest <highlightBlock>、<columns>、<table>。<columns> each <column> inside supports simple blocks and <highlightBlock>,cannot nest <table> or <columns>。

note_id

  • Most tools require note_id to specify the note to operate on.
  • Obtain list_notes or search_notes via note_id; if the user wants to operate on the currently open note, they can directly call get_current_note to obtain it.
  • get_note_info can obtain note metadata (including tags), supporting three modes: single note_id query, batch note_ids query (up to 100), and full paginated browsing (page/page_size/limit), without needing to read the full content.

XML input and output

  • All content is sent and received in semantic XML format, using tags such as <p>、<h1>-<h6>、<blockquote>、<codeblock>、<table>、<highlightBlock>、<columns> etc.
  • Each block-level tag is identified by the id attribute as block_id, such as <p id="aB3kLm9xZq">内容</p>。
  • Important: write operations (edit_block etc.)'s block_id / anchor_id only accept top-level block IDs (returned by get_note_outline ).read_note In XML, containers (<highlightBlock>、<columns>、<table>) internal paragraphs' id are for reading reference only and cannot be used for write operations.
  • Provide content in XML format when writing; the system automatically converts it to the internal block model.replace The target block of block_id is specified by the tool parametercontent , it is recommended not to write id; if the root block idis explicitly written, it must match the target block_id .insert When inserting, block-level tags in the new content should omit id; the system automatically assigns a new block_id。
  • Inline marks use semantic tags:<strong>粗体</strong>、<em>斜体</em>、<s>删除线</s>、<u>下划线</u>、<a href="url">链接</a>。
  • Tag management: use the manage_note_tags tool to manage note tags—directly add/remove file-level tags without editing document content. After creating a note, call manage_note_tags({ note_id, add: ["标签名"] }) to assign tags; use /for multi-level tags, and do not include the # prefix in the call parameters; after editing an existing note, if it has no tags, they should also be added.
  • Inline self-closing elements:<emoji value="😀"/>(emoji),<latex formula="E=mc^2"/>(inline formula),<br/>(hard line break).
  • Style attributes are passed via <span> :<span fontColor="#C21C13">红色文字</span>、<span fontHighlightColor="#FBF5B3">高亮文字</span>、<span fontSize="16">大号文字</span>。
  • Colors are constrained by the preset color palette; any hex color value will be silently discarded by the editor. Preset values for various colors:
    • fontColor(12 colors):#080F17 #C21C13 #DB7800 #078654 #0E52D4 #0080A0 #757575 #DA326B #D1A300 #58A401 #116AF0 #A639D7
    • fontHighlightColor(9 colors):#FBF5B3 #F8D7B7 #F7C7D3 #DFF0C4 #C6EADD #D9EEFB #D5DCF7 #E6D6F0 #E6E6E6
    • highlightBlock colors (6 pairs bg→border):#FAF1E6→#FEC794、#FAE6E6→#F2A7A7、#E6FAEB→#AFE3BB、#E6EEFA→#98C1FF、#F5EBFA→#E5B5FD、#EBEBEB→#C5C5C5
    • columnBackgroundColor(42 colors, including solid colors and gradients):
      • 6 basic colors:#FFF5EB #FFECEB #E8FCEF #EBF2FF #FAF0FF #F2F2F2
      • 18 extended solid colors:#FCFAE1 #FEF6E7 #FFF5ED #FFF2F0 #FFF2F4 #FFF0F7 #EEFFEB #EBFFF5 #E8FCFC #EBF8FF #EBF1FF #F0EDFF #F2E7E4 #F0E6DA #F5EEDA #EDF0EB #EDEEF0 #F0E4DD
      • 6 saturated colors:#FEF49C #BCFAAF #ADF4FF #C2D3FF #FFC7C7 #E0E0E0
      • 12 gradient colors: use CSS linear-gradient() syntax, e.g. linear-gradient(133deg,#FFFAF7 2.14%,#FFEDFE 96.88%)
  • The complete XML format reference has been integrated into the MCP Server Instructions and is automatically injected (depending on client support). If not injected, you can call get_xml_reference tool to get it on demand.

Read-only Token

  • Some note tokens are read-only; write tools will return DOCUMENT_READ_ONLY。
  • At this point retryable: false—do not retry, inform the user. Read operations are unaffected.

Response format

All tools return a unified standard envelope:

{ "ok": true, "code": "OK", "message": "...", "retryable": false, "data": { ... }, "hints": [] }
  • ok—whether the call succeeded.
  • code—machine-readable status code (see error recovery).
  • retryable—when true , you can retry directly.
  • hints—suggested follow-up tools or actions.

Workflow

1. Read and understand notes

get_current_note()                            → 获取 note_id + word_count + size_category(决定后续策略)
list_notes / search_notes                     → 按条件查找 note_id
get_note_outline(note_id)                     → 查看结构和 block ID(超大文档自动分页)
get_cursor_block()                           → 获取当前光标所在顶层 block_id
read_section(note_id, heading_id)             → 读取某个章节
read_blocks(note_id, block_ids)               → 批量读取指定 block
read_blocks(note_id, block_id, before, after) → 读取单个 block 及上下文
search_note_content(note_id, q)               → 在笔记内搜索文本
read_image(note_id, block_id)                 → 读取图片 block 的实际内容(base64)
get_audio_transcript(shorthand_id)            → 获取语音录音的转写内容
get_xml_reference()                           → 获取 XML 格式完整参考文档

For long notes, prefer using get_note_outline → read_section, rather than read_note, to reduce token overhead.

Read large documents in pages

When a note exceeds 200 blocks,read_note and get_note_outline returns are automatically paginated—use the offset and block_limit parameters to switch between pages to view different parts. The note itself has no block count limit; these parameters only control the amount returned in a single read.

read_note example:

read_note({ note_id })
→ pagination: { total_blocks: 350, has_more: true, next_offset: 100 }

read_note({ note_id, offset: 100 })
→ pagination: { has_more: true, next_offset: 200 }

read_note({ note_id, offset: 200 })
→ pagination: { has_more: false }  ← 读完

You can also manually control the page size:read_note({ note_id, offset: 0, block_limit: 50 })

get_note_outline similarly—has_more: true when using next_offset to continue reading:get_note_outline({ note_id, offset: next_offset })

read_section similarly—when truncated, returns next_block_offset, pass in block_offset to continue reading:

read_section({ note_id, heading_block_id, max_blocks: 50 })
→ truncated: true, next_block_offset: 50

read_section({ note_id, heading_block_id, block_offset: 50 })
→ truncated: false  ← 读完

Document size strategy

get_current_note and get_note_outline both return word_count、size_category and estimated_xml_chars, based on which you choose the reading strategy:

size_category Word count range Strategy
small <5K words read_note Read the full text directly
medium 5K-20K characters get_note_outline → read_section Read by chapter
large 20K-80K characters search_note_content Precise targeting → read_blocks Read target + context → edit
very_large >80K characters Same as large, precise targeting takes priority search_note_content;get_note_outline Supports paginated reading (offset/block_limit) to retrieve structure as needed

Principle: The larger the document, the more you should use search to locate rather than reading sequentially. For large/very_large documents, prioritize using search_note_content to find the target block, then use read_blocks to read its context.When operating on the current note, first call get_current_note to get size_category, then decide the path。

2. Edit note content

get_note_outline(note_id)                      → 获取最新 block ID
get_cursor_block()                            → 当前围绕光标位置编辑时,获取锚点 block
read_blocks(note_id, [target_id])              → 确认当前内容
insert_image(note_id, anchor_id, pos, src)     → 插入图片(独立工具,不走 XML,当前需联网)
generate_image(prompt, width?, height?)        → AI 文生图,返回图片 URL(配合 insert_image 插入笔记)
edit_block(note_id, op, ...)                   → 单个编辑操作(替换、插入、删除、更新属性、移动)
batch_edit(note_id, operations)                → 多个操作合并为一次原子事务

Key: After editing, block IDs may change. For consecutive inserts, you can directly use the returned last_block_id as an anchor; before operating on other blocks, refresh via get_note_outline .

Parameter constraints:edit_block / batch_edit Only pass the current op required fields.replace / insert 's content must directly contain the complete XML string; you cannot pass plain text, Markdown, or "把第二段改成……" such natural language editing instructions.

Correct approach for consecutive inserts(to avoid disorder):

  • Preferred: In a single insert , concatenate all content into complete XML (e.g., "<h2>A</h2><p>...</p><h2>B</h2><p>...</p>"), and insert them in XML order; no need to call multiple times.
  • Chained: If you must split into multiple insert, each time use the last_block_id returned from the previous call as the anchor_idfor the next call, or call get_note_outline after each write to refresh the ID.

3. Batch editing (atomic transaction)

Use edit_blockfor a single operation, and batch_edit for multiple operations merged into an atomic transaction:

# 单个操作
edit_block(note_id, op: "replace", block_id: "id1", content: "<p>...</p>")
edit_block(note_id, op: "insert", anchor_id: "id2", position: "after", content: "<h2>...</h2><p>...</p>")

# 多个操作(原子事务)
batch_edit(note_id, operations: [
  { op: "delete",       block_ids: ["id1"] },
  { op: "replace",      block_id: "id2", content: "<p>...</p>" },
  { op: "update_attrs", block_id: "id3", attrs: { level: 2 } },
  { op: "move",         block_id: "id5", anchor_id: "id2", position: "after" },
  { op: "insert",       anchor_id: "id4", position: "after", content: "<h2>...</h2><p>...</p>" }
])

Execution order is fixed(batch_edit): delete → replace → update_attrs → move → insert (independent of array order).

4. Manage notes and tags

get_note_info(note_id)                      → 获取单个笔记元数据(含标签)
get_note_info(note_ids: [...])              → 批量获取多个笔记元数据(最多 100 个)
get_note_info(page, page_size)              → 分页浏览所有笔记元数据
search_notes(keyword, tags, since, before)  → 搜索笔记(也可按标签筛选笔记)
create_note(title)                          → 创建空白笔记(需用 edit_block 添加内容)
import_web_page(url)                       → 从白名单域名导入网页为笔记(微信公众号、知乎、豆瓣等)
delete_note(note_id)                        → 不可恢复——必须与用户确认
sync_note(note_id)                          → 触发同步
find_tags()                                 → 列出所有标签
find_tags(keyword)                          → 搜索标签
manage_note_tags(note_id, add, remove)      → 添加/移除笔记的文件级标签
get_note_stats(detailed)                    → 使用统计

Tool quick reference

Read/locate tools

Tool Purpose Key parameters
get_note_outline Get the structural outline (including title, word_count, block_count, size_category, estimated_xml_chars, blocks list, pagination)—the main way to get block_id and document scale; very large documents are automatically paginated note_id、max_depth?、include_preview?、offset?、block_limit?
get_cursor_block Get the block_id、block_type and note_idof the top-level block where the current cursor is located; not supported when the cursor is inside a highlight block or column (no parameters)
read_blocks Batch read the XML content and attributes of blocks by ID, or read a single block and its surrounding context note_id、block_ids(batch) or block_id+before?+after?(context)
read_note Read the full text or read in pages (XML); very large documents are automatically paginated and return pagination (including has_more + next_offset) note_id、max_length?、offset?、block_limit?
search_note_content Search for text within the note, returning the block_id/type/preview of matching blocks, used for locating before editing note_id、query、max_results?
read_section Read the complete chapter by heading (until the next heading of the same level); when truncated, returns next_block_offset for continued reading note_id、heading_block_id、max_blocks?、block_offset?
read_image Read the actual content of an image block (base64), available for visual understanding note_id、block_id
get_audio_transcript Get the transcription text of a voice recording (NoteAudioCard), returning a list of sentences (including speaker and timestamps) shorthand_id(from outline's note_audio_card block attrs)
get_xml_reference Get the complete reference documentation in XML format (all tags, attributes, and write examples) (no parameters)

Example:

get_note_outline({ note_id: "abc123" })
get_note_outline({ note_id: "abc123", offset: 100 })  // 分页续读
get_cursor_block()
read_blocks({ note_id: "abc123", block_ids: ["aB3kLm9xZq", "xY7nPq2wRt"] })
read_blocks({ note_id: "abc123", block_id: "xY7nPq2wRt", before: 2, after: 3 })
read_note({ note_id: "abc123" })
read_note({ note_id: "abc123", offset: 100 })  // 分页续读
read_note({ note_id: "abc123", offset: 0, block_limit: 50 })  // 手动控制每页大小
search_note_content({ note_id: "abc123", query: "季度总结" })
read_section({ note_id: "abc123", heading_block_id: "aB3kLm9xZq" })
read_section({ note_id: "abc123", heading_block_id: "aB3kLm9xZq", block_offset: 50 })  // 续读截断章节
read_image({ note_id: "abc123", block_id: "imgBlock01" })
get_audio_transcript({ shorthand_id: "sh_abc123" })
get_xml_reference()

Write tools

Tool Purpose Key parameters
edit_block A single edit operation (recommended entry point); after editing, block_id may change and needs to be re-fetched. The insert operation returns new_block_ids and last_block_id. After a move operation, block_id does not change note_id、op(replace/insert/delete/update_attrs/move)、block_id/anchor_id/block_ids、content/attrs
batch_edit An atomic transaction of multiple operations (all succeed or all roll back), with a fixed execution order. Returns new_block_ids and last_block_id note_id、operations[]
insert_image Insert an image (images cannot be created via XML and must use this tool); currently uses online upload, returns block_id and dimensions note_id、anchor_id、position、src、alt?
generate_image AI text-to-image, returns the image URL (use with insert_image to insert into a note). Limited to once per minute per user, takes 30-120 seconds prompt、width?(default 2688),height?(default 1536)
import_web_page Import web content as a note from whitelisted domains (WeChat Official Accounts, Zhihu, Douban, etc.), returning the note ID, title, and summary. Takes 5-30 seconds url

edit_block / batch_edit operation type:

op Required fields
"replace" block_id、content
"insert" anchor_id、position("before"/"after")、content
"delete" block_ids
"update_attrs" block_id、attrs
"move" block_id、anchor_id、position("before"/"after")

content appears only in replace / insert and must be a complete XML string, not natural language, plain text, or Markdown.

File reference parameters(CLI and script scenarios): when content or operations content is too large and causes command-line truncation, file references can be used instead—content_file(pass in a file path; Electron reads it and fills in content)、operations_file(similarly fills in operations)、__args_file(read all parameters from a JSON file). File references are ignored when an explicit value already exists. See references/CLI_REFERENCE.md。

Example:

// 单个操作 — edit_block
edit_block({ note_id: "abc123", op: "replace", block_id: "xY7nPq2wRt", content: "<p>更新后的段落文本</p>" })
edit_block({ note_id: "abc123", op: "insert", anchor_id: "aB3kLm9xZq", position: "after", content: "<h2>新章节</h2><p>这里是新内容。</p>" })
edit_block({ note_id: "abc123", op: "delete", block_ids: ["xY7nPq2wRt", "kL5mNp8vBc"] })
edit_block({ note_id: "abc123", op: "update_attrs", block_id: "aB3kLm9xZq", attrs: { level: 2 } })
edit_block({ note_id: "abc123", op: "move", block_id: "imgBlock01", anchor_id: "aB3kLm9xZq", position: "after" })

// 多个操作(原子事务) — batch_edit
batch_edit({ note_id: "abc123", operations: [
  { op: "replace", block_id: "xY7nPq2wRt", content: "<p>更新后的段落文本</p>" },
  { op: "insert", anchor_id: "aB3kLm9xZq", position: "after", content: "<h2>新章节</h2>" }
]})

// 图片
insert_image({ note_id: "abc123", anchor_id: "aB3kLm9xZq", position: "after", src: "https://example.com/photo.png", alt: "示意图" })

// AI 文生图 → 插入笔记
generate_image({ prompt: "一只橘猫坐在窗台上,水彩画风格,暖色调" })
→ { image_url: "https://...", task_id: "...", width: 2688, height: 1536 }
// 然后用 insert_image 将返回的 image_url 插入笔记

// 导入网页为笔记
import_web_page({ url: "https://mp.weixin.qq.com/s/xxx" })
→ { fileId: "123456", title: "文章标题", intro: "摘要...", linkUrl: "https://xxx/note/123456" }

Hidden write tools

The following tools are still available but not shown by default, suitable for scenarios that require calling them individually:

Tool Purpose Key parameters
replace_block Replace the content of a single block note_id、block_id、content
insert_block Insert before or after a specified position note_id、anchor_id、position、content
delete_blocks Delete a block note_id、block_ids
update_block_attrs Modify block attributes note_id、block_id、attrs

Management tools

Tool Purpose Key parameters
list_notes List notes, supports sorting and pagination, returns { notes, meta } limit?、sort?、direction?、since?、before?、page?、page_size?、starred?
create_note Create a blank note (containing only an empty paragraph), returns { fileId, title } title?
get_note_info Get note metadata (without reading the full text), returns title, time, intro, tags, starred note_id(single),note_ids(batch),limit?、page+page_size(pagination)
get_current_note Get the current note ID, metadata, and document statistics (including word_count, size_category) (no parameters)
get_cursor_block Get the current cursor's block's block_id、block_type and note_id; not supported when inside a highlight block/column layout (no parameters)
search_notes Search notes (keyword + tag intersection + time range); you can also pass only tags to browse by tag keyword?、tags?、since?、before?、sort?、direction?、limit?、starred?
find_tags List or search tags, returning an array of { id, name } keyword?(if not provided, list all; if provided, search)
manage_note_tags Manage file-level tags of a note (add/remove) note_id、add?(array of tag names),remove?(array of tag names or IDs)
sync_note Trigger sync between note and cloud note_id
delete_note Permanently delete note (unrecoverable), must first confirm with user note_id or note_ids(batch, up to 100)
get_note_stats Usage statistics (total notes, tag count, distribution, etc.) detailed?
get_mcp_logs MCP call logs, used for diagnosing INTERNAL_ERROR limit?

Example:

list_notes({ sort: "update_time", direction: "desc", limit: 10 })
list_notes({ starred: true })                  // 仅列出已收藏笔记
search_notes({ keyword: "项目方案", tags: ["工作"], since: "2025-01-01T00:00:00Z" })
search_notes({ tags: ["工作"] })  // 按标签筛选笔记(替代原 list_tag_notes)
search_notes({ starred: true })  // 仅在已收藏笔记中搜索
create_note({ title: "会议记录 2025-03-03" })
get_current_note()
get_cursor_block()
get_note_info({ note_id: "abc123" })              // 单个笔记元数据(含标签)
get_note_info({ note_ids: ["abc123", "def456"] }) // 批量查询
get_note_info({ page: 1, page_size: 20 })         // 分页浏览所有笔记
get_note_info({ limit: 5 })                       // 仅获取前 5 条
find_tags()                       // 列出所有标签
find_tags({ keyword: "工作" })    // 搜索标签
manage_note_tags({ note_id: "abc123", add: ["工作", "项目"] })   // 为笔记添加标签
manage_note_tags({ note_id: "abc123", remove: ["草稿"] })        // 移除笔记标签
manage_note_tags({ note_id: "abc123" })                          // 查看当前标签
delete_note({ note_id: "abc123" })  // 不可恢复——必须先与用户确认!
get_mcp_logs({ limit: 20 })       // 查看最近的工具调用日志

Block types and XML tags

Block type XML tag Description
paragraph <p> Supports inline mark (<strong>、<em>、<s>、<u>、<a>) and inline nodes (<emoji/>、<latex/>、<br/>)
heading <h1>-<h6> level is controlled by tag name or attrs.level Control
blockquote <blockquote> Supports inline mark and <br/> line break
code_block <codeblock lang="..."> Pure text content; language is specified via the lang attribute
list <p listType="bullet|ordered|todo"> Controlled via the listType、listLevel、checked attribute; ordered lists additionally support listId and listValue
table <table> <tr> → <td> structure; must replace the whole table. Cells only support simple blocks (<p>、<h1>-<h6>、<blockquote>、<codeblock>、<hr/>、<img/>), cannot nest <highlightBlock>、<columns>、<table> and other containers
highlight_block <highlightBlock> Highlight block, only supports simple blocks (<p>、<h1>-<h6>、<blockquote>、<codeblock>、<hr/>、<img/>), cannot nest <highlightBlock>、<columns>、<table> and other containers
columns <columns> → <column> Column layout, each column supports simple blocks and <highlightBlock>, cannot nest <table> or <columns>
image <img/> Read-only——cannot be created or modified via XML, use the insert_image tool to insert a single image
image_column <imageColumn> Read-only——images displayed in columns, cannot be created via XML
horizontal_rule <hr/> Divider
embed <embed type="..."/> Read-only——cannot be edited or replaced
note_audio_card <NoteAudioCard/> Read-only——audio recording card, use get_audio_transcript to get the transcript

update_block_attrs supported attributes

Block type Attribute Optional values
heading level 1–6
heading textAlign "left"、"center"、"right"
paragraph textAlign "left"、"center"、"right"
code_block language Language identifier string
todo_list sub-items checked true / false

Troubleshooting

block ID invalid (BLOCK_NOT_FOUND)

Symptom: write operation reports BLOCK_NOT_FOUND, even if the block was just read previously. Cause: editing operations cause block IDs to change, and the cached ID has expired. Solution: always first get_note_outline or search_note_content to refresh the ID before writing; or use the last_block_id returned by the last insert as the next anchor_id。

Table editing fails

Symptom: an error or content loss occurs when trying to edit a table cell. Cause: tables only support whole-table replacement and cannot edit individual cells. Solution: use edit_block 's replace operation to pass in the complete XML table (including the header separator row).

embed block is not writable

Symptom: calling edit_block of the replace operation returns an error. Cause: embedded content such as spreadsheets, videos, audio, and LaTeX are read-only placeholders. Solution: skip embed blocks and only operate on other editable block types.

Note is read-only (DOCUMENT_READ_ONLY)

Symptom: all write operations return DOCUMENT_READ_ONLY。 Cause: the current note token has read-only permission and cannot be retried. Solution: inform the user that this note is read-only. Read operations still work normally.

Editor not ready (EDITOR_NOT_READY)

Symptom: the operation returns EDITOR_NOT_READY。 Cause: the note editor is still initializing, usually recovering in 1-2 seconds. Solution: wait a moment and retry. If it still fails after 3 attempts, ask the user to check the notes app.

WebSocket not connected (WEBSOCKET_NOT_CONNECTED)

Symptom:get_audio_transcript returns WEBSOCKET_NOT_CONNECTED。 Cause: the network is disconnected or the WebSocket connection is interrupted. Solution: check the network connection, wait for the WebSocket to reconnect automatically, then retry.

Other notes

  • Images must use the insert_image tool: images cannot be created via XML (the<img/> tag is read-only).insert_image currently uploads online, requiring internet access when called. Supports HTTP/HTTPS URLs and base64 data URIs.Local file paths are not supported for direct input; you must first read them and convert them to base64 data URIs。The URL must point directly to an image resource (returning image/ content type), and cannot be an HTML page link*. If the URL returns 404, is offline, or contains non-image content, it will report the IMAGE_FETCH_FAILED error.edit_block 's replace/insert/update_attrs do not support images (but move can move image blocks)。
  • generate_image is AI text-to-image: returns an image URL rather than inserting it directly into the note. Must be used with insert_image . Limited to 1 time per user per minute; generation takes about 30-120 seconds.
  • import_web_page only supports whitelisted domains: whitelisted domains such as WeChat Official Accounts, Zhihu, and Douban can be imported; non-whitelisted domains will return INVALID_PARAMS. Conversion takes about 5-30 seconds. After import completes, a new note is automatically created and opened.
  • batch_edit has a fixed execution order: delete → replace → update_attrs → move → insert, regardless of array order.
  • move operations support all block types: including images (<img/>), embedded content (<embed/>), and other read-only tags that cannot be created via XML. After moving, block_id remains unchanged, so there is no need to refresh the outline. Suitable for adjusting content order and reorganizing document structure.
  • create_note creates a blank note: initial content is not supported; use edit_block to fill it.
  • read_section is limited to headings:heading_block_id must point to a heading block, otherwise it reports INVALID_BLOCK_TYPE。
  • get_cursor_block only supports top-level blocks: when the cursor is inside a highlight block (subdoc) or columns, it returns UNSUPPORTED_POSITION。
  • delete_note is unrecoverable: you must first confirm with the user.
  • When the response contains hints ,follow its suggestions—they indicate the fastest recovery path.

Error Code Quick Reference

Error Code Retryable Recovery Method
INVALID_PARAMS No Fix the parameters according to inputSchema
EDITOR_NOT_READY Yes Wait and retry
NO_ACTIVE_EDITOR_WINDOW Yes Ask the user to open the note window
BLOCK_NOT_FOUND No Refresh the outline to get a valid ID
INVALID_BLOCK_TYPE No Check the block type
INVALID_CONTENT No Fix the content format
DOCUMENT_READ_ONLY No Inform the user
FRONTEND_TIMEOUT Yes Narrow the scope or retry
IMAGE_FETCH_FAILED Yes Check whether the image URL points directly to an image resource, fix it, and retry
GENERATE_IMAGE_FAILED No Fix the prompt or check the whitelist/login status
RATE_LIMITED Yes Wait 60 seconds and retry
WEBSOCKET_NOT_CONNECTED Yes Check the network, wait for the WebSocket to reconnect, and retry
INTERNAL_ERROR Yes Retry; check get_mcp_logs(hidden tool)

For full error details, see references/ERROR_CODES.md。

Common Orchestration Patterns

The most frequent multi-tool combinations, usable without consulting the full use case manual.

Pattern 1: Search and locate → Read in sections(preferred for long documents)

search_notes({ keyword }) → note_id
get_note_outline({ note_id }) → heading block ID
read_section({ note_id, heading_block_id }) → 按需读取章节

Pattern 2: Batch search and replace within a note

search_note_content({ note_id, query }) → 匹配的 block_id 列表
read_blocks({ note_id, block_ids }) → 读取完整内容
batch_edit({ note_id, operations: [{ op: "replace", ... }, ...] }) → 原子替换

Pattern 3: Create → Fill template

create_note({ title }) → note_id(空白笔记)
manage_note_tags({ note_id, add: ["标签名"] }) → 分配标签
get_note_outline({ note_id }) → 获取空 block ID
batch_edit({ note_id, operations: [
  { op: "replace", block_id, content: "<h1>标题</h1>" },
  { op: "insert", anchor_id, position: "after", content: "<p>模板内容...</p>" }
]})

Pattern 4: Continuously append multiple sections(avoid out-of-order)

# 方式 A(推荐):单次 insert 拼接完整 XML
edit_block({ note_id, op: "insert", anchor_id: "last_id", position: "after",
  content: "<h2>第一部分</h2><p>内容 A</p><h2>第二部分</h2><p>内容 B</p>" })

# 方式 B:链式 insert,用上次返回的 last_block_id 做锚点
edit_block({ ..., anchor_id: "id1", position: "after", content: "<h2>第一部分</h2><p>内容 A</p>" })
→ { last_block_id: "new_id_1" }
edit_block({ ..., anchor_id: "new_id_1", position: "after", content: "<h2>第二部分</h2><p>内容 B</p>" })
→ { last_block_id: "new_id_2" }

Pattern 5: Move blocks (images, embedded content, etc.)

get_note_outline({ note_id }) → 找到源 block 和目标位置
edit_block({ note_id, op: "move", block_id: "img_id", anchor_id: "target_heading", position: "after" })
→ block_id 不变,无需刷新 outline

Pattern 6: Manage note tags

find_tags() → 查看已有标签名
manage_note_tags({ note_id, add: ["工作", "项目"] }) → 添加标签
manage_note_tags({ note_id, remove: ["草稿"] }) → 移除标签
manage_note_tags({ note_id }) → 查看当前标签

Pattern 7: Read oversized documents in pages(preferred when there is no heading structure; paging only controls the read amount, and notes have no block limit)

read_note({ note_id })
→ pagination: { total_blocks: 350, has_more: true, next_offset: 100 }

read_note({ note_id, offset: 100 })
→ pagination: { has_more: true, next_offset: 200 }

read_note({ note_id, offset: 200 })
→ pagination: { has_more: false }  ← 读完

For more combination patterns and end-to-end scenarios, see references/USE_CASES.md。

Full Examples

User says: "Help me find the Q1 report, update the summary section, and add a conclusion"

Step 1: Locate the note

search_notes({ keyword: "Q1 报告" })
→ data.notes[0].note_id = "note_xyz"

Step 2: Read the structure

get_note_outline({ note_id: "note_xyz" })
→ blocks: [
    { id: "h1abc", type: "heading", preview: "Q1 报告" },
    { id: "p1def", type: "paragraph", preview: "执行摘要..." },
    { id: "h2ghi", type: "heading", preview: "营收" },
    { id: "h2jkl", type: "heading", preview: "下一步计划" },
    { id: "p3mno", type: "paragraph", preview: "继续监控..." }
  ]

Step 3: Confirm the current content

read_blocks({ note_id: "note_xyz", block_ids: ["p1def"] })
→ "本季度各部门..."

Step 4: Atomic edit (replace the summary + insert the conclusion)

batch_edit({ note_id: "note_xyz", operations: [
  { op: "replace", block_id: "p1def",
    content: "<p>本报告涵盖 2025 年 Q1 各部门业绩表现。营收超出目标 15%。</p>" },
  { op: "insert", anchor_id: "p3mno", position: "after",
    content: "<h2>总结</h2><p>2025 年 Q1 是强劲的一个季度,所有关键指标均实现显著增长。</p>" }
]})
→ ok: true, last_block_id: "new_conclusion_id"

Tip:batch_edit / edit_block In the insert operation of , content can contain multiple block-level XML elements (such as <h2> + <p>in the example above), which are inserted in XML order without needing multiple calls. The returned last_block_id can be used directly for subsequent operations.

Step 5: Verify the result

read_section({ note_id: "note_xyz", heading_block_id: "h1abc", max_blocks: 5 })
→ 确认摘要已更新、结论已添加

Result: The note summary has been replaced with the new content, and a "Conclusion" section has been added at the end.

Reference Documentation

  • API Reference—Complete inputSchema for all tools
  • CLI Reference——wpsnote-cli canonical command surface, CLI-specific behavior, and JSON output format
  • Error Codes—Detailed error codes, the hints system, and recovery patterns
  • Use Case Manual—A complete set of use cases progressing by complexity (including end-to-end workflow examples), Prompt templates, and a quick reference for exception handling