moonvy-ai
v1.0.0
Published
Moonvy design extraction MCP server: design-to-code for AI agents (pure API, auto login, self-healing)
Downloads
24
Maintainers
Readme
moonvy-ai
Moonvy 设计稿 → 前端代码的 MCP 服务器。 把 Moonvy 设计协作平台(月维)中的设计文件,以结构化的图层树、样式、设计 Token 和切图资产,直接交付给 AI 编程助手。
纯 TypeScript 实现,不依赖浏览器运行时、不依赖任何外部工具链——只需一个有效期约 180 天的 JWT,所有数据操作直连 Moonvy API,单次调用约 400ms。
特性
- ⚡ 极速:纯 API 架构(无浏览器、无 daemon),缓存命中时单次调用 2-13ms
- 🔑 开箱即用:token 持久化 180 天;
moonvy_login自动打开 Chrome/Edge 引导登录 - 🤖 Agent 原生:结构化输出(
structuredContent)、机器可读错误码、自愈引导(Next: call moonvy_login)、进度通知、取消支持 - 📦 聚合工具:
moonvy_get_design_context一次调用返回 元数据+图层树+Token - 🧭 智能解析:目录 URL 自动解析、Figma 风格/UUID 节点 ID 兼容、5xx 自动重试
- 🔒 安全:输出脱敏、域名校验、工作区黑/白名单、token 文件 0600 权限
快速开始
1. 安装(二选一)
全局安装(推荐,配置最简单):
npm install -g <path/to/moonvy-ai> # 或 npm i -g moonvy-ai(发布后)
# 安装后提供两个全局命令:
moonvy-ai # MCP 服务器(stdio)
moonvy-ai-login # 一键浏览器登录本地开发安装:
git clone <this-repo> moonvy-ai
cd moonvy-ai
npm install
npm run build要求 Node.js >= 20.11。
2. 获取 token(自动或手动,约 180 天有效)
方式 A:全自动(推荐) — 什么都不用做
server 启动后第一次调用工具时,若检测到无 token(或已过期),会自动打开 Chrome/Edge 登录页;你登录后 token 自动捕获并保存到 ~/.moonvy-ai/token.json,原调用自动重试成功。
- 浏览器 profile 持久化:只登录一次;180 天后 token 过期时自动复用已登录会话无感续期
- 无头/CI 环境:设
MOONVY_AUTO_LOGIN=0关闭自动弹窗 - 也可在配置 agent 前先执行
npm run login一次性完成登录
方式 B:手动粘贴 token
在已登录 Moonvy 的浏览器中打开开发者工具(F12)→ Console,执行:
window.app.api.$options.token复制返回的 JWT,然后二选一:
# 通过 MCP 调用 moonvy_set_token 保存(自动持久化),或:
export MOONVY_TOKEN="<你的JWT>" # 环境变量(适合 CI/服务器)配置外部 Agent(教程)
全局安装后,
command直接写"moonvy-ai"(bin 已在 PATH 中);本地安装则写node /absolute/path/to/moonvy-ai/dist/src/server.js。
opencode(全局配置,所有项目生效)
编辑 ~/.config/opencode/opencode.json:
{
"mcp": {
"moonvy": {
"type": "local",
"command": ["moonvy-ai"],
"enabled": true
}
}
}验证:opencode mcp list 应显示 moonvy connected。
Claude Code
claude mcp add --scope user moonvy -- moonvy-ai # 全局(所有项目)
claude mcp list # 验证或编辑 .mcp.json(项目级):
{
"mcpServers": {
"moonvy": {
"command": "moonvy-ai"
}
}
}Cursor
设置 → MCP → 添加新的 MCP Server:
名称:moonvy
类型:command
命令:moonvy-ai通用 JSON-RPC(任何 MCP 客户端 / 自研)
stdio 启动后逐行发送:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"my-client","version":"1.0.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"moonvy_get_design_context","arguments":{"url":"https://moonvy.com/project/<projectId>/<dirId>/<fileId>","maxDepth":99}}}推荐工作流(给 Agent 的自然语言提示)
1. 用 moonvy_sync_project 把 Moonvy 项目同步为本地索引(.moonvy-mcp/catalog.json)
2. 用 moonvy_search_designs 或 moonvy_get_tree_by_name 按名称定位设计稿
3. 用 moonvy_get_design_context 一次获取 元数据+图层树+Token
4. 用 moonvy_download_asset 导出切图/快照(out 必须为绝对路径)
5. 结合 moonvy_restore_design prompt 生成前端代码工具参考(13 个)
| 工具 | 用途 | 关键参数 | 返回结构 |
|---|---|---|---|
| moonvy_get_design | 设计元数据 | url | {items:[{title,frameCount,frames}]} |
| moonvy_list_pages | 项目文件列表 | url, limit, maxPages | {items:[{id,name,type,url,...}]} |
| moonvy_get_design_context ⭐ | 元数据+树+Token 一次拿全 | url, maxDepth | {design, tree:{items}, tokens:{items}} |
| moonvy_get_tree | 图层树(可带样式) | url, frame?, withStyle, maxDepth | {items:[{id,name,type,rect...,children}]} |
| moonvy_list_layers | 扁平图层列表(找节点 ID) | url, frame?, limit | {items:[{id,name,type,x,y,w,h}]} |
| moonvy_get_node_style | 单节点样式 | url, node | {items:[{id,name,bbox,background,color,...}]} |
| moonvy_extract_tokens | 设计 Token | url | {items:[{colors,fontSizes,radii,spacing}]} |
| moonvy_download_asset | 下载切图/快照/图片 | url, node, type?, sliceFormat?, out | {items:[{success,path,size,name,url}]} |
| moonvy_sync_project | 同步项目索引 | projectUrl, workspaceDir, types? | {designCount, sources, ...} |
| moonvy_search_designs | 按名称/别名检索索引 | query, workspaceDir | {matches:[{name,url,score,matchReason}]} |
| moonvy_get_tree_by_name | 按名称取图层树 | name, workspaceDir | {status, tree:{items}} |
| moonvy_set_token | 手动保存 JWT | token | {saved, expiresAt, daysUntilExpiry} |
| moonvy_login | 浏览器引导登录(自愈) | timeoutMs? | {loggedIn, expiresAt, ...} |
⭐
moonvy_get_design_context是设计还原的首选入口:一次调用替代get_design+get_tree+extract_tokens三次往返。 所有设计类工具均接受项目目录 URL(自动解析为第一个设计文件)。
Prompts
moonvy_restore_design— 设计稿 → 前端代码的端到端工作流(推荐栈、切图导出、Token 复用指引)moonvy_handoff— 设计交接单(从 catalog 汇总设计清单与别名映射)
Resources
moonvy://catalog/{workspaceDir}— 工作区设计索引(catalog.json)moonvy://aliases/{workspaceDir}— 代码文件 ↔ 设计稿别名映射
错误码与自愈
所有工具失败时返回 isError: true,错误文本格式:
[CODE] 错误描述 Next: 下一步动作| 错误码 | 含义 | 自愈动作 |
|---|---|---|
| AUTH_REQUIRED | 未配置 token | 调 moonvy_login 或设置 MOONVY_TOKEN |
| AUTH_EXPIRED | token 已过期(约 180 天) | 调 moonvy_login 重新登录 |
| NODE_NOT_FOUND | 节点 ID 无效 | 先用 moonvy_list_layers 获取有效 ID |
| NO_GENOME | URL 是目录而非设计文件 | 用 moonvy_list_pages 找文件 URL |
| BAD_URL | 非 moonvy.com 或格式错误 | 使用合法 URL |
| EMPTY | 数据为空 | 检查项目/设计是否存在 |
| API_ERROR / NETWORK | API 或网络故障(含 5xx,已自动重试 2 次) | 稍后重试 |
架构
AI Agent (opencode / Claude Code / Cursor / 任意 MCP 客户端)
└─ MCP stdio ── tools ×13 · resources ×2 · prompts ×2 · 进度 · 取消 · 结构化错误
└─ src/moonvy-server.ts MCP 服务器工厂
└─ src/moonvy-client.ts 纯 API 客户端(URL 解析/分页/genome 缓存/资产下载)
└─ src/api.ts fetch 层(Bearer 认证 · 超时 · 5xx 退避重试)
└─ src/token-store.ts JWT 持久化(~/.moonvy-ai/token.json · 180 天)
└─ src/browser-login.ts CDP 登录引导(系统 Chrome/Edge · 仅 token 缺失时)src/
├── server.ts # stdio 入口
├── moonvy-server.ts # MCP 服务器工厂(工具/资源/提示词/补全/进度/取消/错误码)
├── moonvy-client.ts # 纯 API 客户端
├── api.ts # fetch 层
├── token-store.ts # token 持久化
├── browser-login.ts # CDP 登录引导
├── genome.ts # genome 解析(纯函数)
├── schemas.ts # outputSchema(zod)
├── utils.ts # 脱敏/JSON 提取/catalog 检索
└── workspace.ts # 工作区校验与 .moonvy-mcp 读写性能(真实项目实测)
| 场景 | 耗时 |
|---|---|
| 首次调用(含元数据 + genome 下载) | 250-450ms |
| 缓存命中(tree / tokens / layers / style) | 2-13ms |
| get_design_context 一次拿全 | ~250ms |
| 资产下载(1.2MB 快照) | ~250-450ms |
开发
npm run build # tsc 编译到 dist/
npm run check # 类型检查(tsc --noEmit)
npm test # 50 个单元/集成测试
npm run login # 一键浏览器登录(token 自动保存)
npm run live-test # 真实 Moonvy 项目端到端实测(需有效 token)环境变量
| 变量 | 说明 | 默认 |
|---|---|---|
| MOONVY_TOKEN | JWT(优先级高于文件) | - |
| MOONVY_TOKEN_FILE | token 存储路径 | ~/.moonvy-ai/token.json |
| MOONVY_AUTO_LOGIN | 无 token/过期时自动打开浏览器登录(0 关闭) | 1(开) |
| MOONVY_CACHE_DIR | genome 缓存目录 | <工具目录>/.genome-cache |
| MOONVY_CACHE_TTL_MS | 缓存有效期 | 300000(5 分钟) |
| MOONVY_WORKSPACE_DIR | 默认工作区(资源列表/补全) | - |
| MOONVY_ALLOWED_WORKSPACES | 工作区白名单(分号或 \| 分隔) | - |
安全设计
- 输出脱敏:JWT / cookie / token / URL query 自动打码
- 输入校验:仅允许
moonvy.com域名;out/workspaceDir强制绝对路径 - 工作区防护:系统目录黑名单 +
MOONVY_ALLOWED_WORKSPACES白名单 - token 文件以
0600权限写入;API 错误信息不含敏感数据
限制
- token 为个人账号凭证(约 180 天有效期,过期需重新登录)
- 依赖 Moonvy 内部 API(
global-api.moonvy.com,无官方 SLA;接口变动时需适配) - 仅支持读取,不支持修改设计
- 未在 macOS/Linux 实测(代码已兼容,欢迎 issue 反馈)
License
MIT
