wps-note

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

WPS Note MCP Skill

WPS Note MCP Skill

核心操作模式:先定位(outline / search)→ 再读取(read)→ 最后编辑(write)。所有内容以语义 XML 格式交换,所有定位基于
block_id
(10 位字母数字)。
Core Operation Mode: Locate first (outline / search) → Read next → Edit last. All content is exchanged in semantic XML format, and all positioning is based on
block_id
(10 alphanumeric characters).

何时使用

When to Use

  • 用户提到 WPS 笔记、WPS Note、云笔记、金山笔记
  • 用户要求读取、编辑、搜索、总结、翻译笔记内容
  • 用户需要创建笔记、管理标签、整理笔记库
  • 需要排查 MCP 工具调用失败(
    BLOCK_NOT_FOUND
    EDITOR_NOT_READY
    等错误)
不适用于:本地 Markdown 文件操作、WPS 文档/表格/演示等其他产品、纯概念讨论。
  • Users mention WPS Notes, WPS Note, cloud notes, or Kingsoft Notes
  • Users request to read, edit, search, summarize, or translate note content
  • Users need to create notes, manage tags, or organize note libraries
  • Need to troubleshoot MCP tool call failures (errors like
    BLOCK_NOT_FOUND
    ,
    EDITOR_NOT_READY
    )
Not applicable to: Local Markdown file operations, other WPS products like documents/spreadsheets/presentations, or pure conceptual discussions.

核心概念

Core Concepts

Block 模型

Block Model

  • 笔记由 block 组成,每个 block 有唯一的
    block_id
  • block 类型:
    paragraph
    heading
    blockquote
    code_block
    list
    table
    image
    (单图/图片分栏)、
    horizontal_rule
    highlight_block
    columns
    embed
    note_audio_card
  • embed
    block(电子表格、视频、LaTeX、倒计时等)为只读占位符,不可编辑。
  • note_audio_card
    block 为语音录音卡片(只读),在 XML 中显示为
    <NoteAudioCard/>
    ,使用
    get_audio_transcript
    工具获取转写内容。
  • 表格必须整表替换,无法编辑单个单元格。表格单元格仅支持简单块(段落、标题、引用、代码块、分隔线、图片),不可在单元格内嵌套高亮块、分栏、表格等容器类块。
  • 容器嵌套限制
    <highlightBlock>
    内仅支持简单块(段落、标题、引用、代码块、分隔线、图片),不可嵌套
    <highlightBlock>
    <columns>
    <table>
    <columns>
    的每个
    <column>
    内支持简单块和
    <highlightBlock>
    不可嵌套
    <table>
    <columns>
  • Notes are composed of blocks, each with a unique
    block_id
    .
  • Block types:
    paragraph
    ,
    heading
    ,
    blockquote
    ,
    code_block
    ,
    list
    ,
    table
    ,
    image
    (single image/image columns),
    horizontal_rule
    ,
    highlight_block
    ,
    columns
    ,
    embed
    ,
    note_audio_card
    .
  • embed
    blocks (spreadsheets, videos, LaTeX, countdowns, etc.) are read-only placeholders and cannot be edited.
  • note_audio_card
    blocks are voice recording cards (read-only), displayed as
    <NoteAudioCard/>
    in XML. Use the
    get_audio_transcript
    tool to obtain transcribed content.
  • Tables must be replaced in full; individual cells cannot be edited. Table cells only support simple blocks (paragraphs, headings, blockquotes, code blocks, horizontal rules, images), and cannot contain nested container blocks like highlight blocks, columns, or tables.
  • Container Nesting Restrictions:
    <highlightBlock>
    only supports simple blocks (paragraphs, headings, blockquotes, code blocks, horizontal rules, images), and cannot nest
    <highlightBlock>
    ,
    <columns>
    , or
    <table>
    . Each
    <column>
    within
    <columns>
    supports simple blocks and
    <highlightBlock>
    , but cannot nest
    <table>
    or
    <columns>
    .

note_id

note_id

  • 大部分工具需要
    note_id
    来指定操作的笔记。
  • 通过
    list_notes
    search_notes
    获取
    note_id
    ;若用户要操作当前打开的笔记,可直接调用
    get_current_note
    获取。
  • get_note_info
    可获取笔记元数据(含标签),支持三种模式:单个
    note_id
    查询、批量
    note_ids
    查询(最多 100 个)、全量分页浏览(
    page
    /
    page_size
    /
    limit
    ),无需读取全文内容。
  • Most tools require
    note_id
    to specify the note to operate on.
  • Obtain
    note_id
    via
    list_notes
    or
    search_notes
    ; if users want to operate on the currently open note, directly call
    get_current_note
    to retrieve it.
  • get_note_info
    can retrieve note metadata (including tags), supporting three modes: single
    note_id
    query, batch
    note_ids
    query (up to 100 notes), and full pagination browsing (
    page
    /
    page_size
    /
    limit
    ), without needing to read the full content.

XML 输入输出

XML Input/Output

  • 所有内容以语义 XML 格式收发,使用标签如
    <p>
    <h1>
    -
    <h6>
    <blockquote>
    <codeblock>
    <table>
    <highlightBlock>
    <columns>
    等。
  • 每个块级标签通过
    id
    属性标识 block_id,如
    <p id="aB3kLm9xZq">内容</p>
  • 重要:写入操作(
    edit_block
    等)的
    block_id
    /
    anchor_id
    只接受顶层 block ID(由
    get_note_outline
    返回)。
    read_note
    XML 中容器(
    <highlightBlock>
    <columns>
    <table>
    )内部段落的
    id
    仅供阅读参考,不可用于写入操作。
  • 写入时提供 XML 格式内容,系统自动转换为内部 block 模型。
    replace
    的目标 block 由工具参数
    block_id
    指定,
    content
    建议不写
    id
    ;若显式写了根块
    id
    ,必须与目标
    block_id
    一致。
    insert
    时新内容中的块级标签应省略
    id
    ,系统自动分配新的
    block_id
  • 行内 mark 使用语义标签:
    <strong>粗体</strong>
    <em>斜体</em>
    <s>删除线</s>
    <u>下划线</u>
    <a href="url">链接</a>
    <tag>#标签名</tag>
  • 标签写入
    <tag>#name</tag>
    可在段落等行内内容中使用。文本必须以
    #
    开头;多级标签用
    /
    分隔(如
    <tag>#工作/项目</tag>
    );id 属性可选,已有标签可通过
    find_tags
    获取 id 后传入,新标签可省略 id,系统自动创建。标签同步到左侧标签树自动完成。限制
    <tag>
    优先放在笔记第一个 block(首行)中;每级最多 20 字、最多 10 级;不支持 emoji、空格、方括号等字符;
    <tag>
    不可嵌套在
    <a>
    内(标签与链接互斥)。不合法内容会降级为纯文本并返回 warning。创建笔记后应在写入正文前先插入标签行;编辑已有笔记完成后若无标签也应补充。
  • 行内自闭合元素:
    <emoji value="😀"/>
    (表情)、
    <latex formula="E=mc^2"/>
    (行内公式)、
    <br/>
    (硬换行)。
  • 样式属性通过
    <span>
    传递:
    <span fontColor="#C21C13">红色文字</span>
    <span fontHighlightColor="#FBF5B3">高亮文字</span>
    <span fontSize="16">大号文字</span>
  • 颜色受预设色板约束,任意 hex 色值会被编辑器静默丢弃。各类颜色预设值:
    • fontColor
      (12 色):
      #080F17
      #C21C13
      #DB7800
      #078654
      #0E52D4
      #0080A0
      #757575
      #DA326B
      #D1A300
      #58A401
      #116AF0
      #A639D7
    • fontHighlightColor
      (9 色):
      #FBF5B3
      #F8D7B7
      #F7C7D3
      #DFF0C4
      #C6EADD
      #D9EEFB
      #D5DCF7
      #E6D6F0
      #E6E6E6
    • highlightBlock
      颜色(6 对 bg→border):
      #FAF1E6
      #FEC794
      #FAE6E6
      #F2A7A7
      #E6FAEB
      #AFE3BB
      #E6EEFA
      #98C1FF
      #F5EBFA
      #E5B5FD
      #EBEBEB
      #C5C5C5
    • columnBackgroundColor
      (42 色,含纯色和渐变):
      • 6 基础色:
        #FFF5EB
        #FFECEB
        #E8FCEF
        #EBF2FF
        #FAF0FF
        #F2F2F2
      • 18 扩展纯色:
        #FCFAE1
        #FEF6E7
        #FFF5ED
        #FFF2F0
        #FFF2F4
        #FFF0F7
        #EEFFEB
        #EBFFF5
        #E8FCFC
        #EBF8FF
        #EBF1FF
        #F0EDFF
        #F2E7E4
        #F0E6DA
        #F5EEDA
        #EDF0EB
        #EDEEF0
        #F0E4DD
      • 6 饱和色:
        #FEF49C
        #BCFAAF
        #ADF4FF
        #C2D3FF
        #FFC7C7
        #E0E0E0
      • 12 渐变色:使用 CSS
        linear-gradient()
        语法,如
        linear-gradient(133deg,#FFFAF7 2.14%,#FFEDFE 96.88%)
  • 完整 XML 格式参考已集成到 MCP Server Instructions 中自动注入(视客户端支持情况)。未注入时可调用
    get_xml_reference
    工具按需获取。
  • 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 identifies the block_id via the
    id
    attribute, e.g.,
    <p id="aB3kLm9xZq">Content</p>
    .
  • Important: The
    block_id
    /
    anchor_id
    for write operations (such as
    edit_block
    ) only accepts top-level block IDs (returned by
    get_note_outline
    ). The
    id
    of paragraphs inside containers (
    <highlightBlock>
    ,
    <columns>
    ,
    <table>
    ) in the
    read_note
    XML is 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. For
    replace
    , the target block is specified by the tool parameter
    block_id
    , and it is recommended not to write the
    id
    in
    content
    ; if the root block
    id
    is explicitly written, it must match the target
    block_id
    . When using
    insert
    , omit the
    id
    from block-level tags in the new content, and the system will automatically assign a new
    block_id
    .
  • Inline marks use semantic tags:
    <strong>bold</strong>
    ,
    <em>italic</em>
    ,
    <s>strikethrough</s>
    ,
    <u>underline</u>
    ,
    <a href="url">link</a>
    ,
    <tag>#tagname</tag>
    .
  • Tag Writing:
    <tag>#name</tag>
    can be used in inline content like paragraphs. The text must start with
    #
    ; multi-level tags are separated by
    /
    (e.g.,
    <tag>#work/project</tag>
    ); the id attribute is optional—for existing tags, you can pass the id obtained via
    find_tags
    , while for new tags, omit the id and the system will automatically create it. Tags are automatically synchronized to the left tag tree. Restrictions:
    <tag>
    should be placed in the first block (first line) of the note; each level can have a maximum of 20 characters, with up to 10 levels; emojis, spaces, square brackets, and other characters are not supported;
    <tag>
    cannot be nested inside
    <a>
    (tags and links are mutually exclusive). Invalid content will be degraded to plain text and return a warning. After creating a note, insert the tag line before writing the body; if there are no tags after editing an existing note, add them.
  • 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">red text</span>
    ,
    <span fontHighlightColor="#FBF5B3">highlighted text</span>
    ,
    <span fontSize="16">large text</span>
    .
  • Colors are constrained by preset palettes; arbitrary hex color values 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 bg→border pairs):
      #FAF1E6
      #FEC794
      #FAE6E6
      #F2A7A7
      #E6FAEB
      #AFE3BB
      #E6EEFA
      #98C1FF
      #F5EBFA
      #E5B5FD
      #EBEBEB
      #C5C5C5
    • columnBackgroundColor
      (42 colors, including solid and gradient):
      • 6 base 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%)
  • Complete XML format references are automatically integrated into MCP Server Instructions (depending on client support). If not injected, call the
    get_xml_reference
    tool to obtain it on demand.

只读 Token

Read-Only Token

  • 部分笔记 token 为只读,写入工具会返回
    DOCUMENT_READ_ONLY
  • 此时
    retryable: false
    ——不要重试,应告知用户。读取操作不受影响。
  • Some note tokens are read-only, and write tools will return
    DOCUMENT_READ_ONLY
    .
  • In this case,
    retryable: false
    —do not retry, inform the user instead. Read operations are not affected.

响应格式

Response Format

所有工具返回统一的标准信封:
json
{ "ok": true, "code": "OK", "message": "...", "retryable": false, "data": { ... }, "hints": [] }
  • ok
    ——调用是否成功。
  • code
    ——机器可读状态码(参见错误恢复)。
  • retryable
    ——为
    true
    时可直接重试。
  • hints
    ——建议的后续工具或操作。
All tools return a unified standard envelope:
json
{ "ok": true, "code": "OK", "message": "...", "retryable": false, "data": { ... }, "hints": [] }
  • ok
    —whether the call was successful.
  • code
    —machine-readable status code (see Error Recovery).
  • retryable
    —if
    true
    , you can retry directly.
  • hints
    —suggested subsequent tools or operations.

工作流

Workflow

1. 读取与理解笔记

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 格式完整参考文档
对于长笔记,优先使用
get_note_outline
read_section
,而非
read_note
,以减少 token 开销。
get_current_note()                            → Get note_id + word_count + size_category (determines subsequent strategy)
list_notes / search_notes                     → Find note_id by conditions
get_note_outline(note_id)                     → View structure and block IDs (automatically paginated for extra-large documents)
get_cursor_block()                           → Get the top-level block_id where the current cursor is located
read_section(note_id, heading_id)             → Read a specific section
read_blocks(note_id, block_ids)               → Batch read specified blocks
read_blocks(note_id, block_id, before, after) → Read a single block and its context
search_note_content(note_id, q)               → Search text within the note
read_image(note_id, block_id)                 → Read the actual content of an image block (base64)
get_audio_transcript(shorthand_id)            → Get transcribed content of voice recordings
get_xml_reference()                           → Get complete XML format reference document
For long notes, prioritize using
get_note_outline
read_section
instead of
read_note
to reduce token overhead.

分页读取大文档

Pagination for Reading Large Documents

当笔记超过 200 blocks 时,read_noteget_note_outline 的返回会自动分页——需通过
offset
block_limit
参数切换分页查看不同部分。笔记本身无 block 数量上限,这些参数仅控制单次读取返回量。
read_note
示例:
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 }  ← 读完
也可手动控制每页大小:
read_note({ note_id, offset: 0, block_limit: 50 })
get_note_outline
同理——
has_more: true
时用
next_offset
续读:
get_note_outline({ note_id, offset: next_offset })
read_section
同理——截断时返回
next_block_offset
,传入
block_offset
续读:
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  ← 读完
When a note has more than 200 blocks, the returns of read_note and get_note_outline will be automatically paginated—use the
offset
and
block_limit
parameters to switch pages and view different parts. There is no upper limit on the number of blocks in a note; these parameters only control the amount returned per read.
Example of
read_note
:
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 }  ← Finished reading
You can also manually control the page size:
read_note({ note_id, offset: 0, block_limit: 50 })
get_note_outline
works similarly—when
has_more: true
, use
next_offset
to continue reading:
get_note_outline({ note_id, offset: next_offset })
read_section
works similarly—when truncated, it returns
next_block_offset
, which can be passed as
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  ← Finished reading

文档大小策略

Document Size Strategy

get_current_note
get_note_outline
都返回
word_count
size_category
estimated_xml_chars
,据此选择读取策略:
size_category字数范围策略
small
<5K 字
read_note
直接读取全文
medium
5K-20K 字
get_note_outline
read_section
按章节读取
large
20K-80K 字
search_note_content
精准定位 →
read_blocks
读取目标 + 上下文 → 编辑
very_large
>80K 字同 large,精准定位优先
search_note_content
get_note_outline
支持分页读取(offset/block_limit)可按需获取结构
原则:文档越大,越应该用搜索定位而非顺序读取。对于 large/very_large 文档,优先使用 search_note_content 找到目标 block,再用 read_blocks 读取其上下文。操作当前笔记时,先调
get_current_note
获取
size_category
,再决定路径
Both
get_current_note
and
get_note_outline
return
word_count
,
size_category
, and
estimated_xml_chars
, based on which you can choose the reading strategy:
size_categoryWord Count RangeStrategy
small
<5K wordsUse
read_note
to read the full text directly
medium
5K-20K wordsUse
get_note_outline
read_section
to read by section
large
20K-80K wordsUse
search_note_content
for precise positioning →
read_blocks
to read the target and context → Edit
very_large
>80K wordsSame as large; prioritize
search_note_content
for precise positioning;
get_note_outline
supports pagination (offset/block_limit) to obtain structure as needed
Principle: The larger the document, the more you should use search positioning instead of sequential reading. For large/very_large documents, first use 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. 编辑笔记内容

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)                → 多个操作合并为一次原子事务
关键:编辑后 block ID 可能变化。连续 insert 可直接使用返回的
last_block_id
做锚点;操作其他 block 前通过
get_note_outline
刷新。
参数约束
edit_block
/
batch_edit
只传当前
op
需要的字段。
replace
/
insert
content
必须直接填写完整 XML 字符串,不能传纯文本、Markdown,或
"把第二段改成……"
这类自然语言编辑指令。
连续插入的正确做法(避免乱序):
  • 优先:在一次
    insert
    中将所有内容拼成完整 XML(如
    "<h2>A</h2><p>...</p><h2>B</h2><p>...</p>"
    ),按 XML 顺序依次插入,无需分多次调用。
  • 链式:如果必须分多次
    insert
    ,每次使用上一次返回的
    last_block_id
    作为下一次的
    anchor_id
    ,或在每次写入后调用
    get_note_outline
    刷新 ID。
get_note_outline(note_id)                      → Get the latest block IDs
get_cursor_block()                            → Get the anchor block when editing around the current cursor position
read_blocks(note_id, [target_id])              → Confirm current content
insert_image(note_id, anchor_id, pos, src)     → Insert image (independent tool, does not use XML, requires internet connection currently)
generate_image(prompt, width?, height?)        → AI text-to-image, returns image URL (use with insert_image to insert into notes)
edit_block(note_id, op, ...)                   → Single edit operation (replace, insert, delete, update attributes, move)
batch_edit(note_id, operations)                → Combine multiple operations into one atomic transaction
Key: Block IDs may change after editing. For consecutive inserts, you can directly use the returned
last_block_id
as the anchor; before operating on other blocks, refresh via
get_note_outline
.
Parameter Constraints:
edit_block
/
batch_edit
only pass the fields required for the current
op
. The
content
for
replace
/
insert
must be a complete XML string, not plain text, Markdown, or natural language editing instructions like "change the second paragraph to...".
Correct way to perform consecutive inserts (avoid out-of-order):
  • Priority: Combine all content into a complete XML in one
    insert
    (e.g.,
    "<h2>A</h2><p>...</p><h2>B</h2><p>...</p>"
    ), insert in XML order, no need to call multiple times.
  • Chained: If you must perform multiple inserts, use the
    last_block_id
    returned from the previous call as the
    anchor_id
    for the next call, or call
    get_note_outline
    to refresh IDs after each write.

3. 批量编辑(原子事务)

3. Batch Editing (Atomic Transaction)

单个操作使用
edit_block
,多个操作使用
batch_edit
合并为原子事务:
undefined
Use
edit_block
for single operations, and
batch_edit
to combine multiple operations into an atomic transaction:
undefined

单个操作

Single operation

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>")
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>")

多个操作(原子事务)

Multiple operations (atomic transaction)

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>" } ])

**执行顺序固定**(`batch_edit`):delete → replace → update_attrs → move → insert(与数组顺序无关)。
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** (for `batch_edit`): delete → replace → update_attrs → move → insert (regardless of array order).

4. 管理笔记与标签

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)                          → 搜索标签
get_note_stats(detailed)                    → 使用统计
get_note_info(note_id)                      → Get single note metadata (including tags)
get_note_info(note_ids: [...])              → Batch get metadata for multiple notes (up to 100)
get_note_info(page, page_size)              → Browse all note metadata by page
search_notes(keyword, tags, since, before)  → Search notes (can also filter by tags)
create_note(title)                          → Create blank note (need to add content with edit_block)
import_web_page(url)                       → Import web pages from whitelisted domains as notes (WeChat Official Accounts, Zhihu, Douban, etc.)
delete_note(note_id)                        → Irrecoverable—must confirm with user first
sync_note(note_id)                          → Trigger synchronization
get_note_stats(detailed)                    → Usage statistics

工具速查表

Tool Cheat Sheet

读取/定位工具

Read/Location Tools

工具用途关键参数
get_note_outline
获取结构大纲(含 title、word_count、block_count、size_category、estimated_xml_chars、blocks 列表、pagination)——获取 block_id 和文档规模的主要方式,超大文档自动分页
note_id
max_depth?
include_preview?
offset?
block_limit?
get_cursor_block
获取当前光标所在顶层 block 的
block_id
block_type
note_id
;光标位于高亮块或分栏内部时不支持
(无参数)
read_blocks
按 ID 批量读取 block 的 XML 内容和属性,或读取单个 block 及前后上下文
note_id
block_ids
(批量)或
block_id
+
before?
+
after?
(上下文)
read_note
读取全文或分页读取(XML),超大文档自动分页并返回 pagination(含 has_more + next_offset)
note_id
max_length?
offset?
block_limit?
search_note_content
在笔记内搜索文本,返回匹配 block 的 block_id/type/preview,用于编辑前定位
note_id
query
max_results?
read_section
按标题读取完整章节(到下一同级标题),截断时返回 next_block_offset 用于续读
note_id
heading_block_id
max_blocks?
block_offset?
read_image
读取图片 block 的实际内容(base64),可供视觉理解
note_id
block_id
get_audio_transcript
获取语音录音(NoteAudioCard)的转写文本,返回句子列表(含说话人、时间戳)
shorthand_id
(从 outline 的
note_audio_card
block attrs 获取)
get_xml_reference
获取 XML 格式完整参考文档(所有标签、属性、写入示例)(无参数)
示例:
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()
ToolPurposeKey Parameters
get_note_outline
Get structural outline (including title, word_count, block_count, size_category, estimated_xml_chars, blocks list, pagination) — main way to get block_id and document scale, automatically paginated for extra-large documents
note_id
max_depth?
include_preview?
offset?
block_limit?
get_cursor_block
Get the
block_id
,
block_type
, and
note_id
of the top-level block where the current cursor is located; not supported when the cursor is inside a highlight block or columns
* (No parameters) *
read_blocks
Batch read 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 full text or paginated content (XML), automatically paginated for extra-large documents and returns pagination (including has_more + next_offset)
note_id
max_length?
offset?
block_limit?
search_note_content
Search text within the note, returns block_id/type/preview of matching blocks, used for positioning before editing
note_id
query
max_results?
read_section
Read a complete section by heading (until the next sibling heading), returns next_block_offset for continuation when truncated
note_id
heading_block_id
max_blocks?
block_offset?
read_image
Read the actual content of an image block (base64), for visual understanding
note_id
block_id
get_audio_transcript
Get transcribed text of voice recordings (NoteAudioCard), returns list of sentences (including speaker, timestamp)
shorthand_id
(obtained from attrs of
note_audio_card
block in outline)
get_xml_reference
Get complete XML format reference document (all tags, attributes, writing examples)* (No parameters) *
Examples:
get_note_outline({ note_id: "abc123" })
get_note_outline({ note_id: "abc123", offset: 100 })  // Continue reading with pagination
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 })  // Continue reading with pagination
read_note({ note_id: "abc123", offset: 0, block_limit: 50 })  // Manually control page size
search_note_content({ note_id: "abc123", query: "Quarterly Summary" })
read_section({ note_id: "abc123", heading_block_id: "aB3kLm9xZq" })
read_section({ note_id: "abc123", heading_block_id: "aB3kLm9xZq", block_offset: 50 })  // Continue reading truncated section
read_image({ note_id: "abc123", block_id: "imgBlock01" })
get_audio_transcript({ shorthand_id: "sh_abc123" })
get_xml_reference()

写入工具

Write Tools

工具用途关键参数
edit_block
单个编辑操作(推荐入口),编辑后 block_id 可能变化需重新获取。insert 操作返回
new_block_ids
last_block_id
。move 操作移动后 block_id 不变
note_id
op
(replace/insert/delete/update_attrs/move)、
block_id
/
anchor_id
/
block_ids
content
/
attrs
batch_edit
多个操作的原子事务(全部成功或全部回滚),执行顺序固定。返回
new_block_ids
last_block_id
note_id
operations[]
insert_image
插入图片(图片不可通过 XML 创建,必须用此工具),当前走在线上传,返回 block_id 和尺寸
note_id
anchor_id
position
src
alt?
generate_image
AI 文生图,返回图片 URL(配合
insert_image
插入笔记)。每用户每分钟限 1 次,耗时 30-120 秒
prompt
width?
(默认 2688)、
height?
(默认 1536)
import_web_page
从白名单域名(微信公众号、知乎、豆瓣等)导入网页内容为笔记,返回笔记 ID、标题和摘要。耗时 5-30 秒
url
edit_block
/
batch_edit
操作类型:
op
必填字段
"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
仅在
replace
/
insert
中出现,且必须是完整 XML 字符串,不是自然语言、纯文本或 Markdown。
文件引用参数(CLI 和脚本场景):当
content
operations
内容过大导致命令行截断时,可使用文件引用替代——
content_file
(传入文件路径,Electron 读取后填入
content
)、
operations_file
(同理填入
operations
)、
__args_file
(从 JSON 文件读取全部参数)。已有显式值时文件引用被忽略。详见
references/CLI_REFERENCE.md
示例:
// 单个操作 — 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" }
ToolPurposeKey Parameters
edit_block
Single edit operation (recommended entry), block_id may change after editing and needs to be re-obtained. Insert operations return
new_block_ids
and
last_block_id
. Move operations do not change block_id
note_id
op
(replace/insert/delete/update_attrs/move)、
block_id
/
anchor_id
/
block_ids
content
/
attrs
batch_edit
Atomic transaction for multiple operations (all succeed or all roll back), execution order is fixed. Returns
new_block_ids
and
last_block_id
note_id
operations[]
insert_image
Insert image (images cannot be created via XML, 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 image URL (use with
insert_image
to insert into notes). Limit 1 time per user per minute, takes 30-120 seconds
prompt
width?
(default 2688)、
height?
(default 1536)
import_web_page
Import web content from whitelisted domains (WeChat Official Accounts, Zhihu, Douban, etc.) as notes, returns note ID, title, and abstract. Takes 5-30 seconds
url
Operation types for
edit_block
/
batch_edit
:
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
only appears 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
are too large to cause command line truncation, you can use file references instead—
content_file
(pass file path, Electron reads it and fills into
content
),
operations_file
(fills into
operations
similarly),
__args_file
(reads all parameters from JSON file). Explicit values take precedence over file references. See
references/CLI_REFERENCE.md
for details.
Examples:
// Single operation — edit_block
edit_block({ note_id: "abc123", op: "replace", block_id: "xY7nPq2wRt", content: "<p>Updated paragraph text</p>" })
edit_block({ note_id: "abc123", op: "insert", anchor_id: "aB3kLm9xZq", position: "after", content: "<h2>New Section</h2><p>This is new content.</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" })

// Multiple operations (atomic transaction) — batch_edit
batch_edit({ note_id: "abc123", operations: [
  { op: "replace", block_id: "xY7nPq2wRt", content: "<p>Updated paragraph text</p>" },
  { op: "insert", anchor_id: "aB3kLm9xZq", position: "after", content: "<h2>New Section</h2>" }
]})

// Image
insert_image({ note_id: "abc123", anchor_id: "aB3kLm9xZq", position: "after", src: "https://example.com/photo.png", alt: "Diagram" })

// AI text-to-image → Insert into note
generate_image({ prompt: "An orange cat sitting on a windowsill, watercolor style, warm tones" })
→ { image_url: "https://...", task_id: "...", width: 2688, height: 1536 }
// Then use insert_image to insert the returned image_url into the note

// Import web page as note
import_web_page({ url: "https://mp.weixin.qq.com/s/xxx" })
→ { fileId: "123456", title: "Article Title", intro: "Abstract...", linkUrl: "https://xxx/note/123456" }

隐藏写入工具

Hidden Write Tools

以下工具仍可用但默认不展示,适用于需要单独调用的场景:
工具用途关键参数
replace_block
替换单个 block 内容
note_id
block_id
content
insert_block
在指定位置前后插入
note_id
anchor_id
position
content
delete_blocks
删除 block
note_id
block_ids
update_block_attrs
修改 block 属性
note_id
block_id
attrs
The following tools are still available but not displayed by default, suitable for scenarios that require separate calls:
ToolPurposeKey Parameters
replace_block
Replace content of a single block
note_id
block_id
content
insert_block
Insert before/after specified position
note_id
anchor_id
position
content
delete_blocks
Delete blocks
note_id
block_ids
update_block_attrs
Modify block attributes
note_id
block_id
attrs

管理工具

Management Tools

工具用途关键参数
list_notes
列出笔记,支持排序和分页,返回 { notes, meta }
limit?
sort?
direction?
since?
before?
page?
page_size?
starred?
create_note
创建空白笔记(仅含空段落),返回 { fileId, title }
title?
get_note_info
获取笔记元数据(不读全文),返回 title、时间、intro、tags、starred
note_id
(单个)、
note_ids
(批量)、
limit?
page
+
page_size
(分页)
get_current_note
获取当前笔记 ID、元数据和文档统计(含 word_count、size_category)(无参数)
get_cursor_block
获取当前光标所在 block 的
block_id
block_type
note_id
;位于高亮块/分栏内部时不支持
(无参数)
search_notes
搜索笔记(关键词 + 标签交集 + 时间范围),也可仅传 tags 按标签浏览
keyword?
tags?
since?
before?
sort?
direction?
limit?
starred?
find_tags
列出或搜索标签,返回 { id, name } 数组
keyword?
(不传列出全部,传入则搜索)
sync_note
触发笔记与云端同步
note_id
delete_note
永久删除笔记(不可恢复),须先与用户确认
note_id
note_ids
(批量,最多 100)
get_note_stats
使用统计(总笔记数、标签数、分布等)
detailed?
get_mcp_logs
MCP 调用日志,用于诊断
INTERNAL_ERROR
limit?
示例:
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: "工作" })    // 搜索标签
delete_note({ note_id: "abc123" })  // 不可恢复——必须先与用户确认!
get_mcp_logs({ limit: 20 })       // 查看最近的工具调用日志
ToolPurposeKey Parameters
list_notes
List notes, supports sorting and pagination, returns { notes, meta }
limit?
sort?
direction?
since?
before?
page?
page_size?
starred?
create_note
Create blank note (only contains empty paragraph), returns { fileId, title }
title?
get_note_info
Get note metadata (does not read full text), returns title, time, intro, tags, starred
note_id
(single)、
note_ids
(batch)、
limit?
page
+
page_size
(pagination)
get_current_note
Get current note ID, metadata, and document statistics (including word_count, size_category)* (No parameters) *
get_cursor_block
Get the
block_id
,
block_type
, and
note_id
of the block where the current cursor is located; not supported when inside a highlight block/columns
* (No parameters) *
search_notes
Search notes (keyword + tag intersection + time range), can also pass only tags to browse by tag
keyword?
tags?
since?
before?
sort?
direction?
limit?
starred?
find_tags
List or search tags, returns array of { id, name }
keyword?
(list all if not passed, search if passed)
sync_note
Trigger synchronization between note and cloud
note_id
delete_note
Permanently delete note (irrecoverable), must confirm with user first
note_id
or
note_ids
(batch, up to 100)
get_note_stats
Usage statistics (total notes, number of tags, distribution, etc.)
detailed?
get_mcp_logs
MCP call logs, used for diagnosing
INTERNAL_ERROR
limit?
Examples:
list_notes({ sort: "update_time", direction: "desc", limit: 10 })
list_notes({ starred: true })                  // List only starred notes
search_notes({ keyword: "Project Plan", tags: ["Work"], since: "2025-01-01T00:00:00Z" })
search_notes({ tags: ["Work"] })  // Filter notes by tag (replaces original list_tag_notes)
search_notes({ starred: true })  // Search only in starred notes
create_note({ title: "Meeting Minutes 2025-03-03" })
get_current_note()
get_cursor_block()
get_note_info({ note_id: "abc123" })              // Single note metadata (including tags)
get_note_info({ note_ids: ["abc123", "def456"] }) // Batch query
get_note_info({ page: 1, page_size: 20 })         // Browse all notes by page
get_note_info({ limit: 5 })                       // Get only the first 5 entries
find_tags()                       // List all tags
find_tags({ keyword: "Work" })    // Search tags
delete_note({ note_id: "abc123" })  // Irrecoverable—must confirm with user first!
get_mcp_logs({ limit: 20 })       // View recent tool call logs

Block 类型与 XML 标签

Block Types and XML Tags

Block 类型XML 标签说明
paragraph
<p>
支持行内 mark(
<strong>
<em>
<s>
<u>
<a>
<tag>
)及行内节点(
<emoji/>
<latex/>
<br/>
heading
<h1>
-
<h6>
级别由标签名或
attrs.level
控制
blockquote
<blockquote>
支持行内 mark 和
<br/>
换行
code_block
<codeblock lang="...">
纯文本内容;语言通过
lang
属性指定
list
<p listType="bullet|ordered|todo">
通过
listType
listLevel
checked
属性控制;有序列表额外支持
listId
listValue
table
<table>
<tr>
<td>
结构;必须整表替换。单元格仅支持简单块(
<p>
<h1>
-
<h6>
<blockquote>
<codeblock>
<hr/>
<img/>
),不可嵌套
<highlightBlock>
<columns>
<table>
等容器
highlight_block
<highlightBlock>
高亮块,仅支持简单块(
<p>
<h1>
-
<h6>
<blockquote>
<codeblock>
<hr/>
<img/>
),不可嵌套
<highlightBlock>
<columns>
<table>
等容器
columns
<columns>
<column>
分栏布局,每个 column 支持简单块和
<highlightBlock>
,不可嵌套
<table>
<columns>
image
<img/>
只读——不可通过 XML 创建或修改,使用
insert_image
工具插入单张图片
image_column
<imageColumn>
只读——图片分栏展示,不可通过 XML 创建
horizontal_rule
<hr/>
分隔线
embed
<embed type="..."/>
只读——不可编辑或替换
note_audio_card
<NoteAudioCard/>
只读——语音录音卡片,使用
get_audio_transcript
获取转写内容
Block TypeXML TagDescription
paragraph
<p>
Supports inline marks (
<strong>
,
<em>
,
<s>
,
<u>
,
<a>
,
<tag>
) and inline nodes (
<emoji/>
,
<latex/>
,
<br/>
)
heading
<h1>
-
<h6>
Level is controlled by tag name or
attrs.level
blockquote
<blockquote>
Supports inline marks and
<br/>
line breaks
code_block
<codeblock lang="...">
Plain text content; language is specified via
lang
attribute
list
<p listType="bullet|ordered|todo">
Controlled by
listType
,
listLevel
,
checked
attributes; ordered lists additionally support
listId
and
listValue
table
<table>
<tr>
<td>
structure; must be replaced in full. Cells only support simple blocks (
<p>
,
<h1>
-
<h6>
,
<blockquote>
,
<codeblock>
,
<hr/>
,
<img/>
), cannot nest
<highlightBlock>
,
<columns>
,
<table>
or other containers
highlight_block
<highlightBlock>
Highlight block, only supports simple blocks (
<p>
,
<h1>
-
<h6>
,
<blockquote>
,
<codeblock>
,
<hr/>
,
<img/>
), cannot nest
<highlightBlock>
,
<columns>
,
<table>
or 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
insert_image
tool to insert single image
image_column
<imageColumn>
Read-only—image column display, cannot be created via XML
horizontal_rule
<hr/>
Horizontal rule
embed
<embed type="..."/>
Read-only—cannot be edited or replaced
note_audio_card
<NoteAudioCard/>
Read-only—voice recording card, use
get_audio_transcript
to get transcribed content

update_block_attrs
支持的属性

Attributes Supported by
update_block_attrs

Block 类型属性可选值
heading
level
1–6
heading
textAlign
"left"
"center"
"right"
paragraph
textAlign
"left"
"center"
"right"
code_block
language
语言标识字符串
todo_list
子项
checked
true
/
false
Block TypeAttributeOptional Values
heading
level
1–6
heading
textAlign
"left"
,
"center"
,
"right"
paragraph
textAlign
"left"
,
"center"
,
"right"
code_block
language
Language identifier string
todo_list
item
checked
true
/
false

Troubleshooting

Troubleshooting

block ID 失效(
BLOCK_NOT_FOUND

Invalid Block ID (
BLOCK_NOT_FOUND
)

现象:写入操作报
BLOCK_NOT_FOUND
,即使之前刚读取过该 block。 原因:编辑操作会导致 block ID 变化,缓存的 ID 已过期。 解决:写入前总是先
get_note_outline
search_note_content
刷新 ID;或使用上次 insert 返回的
last_block_id
作为下次
anchor_id
Symptom: Write operations report
BLOCK_NOT_FOUND
, even though the block was just read. Cause: Editing operations cause block IDs to change, and cached IDs are expired. Solution: Always refresh IDs via
get_note_outline
or
search_note_content
before writing; or use the
last_block_id
returned from the previous insert as the next
anchor_id
.

表格编辑失败

Table Editing Failure

现象:尝试编辑表格单元格时报错或内容丢失。 原因:表格只支持整表替换,不能编辑单个单元格。 解决:用
edit_block
replace
操作传入完整的 XML 表格(含表头分隔行)。
Symptom: Errors or content loss when trying to edit table cells. Cause: Tables only support full replacement; individual cells cannot be edited. Solution: Use the
replace
operation of
edit_block
to pass the complete XML table (including header separator row).

embed block 不可写

Embed Block Cannot Be Written

现象:对 embed block 调用
edit_block
replace
操作返回错误。 原因:电子表格、视频、音频、LaTeX 等嵌入内容为只读占位符。 解决:跳过 embed block,仅操作其他可编辑 block 类型。
Symptom: Calling
replace
operation of
edit_block
on embed blocks returns an error. Cause: Embedded content like spreadsheets, videos, audio, LaTeX, etc., are read-only placeholders. Solution: Skip embed blocks and only operate on other editable block types.

笔记只读(
DOCUMENT_READ_ONLY

Read-Only Note (
DOCUMENT_READ_ONLY
)

现象:所有写入操作均返回
DOCUMENT_READ_ONLY
原因:当前笔记 token 为只读权限,不可重试。 解决:告知用户此笔记为只读。读取操作仍正常。
Symptom: All write operations return
DOCUMENT_READ_ONLY
. Cause: The current note token has read-only permission, cannot retry. Solution: Inform the user that this note is read-only. Read operations still work normally.

编辑器未就绪(
EDITOR_NOT_READY

Editor Not Ready (
EDITOR_NOT_READY
)

现象:操作返回
EDITOR_NOT_READY
原因:笔记编辑器仍在初始化,通常 1-2 秒可恢复。 解决:等待片刻后重试。若 3 次仍失败,请用户检查笔记应用。
Symptom: Operations return
EDITOR_NOT_READY
. Cause: The note editor is still initializing, usually recovers in 1-2 seconds. Solution: Wait a moment and retry. If it fails 3 times, ask the user to check the note app.

WebSocket 未连接(
WEBSOCKET_NOT_CONNECTED

WebSocket Not Connected (
WEBSOCKET_NOT_CONNECTED
)

现象
get_audio_transcript
返回
WEBSOCKET_NOT_CONNECTED
原因:网络断开或 WebSocket 连接中断。 解决:检查网络连接,等待 WebSocket 自动重连后重试。
Symptom:
get_audio_transcript
returns
WEBSOCKET_NOT_CONNECTED
. Cause: Network disconnected or WebSocket connection interrupted. Solution: Check network connection, wait for WebSocket to reconnect automatically and retry.

其他注意事项

Other Notes

  • 图片必须使用
    insert_image
    工具
    :图片不可通过 XML 创建(
    <img/>
    标签为只读)。
    insert_image
    当前走在线上传,调用时需联网。支持 HTTP/HTTPS URL 和 base64 data URI。本地文件路径不支持直接传入,需先读取并转为 base64 data URIURL 必须直接指向图片资源(返回 image/ 内容类型),不可为 HTML 页面链接*。若 URL 返回 404、离线或非图片内容,将报
    IMAGE_FETCH_FAILED
    错误。
    edit_block
    的 replace/insert/update_attrs 不支持图片(但 move 可以移动图片 block)。
  • generate_image
    为 AI 文生图
    :返回图片 URL,而不是直接插入笔记。需配合
    insert_image
    使用。每用户每分钟限 1 次,生成耗时约 30-120 秒。
  • import_web_page
    仅支持白名单域名
    :微信公众号、知乎、豆瓣等白名单域名可导入,非白名单域名会返回
    INVALID_PARAMS
    。转换耗时约 5-30 秒。导入完成后自动创建新笔记并跳转。
  • batch_edit
    执行顺序固定
    :delete → replace → update_attrs → move → insert,与数组顺序无关。
  • move
    操作支持所有 block 类型
    :包括图片(
    <img/>
    )、嵌入内容(
    <embed/>
    )等无法通过 XML 创建的只读标签。移动后 block_id 保持不变,无需刷新 outline。适用于调整内容顺序、重新组织文档结构。
  • create_note
    创建空白笔记
    :不支持初始内容,需用
    edit_block
    填充。
  • read_section
    仅限标题
    heading_block_id
    必须指向
    heading
    block,否则报
    INVALID_BLOCK_TYPE
  • get_cursor_block
    仅支持顶层 block
    :光标位于高亮块(subdoc)或分栏(columns)内部时,会返回
    UNSUPPORTED_POSITION
  • delete_note
    不可恢复
    :必须先与用户确认。
  • 当响应包含
    hints
    时,遵循其建议——它们指明了最快的恢复路径。
  • Images must use the
    insert_image
    tool
    : Images cannot be created via XML (the
    <img/>
    tag is read-only).
    insert_image
    currently uses online upload, requires internet connection when called. Supports HTTP/HTTPS URLs and base64 data URIs. Local file paths are not supported directly; they need to be read and converted to base64 data URIs first. URLs must directly point to image resources (return image/ content type), not HTML page links*. If the URL returns 404, is offline, or is non-image content, it will report
    IMAGE_FETCH_FAILED
    error.
    edit_block
    's replace/insert/update_attrs does not support images (but move can move image blocks).
  • generate_image
    is AI text-to-image
    : Returns image URL, not directly inserted into notes. Need to use with
    insert_image
    . Limit 1 time per user per minute, takes about 30-120 seconds to generate.
  • import_web_page
    only supports whitelisted domains
    : Whitelisted domains like WeChat Official Accounts, Zhihu, Douban can be imported; non-whitelisted domains will return
    INVALID_PARAMS
    . Conversion takes about 5-30 seconds. After import, a new note is automatically created and opened.
  • batch_edit
    execution order is fixed
    : delete → replace → update_attrs → move → insert, regardless of array order.
  • move
    operation supports all block types
    : Including read-only tags that cannot be created via XML, such as images (
    <img/>
    ), embedded content (
    <embed/>
    ), etc. Block_id remains unchanged after moving, no need to refresh outline. Suitable for adjusting content order and reorganizing document structure.
  • create_note
    creates blank note
    : Does not support initial content; need to fill with
    edit_block
    .
  • 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 irrecoverable
    : Must confirm with user first.
  • When the response contains
    hints
    , follow the suggestions—they indicate the fastest recovery path.

错误码速查

Error Code Quick Reference

错误码可重试恢复方法
INVALID_PARAMS
按 inputSchema 修正参数
EDITOR_NOT_READY
等待后重试
NO_ACTIVE_EDITOR_WINDOW
请用户打开笔记窗口
BLOCK_NOT_FOUND
刷新大纲获取有效 ID
INVALID_BLOCK_TYPE
检查 block 类型
INVALID_CONTENT
修正内容格式
DOCUMENT_READ_ONLY
告知用户
FRONTEND_TIMEOUT
缩小范围或重试
IMAGE_FETCH_FAILED
检查图片 URL 是否直接指向图片资源,修正后重试
GENERATE_IMAGE_FAILED
修正 prompt 或检查白名单/登录状态
RATE_LIMITED
等待 60 秒后重试
WEBSOCKET_NOT_CONNECTED
检查网络,等待 WebSocket 重连后重试
INTERNAL_ERROR
重试;查
get_mcp_logs
(隐藏工具)
完整错误详情参见
references/ERROR_CODES.md
Error CodeRetryableRecovery Method
INVALID_PARAMS
NoCorrect parameters according to inputSchema
EDITOR_NOT_READY
YesWait and retry
NO_ACTIVE_EDITOR_WINDOW
YesAsk user to open note window
BLOCK_NOT_FOUND
NoRefresh outline to get valid IDs
INVALID_BLOCK_TYPE
NoCheck block type
INVALID_CONTENT
NoCorrect content format
DOCUMENT_READ_ONLY
NoInform user
FRONTEND_TIMEOUT
YesNarrow scope or retry
IMAGE_FETCH_FAILED
YesCheck if image URL directly points to image resource, correct and retry
GENERATE_IMAGE_FAILED
NoCorrect prompt or check whitelist/login status
RATE_LIMITED
YesWait 60 seconds and retry
WEBSOCKET_NOT_CONNECTED
YesCheck network, wait for WebSocket to reconnect and retry
INTERNAL_ERROR
YesRetry; check
get_mcp_logs
(hidden tool)
Complete error details can be found in
references/ERROR_CODES.md
.

常用编排模式

Common Orchestration Patterns

最高频的多工具组合,无需查阅完整用例手册即可使用。
模式 1:搜索定位 → 分段读取(长文档优先)
search_notes({ keyword }) → note_id
get_note_outline({ note_id }) → heading block ID
read_section({ note_id, heading_block_id }) → 按需读取章节
模式 2:笔记内批量搜索替换
search_note_content({ note_id, query }) → 匹配的 block_id 列表
read_blocks({ note_id, block_ids }) → 读取完整内容
batch_edit({ note_id, operations: [{ op: "replace", ... }, ...] }) → 原子替换
模式 3:创建 → 填充模板
create_note({ title }) → note_id(空白笔记)
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>" }
]})
模式 4:连续追加多段内容(避免乱序)
undefined
The most frequent multi-tool combinations, usable without referring to the complete use case manual.
Pattern 1: Search Positioning → Sectional Reading (priority for long documents)
search_notes({ keyword }) → note_id
get_note_outline({ note_id }) → heading block ID
read_section({ note_id, heading_block_id }) → Read sections as needed
Pattern 2: Batch Search and Replace in Notes
search_note_content({ note_id, query }) → List of matching block_ids
read_blocks({ note_id, block_ids }) → Read full content
batch_edit({ note_id, operations: [{ op: "replace", ... }, ...] }) → Atomic replacement
Pattern 3: Create → Fill Template
create_note({ title }) → note_id (blank note)
get_note_outline({ note_id }) → Get empty block ID
batch_edit({ note_id, operations: [
  { op: "replace", block_id, content: "<h1>Title</h1>" },
  { op: "insert", anchor_id, position: "after", content: "<p>Template content...</p>" }
]})
Pattern 4: Append Multiple Sections Continuously (avoid out-of-order)
undefined

方式 A(推荐):单次 insert 拼接完整 XML

Method A (recommended): Single insert with complete XML

edit_block({ note_id, op: "insert", anchor_id: "last_id", position: "after", content: "<h2>第一部分</h2><p>内容 A</p><h2>第二部分</h2><p>内容 B</p>" })
edit_block({ note_id, op: "insert", anchor_id: "last_id", position: "after", content: "<h2>Part 1</h2><p>Content A</p><h2>Part 2</h2><p>Content B</p>" })

方式 B:链式 insert,用上次返回的 last_block_id 做锚点

Method B: Chained insert, use last_block_id from previous return as anchor

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" }

**模式 5:移动 block(图片、嵌入内容等)**
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

**模式 6:分页读取超大文档**(无标题结构时优先,分页仅控制读取量,笔记无 block 上限)
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 } ← 读完

更多组合模式和端到端场景参见 `references/USE_CASES.md`。
edit_block({ ..., anchor_id: "id1", position: "after", content: "<h2>Part 1</h2><p>Content A</p>" }) → { last_block_id: "new_id_1" } edit_block({ ..., anchor_id: "new_id_1", position: "after", content: "<h2>Part 2</h2><p>Content B</p>" }) → { last_block_id: "new_id_2" }

**Pattern 5: Move Blocks (images, embedded content, etc.)**
get_note_outline({ note_id }) → Find source block and target position edit_block({ note_id, op: "move", block_id: "img_id", anchor_id: "target_heading", position: "after" }) → block_id remains unchanged, no need to refresh outline

**Pattern 6: Paginate to Read Extra-Large Documents** (priority when there is no title structure; pagination only controls reading amount, no block limit for notes)
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 } ← Finished reading

More combination patterns and end-to-end scenarios can be found in `references/USE_CASES.md`.

完整示例

Complete Example

用户说:"帮我找到 Q1 报告,更新摘要部分,加一个结论"
步骤 1:定位笔记
search_notes({ keyword: "Q1 报告" })
→ data.notes[0].note_id = "note_xyz"
步骤 2:读取结构
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: "继续监控..." }
  ]
步骤 3:确认当前内容
read_blocks({ note_id: "note_xyz", block_ids: ["p1def"] })
→ "本季度各部门..."
步骤 4:原子编辑(替换摘要 + 插入结论)
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"
提示:
batch_edit
/
edit_block
的 insert 操作中,content 可包含多个块级 XML 元素(如上例的
<h2>
+
<p>
),它们按 XML 顺序插入,无需分多次调用。返回的
last_block_id
可直接用于后续操作。
步骤 5:验证结果
read_section({ note_id: "note_xyz", heading_block_id: "h1abc", max_blocks: 5 })
→ 确认摘要已更新、结论已添加
结果:笔记摘要已替换为新内容,文末新增"总结"章节。
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 Report" })
→ data.notes[0].note_id = "note_xyz"
Step 2: Read structure
get_note_outline({ note_id: "note_xyz" })
→ blocks: [
    { id: "h1abc", type: "heading", preview: "Q1 Report" },
    { id: "p1def", type: "paragraph", preview: "Executive Summary..." },
    { id: "h2ghi", type: "heading", preview: "Revenue" },
    { id: "h2jkl", type: "heading", preview: "Next Steps" },
    { id: "p3mno", type: "paragraph", preview: "Continue monitoring..." }
  ]
Step 3: Confirm current content
read_blocks({ note_id: "note_xyz", block_ids: ["p1def"] })
→ "This quarter, each department..."
Step 4: Atomic edit (replace summary + insert conclusion)
batch_edit({ note_id: "note_xyz", operations: [
  { op: "replace", block_id: "p1def",
    content: "<p>This report covers the performance of all departments in Q1 2025. Revenue exceeded the target by 15%.</p>" },
  { op: "insert", anchor_id: "p3mno", position: "after",
    content: "<h2>Conclusion</h2><p>Q1 2025 was a strong quarter, with all key indicators achieving significant growth.</p>" }
]})
→ ok: true, last_block_id: "new_conclusion_id"
Tip: In the insert operation of
batch_edit
/
edit_block
, content can contain multiple block-level XML elements (like
<h2>
+
<p>
in the example), which are inserted in XML order without needing multiple calls. The returned
last_block_id
can be directly used for subsequent operations.
Step 5: Verify results
read_section({ note_id: "note_xyz", heading_block_id: "h1abc", max_blocks: 5 })
→ Confirm summary is updated and conclusion is added
Result: The note summary has been replaced with new content, and a "Conclusion" section has been added at the end.

参考文档

Reference Documents

  • API 参考——全部工具的完整 inputSchema
  • CLI 参考——
    wpsnote-cli
    的 canonical 命令面、CLI 特有行为和 JSON 输出格式
  • 错误码——详细错误码、hints 系统和恢复模式
  • 用例手册——按复杂度递进的完整用例集(含端到端工作流示例)、Prompt 模板和异常处理速查
  • API Reference——Complete inputSchema for all tools
  • CLI Reference——Canonical command interface for
    wpsnote-cli
    , CLI-specific behaviors, and JSON output format
  • Error Codes——Detailed error codes, hints system, and recovery modes
  • Use Case Manual——Complete use case set (including end-to-end workflow examples) by complexity, prompt templates, and quick reference for exception handling