PassPaper
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@PassPaperTake a look at what I just wrote on the tablet"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
递纸 PassPaper
中文
在平板上手写公式/草图,AI 通过 MCP 工具实时读取。 支持 Claude Code 和 Codex CLI。
状态:v1.0.0 早期版本。核心功能已实现并通过代码级校验(
py_compile/ import / 识别解析),尚未在大规模真机环境验证。欢迎在 GitHub Issues 反馈问题与使用场景。
[平板 Chrome] [电脑]
手写 canvas ──WebSocket──▶ passpaper daemon (常驻)
│ 笔画落笔即渲染到内存画布
Claude Code / Codex ◀─MCP stdio─ mcp_shim
└──── localhost HTTP ────┘功能
中文潦草 / 公式手写识别(本地、隐私) — 配置本地 VLM(
PASSPAPER_RECOGNIZER_ENDPOINT,如 ollama / llama.cpp / vLLM 的 OpenAI 兼容端点)后,图片在交给 Agent 前会先转成结构化文本 / LaTeX。未配置时回退到「Agent 直接看图」。详见 docs/RECOGNITION.md。低延迟跨设备接力 — 平板落笔即增量渲染到内存画布,取图 = 读缓存(实测约 25ms)。WebSocket 断线时笔画本地缓存,重连后自动批量补发。
手写会话可随项目回溯 — 每一笔落盘为 JSONL(
~/.passpaper/sessions/)。可导出 Markdown / Excalidraw,在 Excalidraw / tldraw 中回放编辑。通用 MCP + 本地优先 — MCP shim 同时支持 Claude Code 和 Codex;数据只走本机和局域网,无账号、无云、无出站调用。设计受多个开源项目启发,逐条署名见 REFERENCES.md。
设计架构:daemon + shim 双层
问题 | 解法 |
AI 客户端里 MCP 加载慢/超时 | shim 纯标准库,握手 <100ms;重活全在 daemon |
连接不稳定 | daemon 常驻,独立于客户端生命周期;日志写文件不写管道;平板断线笔画本地缓存、重连自动补发 |
传输慢 | 笔画到达即增量渲染,取图 = 读缓存(实测约 25ms);图片自动裁切、限制 1568px、调色板 PNG |
每次用每次扫码 | 持久配对码:平板上存书签,点开就写, |
客户端重启后僵尸进程占端口 | shim 在 stdin 关闭时立即退出;daemon 用 PID 文件管理,优雅关机先存盘 |
想用 Codex | 同一 shim, |
快速开始(Windows)
双击
start.bat(自动检测 Python、装依赖、注册、启动 daemon)打开 Claude Code 或 Codex,说 "我要用递纸"
在平板上打开它给你的链接(Chrome),存成书签
写字,然后对 AI 说 "看看我写的"
以后每次用:打开书签直接写。daemon 没跑的话 shim 会自动拉起。
手动命令
python src/passpaper/cli.py setup # 一次性:依赖 + 运行时包 + 注册 CC/Codex
python src/passpaper/cli.py start # 启动 daemon(后台常驻)
python src/passpaper/cli.py status # 健康状态 / 笔画数 / 平板数 / 链接
python src/passpaper/cli.py stop # 优雅停止(先存盘)
python src/passpaper/cli.py doctor # 环境诊断
python src/passpaper/cli.py rotate-token # 配对码泄露时轮换可选开机自启:python src/passpaper/cli.py setup --autostart
MCP 工具
工具 | 用途 |
| 平板链接 + 二维码(AI 首次必调) |
| 当前手写内容(PNG,自动裁切/缩放) |
| 笔画数/修订号/有无新内容(轻量) |
| 清空画布 |
| 存 PNG 到磁盘返回路径(无法接收 MCP 图片的客户端走这里) |
| 列出已录制手写会话(笔画数/时间) |
| 开新会话,旧会话保留可回溯 |
| 导出会话为 md / jsonl / json / excalidraw,可随项目 Git 提交 |
| 调用本地 VLM 识别中文/公式(未配置则回退到 Agent 视觉) |
深入阅读
docs/ARCHITECTURE.md — daemon + shim 双层架构、数据流、延迟与鉴权细节
docs/RECOGNITION.md — 本地中文/公式识别端点配置 + 推荐模型组合
docs/ACCEPTANCE_TEST_PLAN.md — 真机验收清单
PRIVACY.md — 隐私政策:本地优先,无云、无遥测、无出站调用
SECURITY.md — 安全模型:配对令牌、识别端点风险说明、漏洞报告
依赖
Python ≥ 3.10,websockets Pillow qrcode(shim 本身零依赖,纯标准库)。
测试
python scripts/e2e_test.py
# 26 项检查:shim 冷握手速度、daemon 自动拉起、平板 WS、取图延迟、
# 6 万点渲染性能、离线批量补发、优雅关机等设计要点
坐标系:平板端把可视区域等比映射到 2048×1536 规范坐标(letterbox),所见即所得,与设备方向/缩放无关
橡皮擦:白墨覆盖渲染(视觉等同真擦除),擦除笔迹不参与自动裁切
安全:128-bit 持久配对码,WS/HTTP 全部校验;仅局域网监听
运行时包:
setup把 daemon/shim 复制到~/.passpaper/(纯 ASCII 路径),客户端配置指向那里——项目在中文路径下也不会踩 spawn 编码坑环境变量:
PASSPAPER_HOME可改数据目录(测试/便携安装用)
路线图
已发布(v1.0.0)
常驻 daemon + MCP shim
持久配对 / 离线补发 / 增量渲染(~25ms 取图、MCP 握手 <100ms)
手写会话录制 + 多格式导出(md / jsonl / json / excalidraw)
可插拔中文 / 公式识别管线(本地 VLM,无模型时回退)
进行中 / 下一步
真机验收(平板 + Claude Code / Codex 实跑)
PyPI 发布 + MCP 市场提交(
pip install passpaper-mcp)Cloudflare Tunnel 模式(户外 / 跨网络)
笔画级语义擦除
系统托盘 App 形态
更多本地识别后端(PaddleOCR-VL / GLM-OCR 开箱集成)
故障排除
passpaper doctor— 诊断 Python / 依赖 / 运行时包 / MCP 注册 / 配对令牌。daemon 没起来?看
~/.passpaper/daemon.log与~/.passpaper/daemon.spawn.log。端口 8765 被占?
passpaper stop后再passpaper start;或改PORT(需同步改 canvas)。平板连不上:确认与电脑同一 WiFi;用
passpaper url重新获取链接;公司/校园网可能隔离设备——换手机热点测试。识别没反应:未配置
PASSPAPER_RECOGNIZER_ENDPOINT时走「Agent 直接看图」回退,属正常;配置方法见 docs/RECOGNITION.md。
贡献
欢迎 Issue / PR。开发环境、测试与规则见 CONTRIBUTING.md。安全漏洞请私下报告,见 SECURITY.md。
参考与灵感来源
递纸的设计受到多个开源项目的启发,逐条署名见 REFERENCES.md。
License
MIT — Copyright (c) 2026 B.Han.
Related MCP server: io.github.praveensehgal/remarkable
English
Write formulas/sketches on your tablet — the AI reads them in real time through MCP tools. Supports Claude Code and Codex CLI.
Status: v1.0.0 early release. Core features are implemented and verified at the code level (
py_compile/ import / recognition parsing), but not yet validated in large-scale real-device environments. Please report issues and use cases via GitHub Issues.
[Tablet Chrome] [Computer]
handwriting canvas ──WebSocket──▶ passpaper daemon (resident)
│ strokes rendered to in-memory canvas on arrival
Claude Code / Codex ◀─MCP stdio─ mcp_shim
└──── localhost HTTP ────┘Features
Messy-Chinese / formula handwriting recognition (local & private) — After you configure a local VLM (
PASSPAPER_RECOGNIZER_ENDPOINT, e.g. an OpenAI-compatible endpoint from ollama / llama.cpp / vLLM), the image is converted into structured text / LaTeX before being handed to the agent. Without a configured endpoint it falls back to letting the agent look at the image directly. See docs/RECOGNITION.md.Low-latency cross-device relay — Strokes are incrementally rendered to an in-memory canvas as they land on the tablet; capturing an image reads a cache (~25ms measured). On WebSocket disconnect, strokes are cached locally and bulk re-sent on reconnect.
Handwriting sessions traceable per project — Every stroke is persisted to JSONL (
~/.passpaper/sessions/). Sessions can be exported as Markdown / Excalidraw and replayed or edited in Excalidraw / tldraw.Generic MCP + local-first — The MCP shim supports both Claude Code and Codex; data travels only over your own machine and LAN — no account, no cloud, no outbound calls. The design draws inspiration from several open-source projects, credited one by one in REFERENCES.md.
Architecture: daemon + shim
Problem | Solution |
MCP loads slowly / times out inside AI clients | shim is pure stdlib, handshake <100ms; all heavy work lives in the daemon |
Unstable connections | daemon is resident and independent of the client lifecycle; logs go to files, not pipes; tablet strokes cached locally on disconnect, bulk re-sent on reconnect |
Slow transfer | strokes are incrementally rendered on arrival; capture reads a cache (~25ms measured); images auto-cropped, capped at 1568px, palette PNG |
Re-scanning a QR code every time | persistent pairing code: save a bookmark on the tablet, tap to write, valid until rotated ( |
Zombie processes holding the port after client restart | shim exits immediately when stdin closes; daemon is managed via a PID file; graceful shutdown persists data first |
Want to use Codex | same shim — |
Quick start (Windows)
Double-click
start.bat(auto-detects Python, installs dependencies, registers, starts the daemon)Open Claude Code or Codex and say "I want to use PassPaper"
Open the link it gives you on your tablet (Chrome) and save it as a bookmark
Write, then tell the AI "look at what I wrote"
From then on: open the bookmark and just write. If the daemon isn't running, the shim starts it automatically.
Manual commands
python src/passpaper/cli.py setup # one-time: dependencies + runtime package + register CC/Codex
python src/passpaper/cli.py start # start the daemon (resident in background)
python src/passpaper/cli.py status # health / stroke count / tablet count / links
python src/passpaper/cli.py stop # graceful stop (persists data first)
python src/passpaper/cli.py doctor # environment diagnostics
python src/passpaper/cli.py rotate-token # rotate when the pairing code leaksOptional autostart at boot: python src/passpaper/cli.py setup --autostart
MCP tools
Tool | Purpose |
| Tablet link + QR code (the AI must call this first) |
| Current handwriting content (PNG, auto-cropped / scaled) |
| Stroke count / revision / whether new content exists (lightweight) |
| Clear the canvas |
| Save PNG to disk and return the path (for clients that cannot receive MCP images) |
| List recorded handwriting sessions (stroke count / time) |
| Start a new session; old sessions are kept for traceability |
| Export a session as md / jsonl / json / excalidraw, committable with the project's Git |
| Call the local VLM to recognize Chinese / formulas (falls back to agent vision if unconfigured) |
Further reading
docs/ARCHITECTURE.md — daemon + shim architecture, data flow, latency and auth details
docs/RECOGNITION.md — local Chinese / formula recognition endpoint configuration + recommended model combinations
docs/ACCEPTANCE_TEST_PLAN.md — real-device acceptance checklist
PRIVACY.md — privacy policy: local-first, no cloud, no telemetry, no outbound calls
SECURITY.md — security model: pairing token, recognition endpoint risk, vulnerability reporting
Dependencies
Python ≥ 3.10, websockets Pillow qrcode (the shim itself has zero dependencies — pure stdlib).
Testing
python scripts/e2e_test.py
# 26 checks: shim cold-handshake speed, daemon auto-spawn, tablet WS, capture latency,
# 60k-point rendering performance, offline bulk re-send, graceful shutdown, etc.Design notes
Coordinate system: the tablet maps the visible area proportionally onto 2048×1536 canonical coordinates (letterbox) — WYSIWYG, independent of device orientation / zoom
Eraser: white-ink overlay rendering (visually equivalent to a real erase); erased strokes don't participate in auto-cropping
Security: 128-bit persistent pairing code, verified on WS/HTTP; listens on LAN only
Runtime package:
setupcopies daemon/shim to~/.passpaper/(pure ASCII path); client config points there — no spawn encoding issues even when the project lives under a non-ASCII pathEnvironment variable:
PASSPAPER_HOMEchanges the data directory (for testing / portable installs)
Roadmap
Shipped (v1.0.0)
Resident daemon + MCP shim
Persistent pairing / offline re-send / incremental rendering (~25ms capture, MCP handshake <100ms)
Handwriting session recording + multi-format export (md / jsonl / json / excalidraw)
Pluggable Chinese / formula recognition pipeline (local VLM, falls back when no model)
In progress / next
Real-device acceptance (tablet + Claude Code / Codex in actual use)
PyPI release + MCP marketplace submission (
pip install passpaper-mcp)Cloudflare Tunnel mode (outdoor / cross-network)
Stroke-level semantic erasing
System tray app
More local recognition backends (PaddleOCR-VL / GLM-OCR out-of-the-box integration)
Troubleshooting
passpaper doctor— diagnostics for Python / dependencies / runtime package / MCP registration / pairing token.Daemon not starting? Check
~/.passpaper/daemon.logand~/.passpaper/daemon.spawn.log.Port 8765 taken? Run
passpaper stopthenpasspaper start; or changePORT(must also update the canvas).Tablet can't connect: make sure it's on the same WiFi as the computer; re-fetch the link with
passpaper url; corporate / campus networks may isolate devices — try a phone hotspot.Recognition not responding: without
PASSPAPER_RECOGNIZER_ENDPOINTconfigured it falls back to "agent looks at the image directly", which is expected; configuration see docs/RECOGNITION.md.
Contributing
Issues and PRs welcome. Dev environment, tests and rules: see CONTRIBUTING.md. Report security vulnerabilities privately, see SECURITY.md.
References & inspiration
PassPaper's design is inspired by several open-source projects, credited one by one in REFERENCES.md.
Star History
License
MIT — Copyright (c) 2026 B.Han.
Available Tools
9 toolsclear_canvasA
【递纸】Clear the tablet canvas. Call when user says '清空画布', 'clear', '重新开始'.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It clearly states the core effect — clearing the tablet canvas — but does not disclose whether the action is irreversible, whether unsaved content is lost, or whether saved sessions/snapshots are affected. That residual ambiguity keeps this below a 4.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short, front-loaded with the action, and includes concrete trigger examples. The unexplained '【递纸】' prefix adds a small amount of noise, but the operational content is still minimal and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, no-output-schema tool, the description covers the essential 'what' and 'when'. It is missing side-effect context such as irreversibility or whether saved snapshots are preserved, but these are not strictly required to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the input schema is empty, so there are no parameter semantics to add. The baseline for 0-parameter tools is 4, and the description does not need to compensate for any schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and object: 'Clear the tablet canvas', which is unambiguous and immediately distinguishable from the sibling tools (get_handwriting, save_snapshot, export_session, etc.). The included trigger phrases reinforce the exact intent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to call the tool: when the user says '清空画布', 'clear', or '重新开始'. It does not name alternatives or exclusions, but for a zero-parameter clear action the trigger-based guidance is clear and sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_sessionA
【递纸】导出一个手写会话为可移植格式:md(人类可读+识别文本)、jsonl(原始日志)、json(笔画重放)、excalidraw(可在 Excalidraw 打开)。session_id 留空则用当前会话。
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | 导出格式,默认 md | |
| session_id | No | 会话 ID,来自 list_sessions;留空=当前会话 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. It explains what each format represents (human-readable text, raw logs, stroke replay, Excalidraw compatibility) and the blank-session default. It could mention side effects or the return envelope, but the core behavior is well disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense sentence with no fluff. It front-loads the action and resource, then packs the format options and default behavior into a compact, easily scannable structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with two optional parameters and no output schema, the description covers the core decisions: which format to choose and which session to export. It does not describe the exact return shape, but that is not required to invoke the tool correctly, and the format semantics provide sufficient operational context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by explaining the semantic meaning of each format enum value and confirming the session_id default behavior, which goes slightly beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('导出') with a clear resource ('手写会话') and enumerates the exact output formats and their purposes. This makes it easy to distinguish from sibling tools like get_handwriting or save_snapshot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: exporting a handwriting session into one of four formats, with explicit behavior for blank session_id. It does not explicitly name alternatives or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_connection_infoA
【递纸】Get the PassPaper tablet connection URL + QR code image. Call this FIRST whenever the user mentions '递纸', 'passpaper', '手写板', '平板连接', '画布', '地址', '二维码', '扫码', '我要用递纸', '打开递纸', '连接平板', '连平板'. The pairing is persistent — the user can bookmark the URL.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses that pairing is persistent and the URL can be bookmarked, which helps set expectations. However, it doesn't describe the exact output format or whether the QR code/URL expire, so there is still a moderate gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core purpose. The long trigger-phrase list is useful but somewhat repetitive; however, it is directly actionable for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with no output schema, the description provides a solid context: when to call it and what to expect in terms of persistent pairing. It stops short of detailing the response fields or security considerations, but the overall guidance is sufficient for straightforward invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description naturally cannot add parameter detail. The baseline for zero-parameter tools is 4, and the description adequately explains what to do with the connection info, which is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: getting the PassPaper tablet connection URL and QR code image. It uses specific verbs and resources, and the trigger phrase list distinguishes it from sibling tools that deal with handwriting or session data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to call this FIRST when the user mentions specific phrases and provides a list of trigger examples. It also conveys that it is the initial connection step, not a handwriting or session operation, which helps an agent choose it over siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_handwritingA
Read the user's CURRENT handwriting from the tablet. Returns a PNG image. Only call this AFTER the user has written something and asks you to look. Triggers: '看看我写的', '看我写的', 'look at my writing', '帮我检查这个推导', '你看一下'. Do NOT call this for initial setup — use get_connection_info first.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It states this is a read operation, returns a PNG, and has a precondition (user has already written something). It does not describe failure behavior if called prematurely, but the explicit 'only call after' warning makes the main risk visible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then gives return type, precondition, triggers, and an exclusion in compact form. Every sentence adds useful selection or invocation guidance without unnecessary filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with no output schema, the description adequately covers what the tool does, what it returns, and when it should be called. It could be slightly more complete by contrasting with recognize_handwriting, but the essential invocation context is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema has no properties, so there is nothing for the description to clarify. The baseline for zero-parameter tools is 4, and the description appropriately says nothing misleading about inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Read the user's CURRENT handwriting from the tablet') and the return type (PNG image). It is specific about the resource and timing, but it does not explicitly distinguish this from the sibling recognize_handwriting, so full differentiation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use conditions ('Only call this AFTER the user has written something and asks you to look'), concrete trigger phrases, and a clear when-not-to-use instruction with the alternative named ('Do NOT call this for initial setup — use get_connection_info first'). This is strong guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_handwriting_statusA
【递纸】Check tablet status: stroke count, revision, connected tablets, new-content flag. Does NOT render an image. Lightweight. Call when user asks '有更新吗', '有没有新内容'.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It discloses non-rendering behavior, lightweight operation, and the specific status fields checked. It doesn't discuss side effects or return format, but 'Check' implies a read-only operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with the purpose and key constraints front-loaded before usage triggers. Every fragment ('Lightweight', 'Does NOT render an image') adds decision-relevant information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only status tool, the description covers what it returns (status fields), what it avoids (rendering), and when to invoke it. No output schema exists, but listing the status fields is sufficient guidance for correct usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the schema is vacuously 100% covered. No parameter-specific description is needed, and the baseline for zero-parameter tools is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Check') and resource ('tablet status') and enumerates the exact status fields: stroke count, revision, connected tablets, new-content flag. It also explicitly distinguishes itself from image-rendering tools with 'Does NOT render an image.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit trigger phrases '有更新吗' and '有没有新内容' for when to call. The negative behavior 'Does NOT render an image' and 'Lightweight' help an agent choose it over image-producing alternatives, though no sibling tool is named directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sessionsA
【递纸】列出本地保存的手写会话(按时间倒序)。每个会话是一份可随项目 Git 提交、可回放、可导出的文本记录。
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral disclosure burden. It does add useful context: sessions are local, reverse-chronologically ordered, and are text records that can be Git-committed, replayed, and exported. However, it does not mention side effects (or their absence), permissions, or output behavior, leaving part of the behavioral profile undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loads the core action and resource. The second sentence adds useful context about what sessions are. The unexplained '【递纸】' prefix is a minor distraction, but the overall structure is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with no parameters, so the description is mostly sufficient for invocation. However, there is no output schema, and the description does not clarify what fields or structure the returned session list will have. It hints at the nature of sessions but not the actual response format, leaving a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema already covers this fully. The description does not need to explain parameter semantics. The baseline of 4 is appropriate because there is nothing missing for an agent to invoke the tool correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: '列出本地保存的手写会话' (list locally saved handwriting sessions), with an additional ordering detail (reverse chronological). This clearly distinguishes the tool from siblings like start_session, export_session, and get_handwriting, which concern creation, export, and individual retrieval rather than listing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage context is implied: use this tool when you need to see locally saved handwriting sessions. However, the description does not provide explicit guidance about when not to use it or how it compares to related tools such as export_session or get_handwriting. There are no exclusions or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recognize_handwritingA
【递纸】对手写画布做结构化识别(若已配置本地 VLM/PaddleOCR-VL/GLM-OCR 则输出中文文本与 LaTeX;否则回退为让 Agent 直接看图)。同时把识别结果记入当前会话,便于回溯。
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that behavior depends on local VLM/OCR configuration, that it may fall back to Agent image inspection, and that results are recorded in the current session for traceability. It does not cover all edge-case behaviors but provides meaningful transparency beyond the bare tool name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core purpose, then covers fallback and side effects in one dense sentence. However, the leading '【递纸】' is unexplained jargon that could confuse an AI agent, and the single-sentence structure packs several ideas together.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with no output schema, the description is reasonably complete: it states what the tool produces, when it falls back, and that it persists the result to the session. It could be improved by clarifying prerequisites like whether a handwriting canvas must already exist and what the structured result format looks like, but those are not critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema description coverage is 100%, so there are no parameter semantics to document. The baseline of 4 applies, and the description appropriately does not try to invent parameter information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action ('做结构化识别' on the handwriting canvas) and specifies the expected outputs (Chinese text and LaTeX) with a fallback to letting the Agent view the image. This distinguishes it from siblings like get_handwriting, which presumably retrieves the raw canvas, and get_handwriting_status, which checks status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the conditional behavior: use configured local VLM/OCR for structured output, otherwise fall back to Agent direct image viewing. It implies when this tool is appropriate but does not explicitly mention exclusions or directly name sibling alternatives, leaving some inference to the user.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_snapshotA
【递纸】Save the current handwriting as a PNG file on disk and return its path. Use this when you cannot receive images through MCP directly (e.g. some Codex setups) — then read the file instead.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that the tool writes a PNG file to disk and returns a path, but it does not mention overwrite behavior, where the file is stored, or whether an active session is required.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, with the core operation front-loaded and the usage scenario following immediately. Every part adds useful information, with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with no output schema, the description covers the main operation, the return value, and the practical use case. Minor gaps around file location and system prerequisites are acceptable at this level of simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so there is no schema gap to compensate for; this earns the baseline 4. The description adds only relevant context by referring to 'current handwriting'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: saving the current handwriting as a PNG file on disk and returning its path. This is specific, uses a clear verb, and is easily distinguished from sibling tools like get_handwriting or get_connection_info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use this tool: when images cannot be received through MCP directly, telling the agent to read the file instead. It does not name a specific sibling alternative, but the fallback scenario is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_sessionA
【递纸】开始一个新的手写会话(之前的会话会被保留,可随时导出)。
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It does disclose an important behavioral fact: previous sessions are retained and can be exported. However, it does not say what happens to the current active canvas or whether a new session identifier is returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact sentence with no filler. The core action is front-loaded, and the parenthetical adds the most relevant behavioral detail without unnecessary length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with no output schema, the description provides the key context an agent needs: starting a new session and reassurance that previous work is preserved. It leaves minor ambiguity about the current canvas state, but this is a low-complexity tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and schema coverage is 100%, so the description is not required to explain inputs. The baseline of 4 applies because the empty schema fully documents the invocation surface.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'start a new handwriting session.' The parenthetical that previous sessions are preserved and exportable makes its behavior distinct from siblings like clear_canvas and export_session, so an agent can identify the right tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this tool versus alternatives. The preservation remark hints at a non-destructive use case, but it does not name when to prefer start_session over clear_canvas, save_snapshot, or list_sessions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v1.0.0- First observed
clear_canvas - First observed
export_session - First observed
get_connection_info - First observed
get_handwriting - First observed
get_handwriting_status - First observed
list_sessions - First observed
recognize_handwriting - First observed
save_snapshot - First observed
start_session
TDQS
Scored across 9 tools
Most tools target clearly distinct actions: connection, canvas clearing, status, sessions, and recognition. The main potential confusion is between get_handwriting and save_snapshot, since both capture the current canvas, but their descriptions clarify the different output modes. get_handwriting_status and get_connection_info also overlap slightly, but one is lightweight status while the other is setup-oriented.
All tool names follow a consistent snake_case verb_noun pattern: get_handwriting, clear_canvas, save_snapshot, list_sessions, start_session, export_session, recognize_handwriting. There are no style mixes or vague one-word names, making the toolset predictable for an agent.
Nine tools is well within the ideal range and each tool fills a distinct role in the handwriting tablet workflow. The count feels intentional: connection, reading, clearing, status, snapshotting, session management, export, and recognition are all represented without redundancy.
The core handwriting lifecycle is well covered: connect, write, read, clear, save, recognize, start session, list sessions, and export. Minor gaps exist around session lifecycle, such as no explicit session deletion or loading a previous session back onto the canvas, but these are workable via export and list operations.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
- PenlogOAuthapp.penlog
Handwritten iPad journal your AI can read and write tasks back to, over MCP.
Real-time collaborative whiteboard — AI agents and humans edit the same board live over MCP.
MCP-native notes and memory for ChatGPT, Claude, and other AI tools.
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to collaboratively draw and annotate Excalidraw diagrams in real-time via MCP tools, synced to a browser canvas.6Apache 2.0
- AlicenseAqualityCmaintenanceMCP server that connects AI assistants to your reMarkable tablet, enabling reading, searching, and traversing handwritten and typed notes via OCR.102MIT
- AlicenseAqualityCmaintenanceAn MCP server that gives Claude direct access to your reMarkable tablet's notebooks, enabling document search, PDF rendering, handwriting transcription, and diagram conversion, all locally without API keys.63MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with Ratta Supernote e-ink tablets over Wi-Fi, allowing live screen capture, reading and rendering of handwriting notes, and file upload.331MIT