# @deeploop-ai/modao-cli

> 墨刀（modao.cc）离线包 CLI 与 MCP 服务器

Latest version **0.1.1** (published 2026-08-31) · MIT license · 0 weekly downloads

## Install

```sh
npm install @deeploop-ai/modao-cli
pnpm add @deeploop-ai/modao-cli
yarn add @deeploop-ai/modao-cli
bun add @deeploop-ai/modao-cli
```

Provides the command `modao`.

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.1.1 |
| Published | 2026-08-31 |
| First published | 2026-08-31 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Node | >=18 |
| Dependencies | 6 |
| Unpacked size | 227.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | deeploop-ai |
| Maintainers | qlinhz |
| Keywords | modao, modao-cli, mockingbot, mcp, model-context-protocol, design, prototype, 墨刀 |

## Links

- npm: https://www.npmjs.com/package/@deeploop-ai/modao-cli
- Repository: https://github.com/deeploop-ai/modao-cli
- Homepage: https://github.com/deeploop-ai/modao-cli#readme
- Issues: https://github.com/deeploop-ai/modao-cli/issues
- npm.io page: https://npm.io/package/@deeploop-ai/modao-cli

## Dependencies (6)

- [cac](https://npm.io/package/cac.md) ^6.7.14
- [zod](https://npm.io/package/zod.md) ^3.25.0
- [pako](https://npm.io/package/pako.md) ^2.1.0
- [yaml](https://npm.io/package/yaml.md) ^2.8.0
- [fflate](https://npm.io/package/fflate.md) ^0.8.3
- [@modelcontextprotocol/sdk](https://npm.io/package/@modelcontextprotocol/sdk.md) ^1.17.0

## Alternatives

- [pagerjs](https://npm.io/package/pagerjs.md) — 60 weekly downloads
- [whistle.savefor-mock](https://npm.io/package/whistle.savefor-mock.md) — 4 weekly downloads
- [@volter/twin-ai-gateway](https://npm.io/package/@volter/twin-ai-gateway.md) — 0 weekly downloads
- [telegram-bot-test-server](https://npm.io/package/telegram-bot-test-server.md) — 0 weekly downloads
- [@newmo/eslint-plugin-graphql-fake](https://npm.io/package/@newmo/eslint-plugin-graphql-fake.md) — 0 weekly downloads

## Recent versions

- 0.1.1 (latest) — 2026-08-31
- 0.1.0 — 2026-08-31

## README

# Modao CLI

墨刀（MockingBot）离线包 CLI 与 MCP 服务器：在终端读取、浏览、检索墨刀设计资产，也可作为 stdio MCP 服务供 Claude Code、Cursor 等客户端调用——项目 → 画布 → 页面 → 元素树，以及批注与图片资源。

墨刀官方 MCP（modao-proto-mcp）只做 AI 生成 HTML / 导入，**不读取已有设计**。本项目补的是「加载并理解既有设计文件」这个空位，不与官方冲突。

> Modao (MockingBot) offline-package CLI and MCP server: list/search/read projects, pages, element trees, annotations and image assets from exported Modao HTML packages. Complements the official generation-oriented modao-proto-mcp.

## 重要前置说明

**本工具的输入是墨刀的「HTML 离线演示包」，这是付费导出功能**（个人版/团队版付费用户可用，免费版不支持）。获取步骤：

1. 在墨刀网页版（modao.cc）打开目标项目；
2. 使用「导出 → HTML 离线演示包」；
3. 解压导出的压缩包，得到一个项目目录（内含 `extra/`、`uploads7/`、`index.html`）；
4. 用 `--dir` 指向该目录（或其父目录，可放多个项目）。

**分享链接（`modao.cc/app/<hash>`）目前仅支持占位识别与降级指引，不做数据抓取。** 原因：墨刀没有公开可用的读取型 API（历史 OAuth2 API 已被官方废弃且本就不含页面数据），分享页的设计数据由前端经未公开 XHR 接口加载，属非公开契约、随时可变更。把分享链接传给 `--url`（向后兼容也可传给 `--dir`）时，`list` / `list_projects` 中会出现一个 `status: unsupported` 的占位项目并附降级说明；对其做任何数据访问都会返回上述导出指引。

## 安装

需要 Node.js ≥ 18。

```bash
npm install -g @deeploop-ai/modao-cli
```

也可不安装、用 `npx`：

```bash
npx @deeploop-ai/modao-cli --dir <离线包目录或其父目录>
```

## 命令

全局选项：`--dir <path>`、`--url <url>`（均可重复）、`--json`（结构化输出）。

| 命令 | 说明 | 示例 |
| --- | --- | --- |
| `mcp` | 以 stdio 启动 MCP 服务器（可裸启，数据源由工具调用参数指定） | `modao mcp` / `modao mcp --dir D:/design/modao-exports` |
| `list [project]` | 无参列出项目；带 project id 列出页面 | `modao list --dir ./pkgs` / `modao list <project> --dir ./pkgs --json` |
| `dsl <project> <page>` | 输出页面裁剪 DSL（`--format yaml\|json`、`--depth n`） | `modao dsl <project> <page> --dir ./pkgs --format yaml` |
| `search <query>` | 全文检索（`--project`、`--limit`） | `modao search 首页 --dir ./pkgs --json` |
| `images <project> <page>` | 页面元素级图片清单（含缓存绝对路径） | `modao images <project> <page> --dir ./pkgs` |
| `menu <project>` | 提取播放器菜单树：画布顺序、分组与叶子画布 id（含 flpk 解析缺失的画布） | `modao menu <project> --url http://intranet/pkg/` |
| `snapshot <project> <page>` | 整页长图 PNG（可选 `--out`、`--zoom 1~4`）；远程目录源同时打印预览 URL | `modao snapshot <project> <page> --dir ./pkgs` |
| `snapshot-canvas <project> <canvas>` | 画布总览长图 PNG（该画布全部页面缩略图+页名；可选 `--out`、`--zoom 1~4` 默认 2、`--clip x,y,w,h` 裁剪、`--split` 分片输出） | `modao snapshot-canvas <project> <canvas> --url http://intranet/pkg/ --zoom 3` |
| `pull [url...]` | 预拉/刷新远程包缓存 | `modao pull --url http://intranet/pkg/` / `modao pull http://intranet/pkg.zip --url http://intranet/pkg/` |

### 默认命令

不带子命令时等同 `mcp`，兼容旧的直挂用法：

```bash
modao --dir D:/design/modao-exports
# 等同于
modao mcp --dir D:/design/modao-exports
```

`--dir` 可重复；值为分享链接 URL 时注册为占位项目。也可用 `--url` 指向远程离线包（内网静态目录或 zip）或分享链接：

```bash
modao list --dir D:/design/mdao-exports --url "https://modao.cc/app/<40位hash>"
modao mcp --url "http://192.168.12.67:18080/docs/6.2.6-pkg/"
modao mcp --url "http://192.168.12.67:18080/exports/pkg.zip"
```

`modao mcp`（不带 `--dir`/`--url`、也无相关环境变量）同样可以启动：此时没有默认数据源，每次工具调用需以 `dir` / `url` 入参指定（见「MCP 客户端配置」）。

## MCP 客户端配置

推荐裸启：客户端配置只写 `modao mcp`，数据源由每次工具调用的 `dir` / `url` 入参指定（Agent 无需改配置即可切换多个项目/内网包）；`--dir`/`--url` 与环境变量配置的数据源作为未传参时的默认值。

Claude Desktop（`claude_desktop_config.json`）/ Cursor / Kimi Code：

```json
{
  "mcpServers": {
    "modao": {
      "command": "modao",
      "args": ["mcp"]
    }
  }
}
```

未全局安装时可用 npx：

```json
{
  "mcpServers": {
    "modao": {
      "command": "npx",
      "args": ["-y", "@deeploop-ai/modao-cli", "mcp"]
    }
  }
}
```

Claude Code：

```bash
claude mcp add modao -- modao mcp
```

也可在启动参数里固定默认数据源（向后兼容，工具调用未传参时使用）：

```json
{
  "mcpServers": {
    "modao": {
      "command": "modao",
      "args": ["mcp", "--dir", "D:/design/modao-exports"]
    }
  }
}
```

### MCP 工具数据源入参

每个工具都接受可选的 `dir` / `url` 入参（单值或数组均可，语义同 CLI 的 `--dir`/`--url`）：

- 传了 `dir` / `url`：以调用参数为准（不与默认源合并），相同组合的结果在服务内缓存复用；
- 都不传：使用服务器启动配置（`--dir`/`--url` 或 `MODO_DATA_DIR`/`MODO_DATA_URL`）的默认数据源；
- 两者都未配置时调用会返回指引错误，提示传 `dir` 或 `url`。

### MCP 工具列表

| Tool | 说明 |
| --- | --- |
| `list_projects` | 列出所有已识别项目（id、名称、来源、更新时间；分享链接显示为占位） |
| `list_pages` | 列出项目页面（id、名称、所属画布——区分用户画布/动态组件画布、批注数） |
| `get_page_dsl` | 页面裁剪 DSL（元素类型/名称/位置尺寸/文本/层级），yaml/json 双格式，`depth` 截断 |
| `get_element_detail` | 单个元素完整属性（含 DSL 裁掉的 zIndex、原始字段等） |
| `get_annotations` | 页面批注（富文本说明） |
| `search_assets` | 跨项目全文检索：项目名/页面名/元素名/文本内容，返回定位路径与片段 |
| `get_page_image` | 页面元素级图片清单（复制到缓存目录，返回绝对路径；不做整页合成渲染） |
| `get_page_snapshot` | 整页长图 PNG：传 `page_id` 截单页（原尺寸）；传 `canvas_id` 截画布总览长图（全部页面缩略图+页名一图纵览）；`canvas_id` + `split: true` 追加分片输出（总览+按空白沟切的 N 张可读宽度小图，返回 `tiles` 清单，每片带墙内 clip 坐标，适合逐片读小字）。返回磁盘绝对路径（及远程目录源的预览 URL），Agent 自行读取该图；需要 Playwright |
| `refresh_projects` | 刷新数据源：远程离线包重新拉取，本地目录重新扫描（范围同上：调用参数优先，未传则默认源） |

以上所有工具均接受可选 `dir` / `url` 入参指定数据源（见「MCP 工具数据源入参」）。

典型用法流程：**先检索定位，再精读**——用 `search_assets` / `list_pages` 找到目标页面，再用 `get_page_dsl` 拉裁剪后的 DSL；超大页面先用 `depth` 看骨架，按截断提示用 `get_element_detail` 精读子树。**看稿**用 `get_page_snapshot`（读取返回的 `path` 直接看整页长图），**读结构与文案**用 `get_page_dsl`。

## 环境变量

| 环境变量 | 说明 |
| --- | --- |
| `MODO_DATA_DIR` | 数据源（等价 `--dir`，逗号分隔多个值；CLI 有值时不生效）。MCP 模式下作为工具未传 `dir`/`url` 入参时的默认数据源 |
| `MODO_DATA_URL` | 远程数据源（等价 `--url`，逗号分隔多个值；CLI 有值时不生效）。MCP 模式下作为工具未传 `dir`/`url` 入参时的默认数据源 |
| `MODO_CACHE_DIR` | 缓存目录（图片、远程数据），默认 Windows 为 `%LOCALAPPDATA%\modao-mcp`，macOS/Linux 为 `~/.cache/modao-mcp` |

## 数据源形态

支持三种输入（CLI 用 `--dir`/`--url`，MCP 工具调用用 `dir`/`url` 入参，形态一致）：

- **本地目录（一等）**：`dir` 指向已解压的离线包根目录，或其父目录（扫描含 `extra/data.0.js` 的子目录）。
- **远程离线包**：`url` 指向内网静态服务器上的解压目录，或 zip 下载地址；会下载到本地缓存后再解析。
- **分享链接**：`url`（或向后兼容写在 `dir`/`--dir`）识别为占位项目，不抓取数据，仅返回导出离线包的降级指引。

远程数据缓存于 `MODO_CACHE_DIR`（或系统默认缓存目录）下的 `remote/`。MCP 启动时会自动检查默认远程源的更新，工具调用首次使用某个 `url` 数据源时同样做一次检查（目录形态对比 `updated_at`，zip 对比 ETag/Last-Modified）；运行期间可调用 `refresh_projects` 工具重新拉取，或在 CLI 使用 `modao pull` 检查并在有更新时拉取。

## 图片缓存

`images` 命令与 MCP 工具 `get_page_image` 不做整页合成渲染，只收集页面元素级图片：从包内 `uploads7/images/` 按需复制到缓存目录，返回绝对路径。远程目录形态若本地未带图片，会按 `uploads7/images/<file>` 回源拉取并落盘；失败则跳过该图片。缓存根目录由 `MODO_CACHE_DIR` 控制。

## 整页截图（snapshot）

`snapshot` 命令与 MCP 工具 `get_page_snapshot` 用 Playwright 打开官方离线 HTML 播放器，按页面画板实际宽度截取整页长图 PNG：

- 默认落盘 `<缓存目录>/snapshots/<project>/<画布序>-<页序>-<页面名>.png`（画布总览为 `overview-<画布序>-<画布名>.png`），序号 1 起零填充两位，目录按名排序即设计稿顺序；页面不在模型中（远程源宽容放行）时回退用页面 id。CLI 可用 `--out` 覆盖；返回值含 `path`、`width`、`height`。
- 数据源为远程**目录**形态（`--url http://...`）时一并返回 `previewUrl`（包根地址，可直接打开播放器）；zip 与本地 `--dir` 源只返回 `path`（本地源截图期间会临时起一个仅绑定 127.0.0.1 的静态服务，进程退出即关闭）。
- **Playwright 为可选依赖**：未安装时报错并提示安装，不做静默降级；托管 chromium 未下载时会自动回退本机 Chrome/Edge（`channel` 方式），无需 150MB 浏览器下载：

```bash
npm install playwright          # 未安装时
npx playwright install chromium # 可选：下载托管浏览器（无系统 Chrome/Edge 时）
```

- 跳页采用官方播放器深链 `?view_mode=device&canvasId=<页面id>` 直达目标页，并按画板自然尺寸（非模拟器缩放尺寸）输出 PNG。
- **画布总览**：`snapshot-canvas` 命令（或 `get_page_snapshot` 传 `canvas_id`，来自 `list_pages` 的 `canvasId`，或 `menu` 命令输出的叶子画布 id）切换到播放器总览模式，一面长图截下该画布全部页面缩略图与页名——适合一图纵览多页结构。默认 2 倍像素输出，`--zoom 1~4` 调节；`--clip x,y,w,h`（相对墙左上 CSS 像素）可只截批注/文档区域。页面级 `snapshot --zoom` 同理。
- **分片输出（读小字推荐）**：整墙长图送入读图模型会被降采样，批注小字必然不可读。`--split` 在同一次渲染内追加输出：总览 1 张（看结构）+ 按内容空白沟切的 N 张可读宽度分片（逐片读文字，无需手工估算 clip 坐标），并写 `tiles.json` 清单——每片带墙内 CSS 像素 `clip` 坐标与切法（gutter=刀口在空白沟，uniform=等宽退化切），可溯源、可定点复查。`--split auto` 按空白沟自适应片数（默认片宽 520 CSS px，`--band` 调节）；`--split <n>` 强制片数；墙内容过密无沟可切时退化为等宽切并留 `--overlap`（默认 60 CSS px）；沟内有内容贯穿（表格行线、白卡连续区——切开会把一张表/一张卡劈到两片）时不下刀，整块内容并入同一条分片（最宽 band+200 CSS px，超宽才等宽切）；墙缘滚动条等过窄伪内容不参与切线。`--out` 此时为输出目录（默认 `snapshots/<project>/split-<画布序>-<画布名>/`）；`--skip-existing` 在清单与文件齐全时直接复用不重截。与 `--clip` 互斥。
- 画布 id 校验规则：id 在解析结果中时直接使用；不在时，**远程目录源**会放行并由播放器侧选中态校验（覆盖菜单中存在但解析缺失的画布），**本地源**则严格报错并列出可用画布。

## 典型工作流：从设计稿到需求文档（Agent 自主完成）

```bash
modao list --url http://intranet/pkg/                    # 1. 找到项目 id
modao menu <project> --url http://intranet/pkg/          # 2. 菜单顺序 + 全部画布 id（含解析缺失的）
modao snapshot-canvas <project> <canvasId> \
  --url http://intranet/pkg/ --zoom 3 \
  --split auto --out shots/<canvasId>/                   # 3. 总览 + 按空白沟分片 + tiles.json
# Agent 识读:先读总览看结构,再按 tiles.json 顺序逐片读文字;
# 个别没读清的行用 tiles.json 的 clip 坐标 --clip 定点复查
```

全程只需要 CLI 返回的信息：菜单给出顺序与 id，snapshot 返回 PNG 绝对路径与尺寸（分片模式附每片墙内坐标），无需了解墨刀文件结构，也无需人工估算裁剪坐标。

## 数据格式说明

离线包内 `extra/data.0.js` 为项目元信息，`extra/data.1.js` 为设计数据，核心是 `window.hzv5.flpk` 操作码序列：

- **v1（旧版）**：明文操作码数组；
- **v2（新版）**：gzip+base64 压缩块 + 明文增量更新。

解析器做操作码回放（`I` 定义元素 / `A` 更新属性 / `B@ref-danli` 动态组件画布 / `@@T` 外部引用跳过），用 `rRBPK` 索引区分用户画布与动态组件画布。flpk 是墨刀内部格式、非公开契约，解析器采用**防御式解析**：无法识别的操作码跳过并计数，不会崩溃。

本项目的 flpk 解析逻辑移植自 [modao-exporter](https://github.com/zjysyxx/modao-exporter)（MIT 许可证）的 `src/parser/`，特此致谢。本项目同样以 MIT 许可证发布。

## 开发

```bash
npm install
npm run build   # tsc → dist/
npm test        # vitest
npm run dev     # tsx 直接跑 src/index.ts（需 -- --dir <path> 或子命令）
```

项目结构：

```
modao-cli/
├── src/
│   ├── index.ts              # 入口：分发到 cli
│   ├── cli.ts                # cac 命令定义与分发
│   ├── config.ts             # configFromOptions（CLI 选项 + 环境变量）
│   ├── bootstrap.ts          # createSource / checkRemoteUpdates
│   ├── cli-output.ts         # 人类可读格式化
│   ├── mcp-command.ts        # mcp 子命令：stdio 启动│   ├── commands/             # list / dsl / search / images / pull
│   ├── model/                # Project/Canvas/Page/Element/Annotation/Asset 统一模型
│   ├── flpk/
│   │   ├── decode.ts         # flpk v1/v2 解包（gzip+base64 → 操作码行）
│   │   └── replay.ts         # 操作码回放 → 统一文档模型
│   ├── sources/
│   │   ├── source.ts         # Source 接口
│   │   ├── offline-package.ts# 本地离线包目录（惰性解析）
│   │   ├── remote-package.ts # 远程离线包目录 / zip 拉取与缓存
│   │   ├── share-link.ts     # 分享链接占位（降级指引，不抓取）
│   │   └── combined.ts       # 多数据源组合
│   ├── services/
│   │   ├── dsl.ts            # 文档模型 → 裁剪 DSL（json/yaml、depth 截断）
│   │   ├── index.ts          # 内存检索索引与打分
│   │   ├── assets.ts         # uploads7/images 资源读取与缓存目录落盘
│   │   └── pages.ts          # 页面查找辅助
│   └── mcp/
│       ├── server.ts         # McpServer 装配
│       ├── source-manager.ts # 工具调用 dir/url 入参 → 数据源解析与缓存
│       └── tools.ts          # tool 注册
└── test/                     # vitest + 手工构造的微型离线包 fixtures
```

## License

MIT © deeploop-ai

---
_Source: https://npm.io/package/@deeploop-ai/modao-cli · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
