递纸 PassPaper

CI OpenSSF Scorecard M8ven Score License: MIT Python 3.10+ Platform SonarCloud codecov

中文 | English


中文

在平板上手写公式/草图,AI 通过 MCP 工具实时读取。 支持 Claude CodeCodex CLI

状态:v1.0.0 早期版本。核心功能已实现并通过代码级校验(py_compile / import / 识别解析),尚未在大规模真机环境验证。欢迎在 GitHub Issues 反馈问题与使用场景。

[平板 Chrome]                    [电脑]
 手写 canvas ──WebSocket──▶ passpaper daemon (常驻)
                              │  笔画落笔即渲染到内存画布
   Claude Code / Codex ◀─MCP stdio─ mcp_shim
                              └──── localhost HTTP ────┘

功能

  1. 中文潦草 / 公式手写识别(本地、隐私) — 配置本地 VLM(PASSPAPER_RECOGNIZER_ENDPOINT,如 ollama / llama.cpp / vLLM 的 OpenAI 兼容端点)后,图片在交给 Agent 前会先转成结构化文本 / LaTeX。未配置时回退到「Agent 直接看图」。详见 docs/RECOGNITION.md
  2. 低延迟跨设备接力 — 平板落笔即增量渲染到内存画布,取图 = 读缓存(实测约 25ms)。WebSocket 断线时笔画本地缓存,重连后自动批量补发。
  3. 手写会话可随项目回溯 — 每一笔落盘为 JSONL(~/.passpaper/sessions/)。可导出 Markdown / Excalidraw,在 Excalidraw / tldraw 中回放编辑。
  4. 通用 MCP + 本地优先 — MCP shim 同时支持 Claude CodeCodex;数据只走本机和局域网,无账号、无云、无出站调用。设计受多个开源项目启发,逐条署名见 REFERENCES.md

设计架构:daemon + shim 双层

问题 解法
AI 客户端里 MCP 加载慢/超时 shim 纯标准库,握手 <100ms;重活全在 daemon
连接不稳定 daemon 常驻,独立于客户端生命周期;日志写文件不写管道;平板断线笔画本地缓存、重连自动补发
传输慢 笔画到达即增量渲染,取图 = 读缓存(实测约 25ms);图片自动裁切、限制 1568px、调色板 PNG
每次用每次扫码 持久配对码:平板上存书签,点开就写,passpaper rotate-token 可轮换
客户端重启后僵尸进程占端口 shim 在 stdin 关闭时立即退出;daemon 用 PID 文件管理,优雅关机先存盘
想用 Codex 同一 shim,passpaper setup 同时注册 Claude Code + Codex;save_snapshot 提供文件兜底

快速开始(Windows)

  1. 双击 start.bat(自动检测 Python、装依赖、注册、启动 daemon)
  2. 打开 Claude Code 或 Codex,说 "我要用递纸"
  3. 在平板上打开它给你的链接(Chrome),存成书签
  4. 写字,然后对 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 工具

工具 用途
get_connection_info 平板链接 + 二维码(AI 首次必调)
get_handwriting 当前手写内容(PNG,自动裁切/缩放)
get_handwriting_status 笔画数/修订号/有无新内容(轻量)
clear_canvas 清空画布
save_snapshot 存 PNG 到磁盘返回路径(无法接收 MCP 图片的客户端走这里)
list_sessions 列出已录制手写会话(笔画数/时间)
start_session 开新会话,旧会话保留可回溯
export_session 导出会话为 md / jsonl / json / excalidraw,可随项目 Git 提交
recognize_handwriting 调用本地 VLM 识别中文/公式(未配置则回退到 Agent 视觉)

深入阅读

依赖

Python ≥ 3.10,websockets Pillow qrcode(shim 本身零依赖,纯标准库)。

测试

python scripts/e2e_test.py
# 26 项检查:shim 冷握手速度、daemon 自动拉起、平板 WS、取图延迟、
# 6 万点渲染性能、离线批量补发、优雅关机等

设计要点

路线图

已发布(v1.0.0) - [x] 常驻 daemon + MCP shim - [x] 持久配对 / 离线补发 / 增量渲染(~25ms 取图、MCP 握手 <100ms) - [x] 手写会话录制 + 多格式导出(md / jsonl / json / excalidraw) - [x] 可插拔中文 / 公式识别管线(本地 VLM,无模型时回退)

进行中 / 下一步 - [ ] 真机验收(平板 + Claude Code / Codex 实跑) - [ ] PyPI 发布 + MCP 市场提交(pip install passpaper-mcp) - [ ] Cloudflare Tunnel 模式(户外 / 跨网络) - [ ] 笔画级语义擦除 - [ ] 系统托盘 App 形态 - [ ] 更多本地识别后端(PaddleOCR-VL / GLM-OCR 开箱集成)

故障排除

贡献

欢迎 Issue / PR。开发环境、测试与规则见 CONTRIBUTING.md。安全漏洞请私下报告,见 SECURITY.md

参考与灵感来源

递纸的设计受到多个开源项目的启发,逐条署名见 REFERENCES.md

License

MIT — Copyright (c) 2026 B.Han.


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

  1. 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.
  2. 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.
  3. 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.
  4. 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 (passpaper rotate-token)
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 — passpaper setup registers both Claude Code and Codex; save_snapshot provides a file-based fallback

Quick start (Windows)

  1. Double-click start.bat (auto-detects Python, installs dependencies, registers, starts the daemon)
  2. Open Claude Code or Codex and say "I want to use PassPaper"
  3. Open the link it gives you on your tablet (Chrome) and save it as a bookmark
  4. 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 leaks

Optional autostart at boot: python src/passpaper/cli.py setup --autostart

MCP tools

Tool Purpose
get_connection_info Tablet link + QR code (the AI must call this first)
get_handwriting Current handwriting content (PNG, auto-cropped / scaled)
get_handwriting_status Stroke count / revision / whether new content exists (lightweight)
clear_canvas Clear the canvas
save_snapshot Save PNG to disk and return the path (for clients that cannot receive MCP images)
list_sessions List recorded handwriting sessions (stroke count / time)
start_session Start a new session; old sessions are kept for traceability
export_session Export a session as md / jsonl / json / excalidraw, committable with the project's Git
recognize_handwriting Call the local VLM to recognize Chinese / formulas (falls back to agent vision if unconfigured)

Further reading

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

Roadmap

Shipped (v1.0.0) - [x] Resident daemon + MCP shim - [x] Persistent pairing / offline re-send / incremental rendering (~25ms capture, MCP handshake <100ms) - [x] Handwriting session recording + multi-format export (md / jsonl / json / excalidraw) - [x] 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

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

Star History Chart

License

MIT — Copyright (c) 2026 B.Han.