在平板上手写公式/草图,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 ────┘
PASSPAPER_RECOGNIZER_ENDPOINT,如 ollama / llama.cpp / vLLM 的 OpenAI 兼容端点)后,图片在交给 Agent 前会先转成结构化文本 / LaTeX。未配置时回退到「Agent 直接看图」。详见 docs/RECOGNITION.md。~/.passpaper/sessions/)。可导出 Markdown / Excalidraw,在 Excalidraw / tldraw 中回放编辑。| 问题 | 解法 |
|---|---|
| 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 提供文件兜底 |
start.bat(自动检测 Python、装依赖、注册、启动 daemon)以后每次用:打开书签直接写。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
| 工具 | 用途 |
|---|---|
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 万点渲染性能、离线批量补发、优雅关机等
setup 把 daemon/shim 复制到 ~/.passpaper/(纯 ASCII 路径),客户端配置指向那里——项目在中文路径下也不会踩 spawn 编码坑PASSPAPER_HOME 可改数据目录(测试/便携安装用)已发布(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 开箱集成)
passpaper doctor — 诊断 Python / 依赖 / 运行时包 / MCP 注册 / 配对令牌。~/.passpaper/daemon.log 与 ~/.passpaper/daemon.spawn.log。passpaper stop 后再 passpaper start;或改 PORT(需同步改 canvas)。passpaper url 重新获取链接;公司/校园网可能隔离设备——换手机热点测试。PASSPAPER_RECOGNIZER_ENDPOINT 时走「Agent 直接看图」回退,属正常;配置方法见 docs/RECOGNITION.md。欢迎 Issue / PR。开发环境、测试与规则见 CONTRIBUTING.md。安全漏洞请私下报告,见 SECURITY.md。
递纸的设计受到多个开源项目的启发,逐条署名见 REFERENCES.md。
MIT — Copyright (c) 2026 B.Han.
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 ────┘
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.~/.passpaper/sessions/). Sessions can be exported as Markdown / Excalidraw and replayed or edited in Excalidraw / tldraw.| 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 |
start.bat (auto-detects Python, installs dependencies, registers, starts the daemon)From then on: open the bookmark and just write. If the daemon isn't running, the shim starts it automatically.
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
| 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) |
Python ≥ 3.10, websockets Pillow qrcode (the shim itself has zero dependencies — pure stdlib).
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.
setup copies daemon/shim to ~/.passpaper/ (pure ASCII path); client config points there — no spawn encoding issues even when the project lives under a non-ASCII pathPASSPAPER_HOME changes the data directory (for testing / portable installs)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)
passpaper doctor — diagnostics for Python / dependencies / runtime package / MCP registration / pairing token.~/.passpaper/daemon.log and ~/.passpaper/daemon.spawn.log.passpaper stop then passpaper start; or change PORT (must also update the canvas).passpaper url; corporate / campus networks may isolate devices — try a phone hotspot.PASSPAPER_RECOGNIZER_ENDPOINT configured it falls back to "agent looks at the image directly", which is expected; configuration see docs/RECOGNITION.md.Issues and PRs welcome. Dev environment, tests and rules: see CONTRIBUTING.md. Report security vulnerabilities privately, see SECURITY.md.
PassPaper's design is inspired by several open-source projects, credited one by one in REFERENCES.md.
MIT — Copyright (c) 2026 B.Han.