> ## Documentation Index
> Fetch the complete documentation index at: https://dev.marginnote.com.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 获取手写能力清单

> 调用手写会话的其他路由之前须先读取该接口，确认 MarginNote 支持的子能力。

该接口返回能力清单，不构成可写许可。清单里某项开关为假时，对应的那一类操作当前不可用。




## OpenAPI

````yaml /openapi/plugin-api.yaml get /writing/capabilities
openapi: 3.1.0
info:
  title: 场景插件 API
  summary: 场景插件在网页面板里可以调用的接口。
  description: >
    场景插件的面板是一个网页。页面里向 `/bridge/v1` 发请求，就能读写 MarginNote 里的数据。

    请求由 MarginNote 处理，与外部命令行工具共用同一套处理代码。外部工具要带令牌，面板不必带。

    面板页面从 `mnpanel://panel/index.html` 加载，因此 `fetch('/bridge/v1' + path)`
    属于同源请求。


    面板调用受这些条件约束：


    - 请求不带令牌，本文件也不声明安全方案。

    - 页面能调用哪些接口，取决于两份名单。模板里的 `plugins` 名单和沉浸态决定面板能不能建好，
      网页面板白名单决定页面能调哪些接口。不在白名单里的请求返回 `403`，
      错误码为 `IN_PROCESS_NOT_ALLOWED`。
    - `GET /capabilities` 里的 `requiresMax` 只约束外部 Agent。面板的请求在 MarginNote 进程内处理，
      不受令牌、订阅状态与跨设备批准的限制，能否调用只看该路径是否在白名单内。
    - 写操作里的 `addon`，MarginNote 会改写为当前面板所属插件的 id；`confirm` 由 MarginNote 补上。
      页面填的值不会生效。

    用 `mn.api(path, opts)` 读取数据。该方法始终将 Response Body 按 JSON 解析，相当于

    `fetch('/bridge/v1' + path, opts).then(r => r.json())`。


    响应的内容不是 JSON 的接口，改用 `fetch`：


    - `GET /guide` 返回 Markdown 正文。

    - `GET /notes/{noteid}/render` 返回卡片长图或 PDF。

    - `GET /documents/{bookmd5}/pages/{index}/content/{contentId}` 返回图片。

    - `GET /bundles/{bundleId}/files` 带 `?path=` 时返回该文件的原始字节。


    调用失败时 Promise 不会进入 reject。MarginNote 把错误对象

    `{"error":{"code":"…","message":"…"}}` 当作 Response Body 返回，因此结果落在 resolve 里。

    判断调用结果看响应里是否带 `error`，写操作另看响应里的 `persisted`。


    接口清单、各项上限与 Request Body 结构随 MarginNote 的版本变化，运行时以 `GET /capabilities` 与

    `GET /guide` 返回的内容为准。
  version: '0.91'
servers: []
security: []
tags:
  - name: 能力与状态
    description: 读取 MarginNote 的能力、版本与当前上下文。调用其他接口之前先读这组。
  - name: 卡片与摘录
    description: 卡片的读取与写入、摘录的创建、批注、标签、元数据与留白。
  - name: 手写会话
    description: 手写层、作答纸、练习准备清单与会话记录的读取与提交。
  - name: 学习集与卡组
    description: 学习集结构、脑图树、子脑图、色板、快照与复习卡组。
  - name: 文档与页面
    description: 文档目录、页文本、页内注释面、摘录清单与同步诊断。
  - name: 导出与 Anki
    description: 文档导出计划、导出文件、Anki 导出能力、作业与产物。
  - name: 查找
    description: 跨库搜索、文件夹列表与学习集列表。
  - name: 界面与模板
    description: 读取当前界面状态与沉浸模板。
  - name: 插件辅助
    description: 面板辅助脚本、已配对设备与本机 helper 信息。
  - name: 任务包与同步诊断
    description: 拆书任务包与旧 CloudKit 同步诊断。
paths:
  /writing/capabilities:
    get:
      tags:
        - 手写会话
      summary: 获取手写能力清单
      description: |
        调用手写会话的其他路由之前须先读取该接口，确认 MarginNote 支持的子能力。

        该接口返回能力清单，不构成可写许可。清单里某项开关为假时，对应的那一类操作当前不可用。
      operationId: getWritingCapabilities
      responses:
        '200':
          description: 能力清单。可读的子项与 `GET /capabilities` 的手写会话分组同形。
          content:
            application/json:
              schema:
                type: object
                properties:
                  carriers:
                    type: array
                    items:
                      type: string
                  routes:
                    type: object
                    properties:
                      content:
                        type: string
                      context:
                        type: string
                      resolve:
                        type: string
                      windows:
                        type: string
                  prepare:
                    type: boolean
                  includesUnsavedCanvas:
                    type: boolean
                  managedLayers:
                    type: boolean
                  windowEnumeration:
                    type: boolean
                  confirmsWritable:
                    type: boolean
                  pencilCommit:
                    type: object
                    properties:
                      canSwitch:
                        type: boolean
                      carriers:
                        type: array
                        items:
                          type: string
                      inputFrozen:
                        type: boolean
                      operationRecord:
                        type: string
                      requiresConfirm:
                        type: boolean
                      result:
                        type: string
                      submit:
                        type: string
                  focusTransition:
                    type: object
                    properties:
                      changesLayer:
                        type: boolean
                      createsAttempt:
                        type: boolean
                      result:
                        type: string
                      savesCurrentPencil:
                        type: boolean
                      submit:
                        type: string
                  ownedBlankEntry:
                    type: object
                    properties:
                      changesLayer:
                        type: boolean
                      createsAttempt:
                        type: boolean
                      opensOwnedBlank:
                        type: boolean
                      result:
                        type: string
                      submit:
                        type: string
                  stage:
                    type: string
                  practiceSessionRecord:
                    type: object
                    properties:
                      assess:
                        type: string
                      blankBegin:
                        type: string
                      canCreate:
                        type: boolean
                      canSwitch:
                        type: boolean
                      cancel:
                        type: string
                      create:
                        type: string
                      finish:
                        type: string
                      focusBegin:
                        type: string
                      pause:
                        type: string
                      preview:
                        type: string
                      read:
                        type: string
                      ready:
                        type: boolean
                      reconcile:
                        type: string
                      reserve:
                        type: string
                      restore:
                        type: string
                      result:
                        type: string
                      resume:
                        type: string
                      storage:
                        type: string
                  bridgeApiVersion:
                    type: string
                  documentPencilCommit:
                    type: object
                    properties:
                      canSwitch:
                        type: boolean
                      inputFrozen:
                        type: boolean
                      requiresConfirm:
                        type: boolean
                      result:
                        type: string
                      submit:
                        type: string
                      targetFrom:
                        type: string
                      writers:
                        type: array
                        items:
                          type: string
                  ownedBlankPreparation:
                    type: object
                    properties:
                      changesLayer:
                        type: boolean
                      createsAttempt:
                        type: boolean
                      opensAnswerSpace:
                        type: boolean
                      result:
                        type: string
                      submit:
                        type: string
                  sessionContext:
                    type: boolean
                  resolve:
                    type: boolean
                  flush:
                    type: boolean
                  pencilInputGate:
                    type: object
                    properties:
                      grantsCallerLease:
                        type: boolean
                      maximumSeconds:
                        type: integer
                      programmaticNavigationBlocked:
                        type: boolean
                      scope:
                        type: string
                  liveWindowContext:
                    type: boolean
                  contentInventory:
                    type: boolean
                  practiceOnCurrentLayer:
                    type: object
                    properties:
                      blankEnter:
                        type: string
                      changesLayer:
                        type: boolean
                      createsAttempt:
                        type: boolean
                      exit:
                        type: string
                      focusEnter:
                        type: string
                      restoresOnExit:
                        type: boolean
                      result:
                        type: string
                      takesLease:
                        type: boolean
                  managedLayerTrial:
                    type: object
                    properties:
                      blankBegin:
                        type: string
                      canSwitch:
                        type: boolean
                      compact:
                        type: string
                      confirmsPersistedLayer:
                        type: boolean
                      createsAttempt:
                        type: boolean
                      focusBegin:
                        type: string
                      leaseStorage:
                        type: string
                      read:
                        type: string
                      ready:
                        type: boolean
                      restore:
                        type: string
                      result:
                        type: string
                  schemaVersion:
                    type: integer
                  snapshot:
                    type: boolean
                  practicePlan:
                    type: object
                    properties:
                      maxQuestions:
                        type: integer
                      read:
                        type: string
                      save:
                        type: string
                      startsWriting:
                        type: boolean
                      storage:
                        type: string
                  switch:
                    type: boolean
                  limits:
                    type: object
                    properties:
                      layerIds:
                        type: integer
                      parts:
                        type: integer
                      rows:
                        type: integer
              examples:
                measured:
                  summary: 实测于 2026-10-07，App 0.91
                  value:
                    carriers:
                      - blank
                      - focus
                    routes:
                      content: /writing/content
                      context: /writing/context
                      resolve: /writing/resolve
                      windows: /writing/windows
                    prepare: false
                    includesUnsavedCanvas: false
                    managedLayers: false
                    windowEnumeration: true
                    confirmsWritable: false
                    pencilCommit:
                      canSwitch: false
                      carriers:
                        - focus
                      inputFrozen: false
                      operationRecord: process-local
                      requiresConfirm: true
                      result: /writing/pencil-result
                      submit: /writing/pencil-commit
                    focusTransition:
                      changesLayer: false
                      createsAttempt: false
                      result: /writing/transition-result
                      savesCurrentPencil: true
                      submit: /writing/focus-enter
                    ownedBlankEntry:
                      changesLayer: false
                      createsAttempt: false
                      opensOwnedBlank: true
                      result: /writing/transition-result
                      submit: /writing/blank-enter
                    stage: persisted-inspection
                    practiceSessionRecord:
                      assess: /writing/session-assess
                      blankBegin: /writing/session-blank-begin
                      canCreate: true
                      canSwitch: false
                      cancel: /writing/session-cancel
                      create: /writing/session-create
                      finish: /writing/session-finish
                      focusBegin: /writing/session-focus-begin
                      pause: /writing/session-pause
                      preview: /writing/session-preview
                      read: /writing/session-read
                      ready: false
                      reconcile: /writing/session-reconcile
                      reserve: /writing/session-reserve
                      restore: /writing/session-layer-restore
                      result: /writing/transition-result
                      resume: /writing/session-resume
                      storage: device-local
                    bridgeApiVersion: '0.91'
                    documentPencilCommit:
                      canSwitch: false
                      inputFrozen: false
                      requiresConfirm: true
                      result: /writing/pencil-result
                      submit: /writing/pencil-document-commit
                      targetFrom: >-
                        context.surfaces[].state.visiblePages[].continuousCommitTarget|pagedCommitTarget
                      writers:
                        - continuous
                        - paged
                    ownedBlankPreparation:
                      changesLayer: false
                      createsAttempt: false
                      opensAnswerSpace: false
                      result: /writing/transition-result
                      submit: /writing/blank-prepare
                    sessionContext: false
                    resolve: true
                    flush: false
                    pencilInputGate:
                      grantsCallerLease: false
                      maximumSeconds: 15
                      programmaticNavigationBlocked: false
                      scope: application-ui-only
                    liveWindowContext: true
                    contentInventory: true
                    practiceOnCurrentLayer:
                      blankEnter: /writing/session-blank-enter
                      changesLayer: false
                      createsAttempt: false
                      exit: /writing/session-exit
                      focusEnter: /writing/session-focus-enter
                      restoresOnExit: false
                      result: /writing/transition-result
                      takesLease: false
                    managedLayerTrial:
                      blankBegin: /writing/blank-begin
                      canSwitch: false
                      compact: /writing/layer-compact
                      confirmsPersistedLayer: true
                      createsAttempt: false
                      focusBegin: /writing/focus-begin
                      leaseStorage: device-local
                      read: /writing/layer-leases
                      ready: false
                      restore: /writing/layer-restore
                      result: /writing/transition-result
                    schemaVersion: 1
                    snapshot: false
                    practicePlan:
                      maxQuestions: 20
                      read: /writing/plan-read
                      save: /writing/plan-save
                      startsWriting: false
                      storage: device-local
                    switch: false
                    limits:
                      layerIds: 32
                      parts: 2048
                      rows: 256
      x-codeSamples:
        - lang: javascript
          label: 先获取能力清单
          source: |
            const w = await mn.api('/writing/capabilities');
            if (!w) return;
            mn.log(w.limits, w.routes);

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.