AI MCP
AI MCP
通过 Model Context Protocol (MCP) 让 Cursor / Claude / VS Code 等助手按需检索唯杰AI可视化平台的组件元数据、开发文档与示例,并校验工程 JSON。
端点
- MCP:
POST/GET https://<host>/mcp(Streamable HTTP,有会话;POST 可用 JSON 响应) - LLMs 索引:
GET https://<host>/llms.txt - 可选发现:
GET https://<host>/.well-known/mcp/server-card.json(实验性)
说明:客户端可能探测 /.well-known/oauth-*;本服务不需要 OAuth,这些 404 可忽略。
内置 AI 问答(编辑器面板)
编辑器右下角 AI 助手走唯杰AI可视化平台进程内的 Agent(/api/vp/ai/*),不再依赖外部 :18080。在 server/vp_config.json(发布包是同目录 vp_config.json)填写:
{
"ai": {
"enabled": true,
"baseURL": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"apiKey": "<your-key>",
"models": ["qwen3.6-plus", "qwen-plus-latest", "qwen3-vl-plus"],
"visionModels": ["qwen3.6-plus", "qwen3-vl-plus"],
"contextWindow": 1000000,
"maxOutput": 8192,
"maxSteps": 12
}
}字段与旧 vjagent.env 的 VJAGENT_LLM_* 一一对应。改完后重启后端,启动时会种子化成平台模型端点(固定名 default,密钥加密入库)。用户也可在 AI 设置里添加自己的 OpenAI 兼容端点。环境变量 VP_AI_BASE_URL / VP_AI_API_KEY / VP_AI_MODEL 可覆盖文件。
模型选谁:自建端点优先于平台
解析顺序是会话已定格的模型 → 用户自建(BYO)端点 → 平台 default 端点 → 配置文件 / 环境变量兜底。也就是说 AI 设置里存过自建端点后,它会压过配置文件里的平台端点;配置文件的 apiKey 只属于 default 这一个端点,不会补给自建端点。
自建端点漏填 Key 时,上游会直接回 unauthorized: You didn't provide an API key,而两个端点又常提供同名模型(都叫 qwen3.6-plus),从模型名上看不出差别。所以:
- AI 设置的「模型端点」列表里,没存密钥的会标 未设 Key,「默认」只标后端真正会选中的那一条;每条都可删除(自建随时可删,平台项限管理员,删掉最后一个模型时端点一并移除)。
- 输入框下方的模型药丸显示的就是本会话实际使用的模型,同名模型会带上端点名区分。
- 会话的模型在首次发言时定格,中途改配置不影响进行中的会话;换端点后请新建会话。
默认关闭。在 vp_config.json 中设置:
{
"mcp": {
"enabled": true,
"dataDir": "./vp_mcp_data",
"cacheDir": "./pb_data/mcp-cache",
"publicURL": "https://your-host",
"allowedOrigins": [],
"allowedHosts": [],
"localValidateRoots": []
}
}环境变量:VP_MCP_ENABLED=true、VP_MCP_DATA_DIR、VP_MCP_CACHE_DIR、VP_MCP_PUBLIC_URL、VP_MCP_LOCAL_VALIDATE_ROOTS(多个目录用系统 PATH 分隔符分隔)。
数据目录
文档与组件 catalog 不打包进二进制。部署物为:
- 单文件 Go 后端
vp_mcp_data/(只读知识库:发布包是扁平目录,manifest.json、catalog.json、docs/、examples/直接在该目录下)pb_data/mcp-cache/(Bleve 索引缓存,可写)
仓库里 pnpm mcp:prepare 仍写入 generations/<digest>/ + current.json(便于本地保留构建历史);打包脚本只把当前代摊平拷贝,避免把几十代打进安装包。
生成 / 更新数据:
pnpm mcp:dump-schema
pnpm mcp:prepare
# 同步 vp_mcp_data 后重启后端(只换文档/catalog 无需重编 Go)Windows 本地开发可用仓库根目录 dev-mcp.bat 菜单:准备数据、启动后端(自动 VP_MCP_ENABLED=true)、启动编辑器/文档站,或一键全开。
可用 Tools
| Tool | 作用 |
|---|---|
search_widgets | BM25 检索组件 / 图层 |
search_documentation | BM25 检索文档章节 |
get_widget_metadata | 取 options 结构化元数据。搭建型组件(scene-3d / map-2d / scada-2d)额外返回 childPieces(内部元素 type),再对每个 piece type 查询才是图层/三维选项 |
get_doc | 取文档:传 type 取组件文档小节(scene-3d/map-2d/scada-2d 绑到子系统总览;scene3d-shape 等绑到元素手册),或传 docId 取文档页。不要用 vjmap-docs 猜 VP pieces 选项名 |
list_examples / get_example | 白名单示例 |
validate_project | 校验工程 JSON(内联对象) |
validate_project_file | 按服务器本地路径校验工程 JSON(需配置 localValidateRoots 才出现) |
Cursor 配置
优先用 Cursor 原生 Remote URL(不必 mcp-remote):
{
"mcpServers": {
"vjappvisual": {
"url": "http://127.0.0.1:8090/mcp"
}
}
}若必须走 stdio 代理(与现有 vjmap MCP 一致):
{
"mcpServers": {
"vjappvisual": {
"command": "cmd",
"args": ["/c", "npx", "-y", "mcp-remote", "http://127.0.0.1:8090/mcp"],
"env": {
"HTTP_PROXY": "",
"HTTPS_PROXY": "",
"ALL_PROXY": "",
"NO_PROXY": "*"
}
}
}
}配置后需重启后端(改 MCP 数据或二进制后同样重启),再在 Cursor MCP 面板点刷新。
与 generate-vp-project Skill 的分工
- 查 API / 文档 / 示例 / 校验:走 MCP
- 按规范拼整份
.vpproj.json:继续用.cursor/skills/generate-vp-project - 生成后可用
validate_project自检
按路径校验(省 token)
当生成的工程文件与 MCP 服务在同一台机器时,不必把整份 JSON 内联传给模型,可用 validate_project_file 只传路径:
{ "path": "D:/work/out/demo.vpproj.json" }- 默认关闭:仅当配置了
localValidateRoots(或VP_MCP_LOCAL_VALIDATE_ROOTS)后,validate_project_file才会出现在工具列表。 - 只读取允许目录下的文件:解析真实路径(含符号链接)后做前缀校验,越界路径、非普通文件、超过
maxProjectBytes的文件一律拒绝,杜绝目录穿越。 - 返回结构与
validate_project相同(ok/errors/warnings/dataVersion),并回显解析后的path。 - 公网部署请谨慎开启;
allowedHosts/allowedOrigins仍需按公开配置要求设置。
实时页面控制(AI 操作页面)
除了「静态检索/校验」,MCP 还能连接正在浏览器里打开的某个工程/页面,让 AI 枚举元素、改元素、驱动交互。编辑态支持完整结构编辑(撤销/保存),运行态支持读取/交互/临时改属性(reload 即还原,不写回工程)。
默认关闭,在 vp_config.json 开启(或环境变量 VP_MCP_LIVE_ENABLED=true、VP_MCP_LIVE_SECRET=<稳定密钥>):
{
"mcp": { "liveEnabled": true, "liveSecret": "<32+位稳定密钥>" }
}
liveSecret决定工程地址中的 token;不设则每次重启随机,工程地址会失效。
两种用法
- 配到 Cursor(稳定工程地址):编辑器右下角「AI」面板复制「工程地址」
http://<host>/mcp/p/<projectId>?token=…写入mcp.json。多标签打开同一工程时,先page_sessions再page_attach(sessionId)选定目标标签(仅一个时自动附着)。 - 应用内 AI 按钮(每标签地址):面板里的「本标签地址」
http://<host>/mcp/s/<token>精确指向当前标签,供应用内 AI 面板直接使用。
端点与鉴权
GET /api/vp/live/ws?ticket=…:浏览器 Page Agent 的 WebSocket;ticket 由后端签发(编辑态需登录且为工程 owner;运行态需持有工程 token)。POST/GET /api/vp/live/http[/{sessionId}]:WebSocket 不可用时的 HTTP 长轮询桥(反代丢掉Upgrade导致握手 400 时,前端自动回退);签票接口同时返回httpUrl。POST /api/vp/live/editor-ticket/{id}(需登录+owner)→ 返回 ticket、projectToken、wsUrl/httpUrl、工程 MCP 地址。GET /api/vp/live/runtime-ticket/{id}?token=<projectToken>→ 运行态 ticket(含wsUrl/httpUrl)。POST/GET/DELETE /mcp/p/{projectId}?token=…、/mcp/s/{token}:live MCP 端点(同样受WrapSecure保护,并挂载知识子集search_documentation/get_doc/get_widget_metadata;示例与校验类工具只在独立/mcp生成端点提供)。
可用工具(同族已合并,按端点/会话模式裁剪注册)
工具面刻意收敛:同族操作合并成带 action 参数的单工具、单/批只保留批量形态;编辑态工程端点共 25 个 page_* 工具(含 VP-TSX 两个),本标签(会话)端点不注册 page_attach,运行态会话不注册任何编辑工具(结构编辑、保存与 VP-TSX 均不可用)。
| Tool | 说明 |
|---|---|
page_sessions / page_attach | 会话总览(含当前目标 + 全部会话)/ 选定会话(仅工程端点注册) |
page_get_screens / page_list_elements | 页面结构(摘要省 token);page_list_elements 传 query 即按名字/类型/文字模糊查找(只搜当前屏,普通子串) |
page_get_elements | 元素详情:uids 批量(≤50,fields 限定选项);uid 或 elementUID 单个。两种读法互斥,且只回已写入的选项 |
page_get_schemas | 元素可写属性清单(真实 path/类型/枚举/门控 enabled),按组件类型去重,同屏 8 张卡片只回 1 份 schema |
page_list_widget_types | 已注册组件类型(page_add_element 前必查) |
page_screenshot | 截取当前页面为图片(视觉核对布局/配色/重叠) |
page_get_selection / page_get_data / page_get_params | 读取选中 / 数据 / 参数 |
page_interact / page_emit | 元素交互(action=select/highlight/click:选中/指认/点击)/ 事件 |
page_batch_set_options | 改属性(编辑态持久+撤销 / 运行态临时;单条修改 = 长度 1 的 changes);返回若以 FAILED 开头须先修正失败项 |
page_set_data / page_set_params / page_set_active_screen / page_window | 数据(整表替换)/ 参数(顶层合并)/ 切页 / 画面开关(action=open/close,编辑态等于切编辑画布) |
page_add_element / page_remove_element / page_move_element / page_history / page_save | 结构编辑与撤销重做(page_history action=undo/redo);仅编辑态,运行态会话不注册 |
page_export_tsx / page_apply_project | VP-TSX 整页代码环路(仅编辑态):导出当前页 / 整工程为 VP-TSX 源码,改后编译应用回页面(同机传 path 最省 token),见 VP-TSX 双向环路 |
推荐工作流(schema-first,效率与正确性最优)
page_list_elements(摸清结构)
→ page_get_schemas(uids)(按类型取真实属性 path,绝不臆造)
→ 一次 page_batch_set_options(检查返回的 failed / warnings)
→ page_screenshot(视觉核对)→ page_save- 属性 path 的权威来源:live 会话用
page_get_schemas(含实时门控enabled),生成工程 JSON 用get_widget_metadata;get_doc是人读向导,只列高频项,不可作为写属性依据。 - 常见易混 path:
text-font(文本字体,段落例外是font)、background是开关而background-color才是颜色、按钮四态是background-default-color等带态后缀的形式。 - 批量读用
page_get_elements(uids)/page_get_schemas(uids),不要对同类型元素逐个单读。
语义要点(容易与直觉不符的几处)
- 只读已写入值:
page_get_elements不返回仍是默认值的选项(默认值不落库),默认值请查page_get_schemas。 page_set_data是替换不是追加:表最终就等于你传的rows,空数组即清表。page_set_params只在顶层合并:嵌套对象整段替换,null是存 JSON null 而非删键。page_window分模式:运行态真的开关浮层;编辑态 open 只是切换编辑画布、close 回applied:false。切页面用page_set_active_screen。- 结构字段不在属性面里:
interactions、地图/三维/组态的pieces、data-repeater的unitTemplate只能改 VP-TSX 后page_apply_project;name/visible/locked是列表里的只读元数据。 - 单屏 apply 只替换已存在的屏:新增页面/画面要导出整工程、加好再整体 apply;整屏替换若丢页,结果里会有
droppedScreens。 - 无效入参直接报错:未知 uid(
targetUid/screenUid/ 交互uid)、空字符串、limit=0都会失败而不是静默兜底——这是为了让错误当场暴露,而不是在后面若干步才发现页面没变。
安全
- WS 注册强制鉴权(编辑态验 owner、运行态验工程 token),杜绝伪造会话劫持 AI 命令。
- 运行态默认关闭,需在页面浮层里手动「允许 AI 交互」,且需 URL 携带工程 token(编辑器预览按需附带
&aitoken=)。 - 命令按会话串行执行、带超时;结果大小受
maxResultBytes限制。
安全说明
- 仅暴露公开文档与白名单示例;内部
docs/设计稿不进入数据目录 - 带
Origin的浏览器请求需通过allowedOrigins(可配置) - 请求体 / 超时 / 并发 / 每 IP 频率受限;日志不记录工程正文与查询全文
- 实时页面控制默认关闭;开启后走 token/owner 鉴权,运行态另需显式授权