lvglui MCP server
Enables PC-side preview and rendering of existing ESP-IDF + LVGL 9.x UI projects, including headless PNG screenshots, control tree/meta JSON output, live preview windows, multi-page rendering, Chinese font generation, and project diagnostics.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
lvglui — 在 PC 上预览任意 ESP-IDF + LVGL 工程
当前发布候选:1.0.0-rc.1(Windows)。
lvglui 把工程里同一份 LVGL 界面源码编成 PC 程序:一张 PNG 给无头渲染/CI/模型看,一个窗口给你实时改。
它面向已有的 ESP-IDF 6.x + LVGL 9.x 工程:LVGL 组件、显示驱动、触摸 BSP 都由工程自己准备好;lvglui 只负责 UI 层的搭建、预览、截图和控件树。
前置条件
Windows 10/11
Node.js 22+
Visual Studio 2022(C++ 桌面开发)
ESP-IDF 6.x(工具会从工程自己的
build/project_description.json、.vscode/settings.json、lvglui.json或IDF_PATH发现它,不信任全局环境)工程里已有可用的 LVGL 9.x,并且显示/触摸已经能工作
界面
.c只 include LVGL 和 UI 自己的头;不要 includedriver/、esp_、freertos/等平台头
Related MCP server: EmbedForge
快速开始
# 1. 在现有工程里注入 UI 组件(只新增文件,不改现有文件)
node cli/lvglui.mjs init --project D:/my_project --width 240 --height 320
# 2. 检查工程/LVGL/IDF/工具链
node cli/lvglui.mjs doctor --project D:/my_project
# 3. 无头渲染 → .lvglui/out/shot.png + tree.json + meta.json
node cli/lvglui.mjs render --project D:/my_project
# 4. 实时预览窗口(改 UI 保存即重编)
node cli/lvglui.mjs preview --project D:/my_projectinit 会:
创建
components/app_ui/(或lvglui.json指定的uiDir)创建
lvglui.json在 stdout 打印一段接入代码;需要你把它粘到
main里(通常替换原来的lv_screen_load(...))
如果 sdkconfig 里能唯一推断出宽高,可以省略 --width/--height;推断不出时命令会失败,不会偷偷用 240×320。
目录
cli/ CLI 入口 + MCP stdio server
core/ 工程发现、配置、IDF/LVGL、构建、渲染、诊断、DSH 安装
host/ PC 壳:窗口、计时、PNG、UI 树、ABI
ui-template/ init 注入的 UI 组件模板
examples/ 可复制的示例 UI(demo-sensor 等)
assets/ 内置字体与第三方素材
dsh/ DeepSeek Harness bundle(skill + MCP client)
test/ node:test 单测 + 集成测试产物只写 <project>/.lvglui/build/ 和 <project>/.lvglui/out/:
build/:lv_conf.h、lvglui.cmake、build.cmd、build.log、shot.exe、preview.exe、ui.dllout/:shot.png、tree.json、meta.json
lvglui.json
{
"schema": 1,
"idfPath": "E:/esp/v6.1/esp-idf",
"lvglDir": "managed_components/lvgl__lvgl",
"uiDir": "components/app_ui",
"entry": "ui_start",
"display": { "width": 240, "height": 320, "colorDepth": 16 },
"build": { "dir": ".lvglui/build" },
"font": { "mode": "off" }
}idfPath/lvglDir/uiDir可相对工程根entry是 UI 入口函数,默认ui_startcolorDepth目前只接受16font.mode默认off:不启用中文字体;project用工程生成的子集;cjk是 LVGL 自带 CJK 子集(覆盖不全,仅兼容旧配置);freetype用运行时 FreeType(用户自带组件与文件系统)font.dynamic默认labels:只生成 UI 字符串用到的字符;common生成 GB2312 一级 3755 常用字 + UI 字符 + ASCII,适合动态中文;freetype由运行时 FreeType 渲染font.mode == "project"时,font.file/font.size/font.name由font add写入;font.mode == "freetype"时写font.file/font.size/font.fsPath/font.freetypeDir;不要手改build.dir只能指向工程内;默认.lvglui/build
UI 契约
/* ui.h */
lv_obj_t *ui_start(lv_obj_t *parent);parent == NULL:创建并返回根 screenparent != NULL:在父对象里建页面,返回页面根
业务数据只通过 ui_port.h:
/* ui_port.h —— 由用户在 main/ui_port_impl.c 实现强符号 */
float ui_port_get_temperature(void);
float ui_port_get_humidity(void);
void ui_port_set_relay(bool on);UI 层只声明/调用
ui_port_*,不碰业务状态ui_template里的ui_port_stub.c在 PC 构建时提供桩;固件构建时是空 TU,用户在main/ui_port_impl.c提供强符号缺实现会在链接期报错,不会悄悄编过
控件命名用 lv_obj_set_name(obj, "val_temp")(预览 lv_conf.h 强制开启 LV_USE_OBJ_NAME;固件侧也要开),渲染时 tree.json 和 PNG 一起给你。
多页界面
默认只渲染入口 ui_start() 返回的那一屏。要让工具按页渲染,UI 组件里再实现三个函数(可选契约,签名固定,不需要共享头文件结构):
/* ui_pages.h */
int ui_page_count(void);
const char *ui_page_name(int index); /* 稳定 id,用作文件名 */
lv_obj_t *ui_page_show(int index, lv_obj_t *parent);ui_page_show(index, NULL) 自己创建根 screen 并加载它;parent 非 NULL 时只在该对象里建页,不要 lv_screen_load。
lvglui render --all-pages # 每页 shot-<name>.png + tree-<name>.json,另出 shot-sheet.png 总览
lvglui render --page settings # 只渲染这一页,仍写 shot.png / tree.json总览图按
meta.json的pages顺序排:≤4 页两列,否则四列,格间距 8px,底色#101820,不放文字标签meta.json里pages[]有每页的name/png/sha256/bytes/nodes,allPages: true一个
_page_函数都不实现时,行为与今天完全一致;只实现一部分会直接报“契约不完整”,不会拖到链接期每页单独起一个
shot.exe进程,避免复用 LVGL 引擎产生悬空指针
init 生成的模板自带 ui_pages.c(默认一页 home),新增页面只需往页面表里加一行。
中文字体
默认不启用中文字体。需要时运行:
# 固定文案:只生成 UI 里出现的字符
lvglui font add --project D:/my_project --preset noto-sans-sc --size 16
# 动态中文:生成 3755 个 GB2312 一级常用字 + UI 字符 + ASCII
lvglui font add --project D:/my_project --preset noto-sans-sc --dynamic common --size 16
lvglui font status --project D:/my_project
lvglui font off --project D:/my_projectlabels 模式生成的文件最小、字形最好;common 模式覆盖常用中文,适合状态文字、设备名、用户输入等运行时才确定的文本。16px 4bpp 的 common 字体 C 文件约 3 MB,实际占用取决于链接器裁剪。
labels 模式会扫描 uiDir 里的 C 字符串字面量,用工具自带的 Noto Sans SC 只生成这些字符的子集;common 模式会额外加入 GB2312 一级常用字:
components/app_ui/fonts/ui_font_noto_sc_16.c # labels
components/app_ui/fonts/ui_font_noto_sc_16_common.c # common
components/app_ui/include/ui_font.h预览和固件编译同一个 .c。模板工程有 src/ui_theme.c 时自动挂到主题;已有工程没有主题文件时,会生成 src/ui_font_apply.c,预览自动应用,固件需在 ui_start 之后调用一次:
lvglui_apply_font(lv_screen_active());字体原件和 OFL 许可证在 assets/fonts/。font status 会报告缺字;改完 UI 文案后重新跑一次 font add。
FreeType(可选高级模式)
需要任意中文、不想每次改文案都重新生成子集时,用 FreeType 运行时渲染。这是 BYO 模式:工具只复制 TTF、生成配置和 apply 代码,不提供 esp_freetype、分区表或 SPIFFS 镜像。
lvglui font add --project D:/my_project \
--dynamic freetype \
--font D:/fonts/NotoSansSC-Regular.ttf \
--fs-path A:/fonts/NotoSansSC-Regular.ttf \
--freetype-dir E:/freetype--font:TTF/OTF 源文件;会复制到components/app_ui/fonts/。--fs-path:固件运行时路径(通常是 SPIFFS/FATFS 挂载点),默认A:/fonts/<文件名>。--freetype-dir:预览端 FreeType 安装前缀(含include/freetype2与lib);不传则让 CMake 在系统路径里找。
固件侧需要:LV_USE_FREETYPE=1、esp_freetype(或等价实现)、TTF 已烧进 fs-path 指向的文件系统。预览侧需要主机 FreeType 头/库;Windows 上还要把 freetype.dll 所在目录加入 PATH,否则渲染会报找不到 DLL。
生成的 src/ui_font_apply.c 在 LVGLUI_FONT_PATH 下创建字体;主机构建会用工程内 TTF 绝对路径覆盖该宏,固件用 fs-path。没有 ui_theme.c 的工程,固件仍需在 ui_start 后调用:
lvglui_apply_font(lv_screen_active());FreeType 不生成 .c 字库,工程体积小,但运行时占 RAM、首次渲染有解析成本;字符集不受限。font off 会删除复制的 TTF、apply 代码和配置项。
命令
命令 | 作用 |
| 编译 + 跑 12 帧 + 输出 PNG/tree/meta(默认命令) |
| 只编译 host 渲染器 |
| 监听 |
| HTTP + SSE 预览( |
| 打开实时窗口;保存→重编→换 |
| 注入 UI 组件骨架和 |
| 生成工程字体:默认 labels 子集, |
| 移除工程字体、主题挂载和 CMake 条目 |
| 查看字体模式、字符数和缺字 |
| 检查工程、IDF/LVGL 版本、工具链、显示配置、平台头 |
| 生成 DSH bundle 用的 |
| 帮助 |
常用选项:
--project <dir>:工程目录(默认LVGLUI_PROJECT或 cwd)--width/--height:显示尺寸;工程没配置时必填--frames <n>:渲染帧数,默认 12--out <dir>:输出目录(不是 PNG 文件路径)--no-build:复用已有shot.exe(shot 缺失时会自动构建)--page <name>:只渲染某一页(需要ui_page_*契约)--all-pages:渲染所有页,另出shot-sheet.png总览--json:render/build/doctor只向 stdout 输出 JSON,日志走 stderr--no-render:init后不做空白页渲染--preset noto-sans-sc:font add使用工具自带字体--size 8..64:字体像素大小--chars "保存":额外加入字体的字符(仍会合并 UI 字符串)--dynamic labels|common|freetype:labels只收 UI 字符(默认);common加 GB2312 一级 3755 常用字;freetype用运行时 FreeType--font <ttf>:font add的源字体文件(默认工具自带 Noto Sans SC)--fs-path A:/fonts/x.ttf:FreeType 固件运行时路径--freetype-dir <prefix>:预览端 FreeType 安装前缀--name ui_font_xxx:生成字体符号名
退出码:0 成功,1 构建/渲染失败,2 用法/配置错误,3 运行时/IO 错误。
在 DSH 里用
node cli/lvglui.mjs dsh install
# 输出里会给你:
# plugin_manager install_bundle target="file:D:/LVGL_preview/dsh"然后重启 DSH。重启后:
技能列表里出现
lvglui工具里出现
mcp__lvglui__*(detect_project、init_ui、render_ui、build_ui、doctor、preview_ui)
直接说:
在 D:/my_project 里把 home 页改成三个传感器卡片,数据走 ui_port,改完截图给我看。
skill 的约束是文字约定:只改 uiDir、不改 main/BSP/sdkconfig/工程 CMakeLists、不 include 平台头、业务只走 ui_port。没有强制写入围栏,也没有自动审计。
移动工具目录后必须重新跑
dsh install,再重新安装 bundle;dsh/cordis.patch.yml是生成文件,已被.gitignore忽略。
限制
只做静态渲染 + 控件树;点击/滑动/动画模拟不在 1.x 范围内,留到 2.0
只支持 16bit 色深
Windows + ESP-IDF 6.x + LVGL 9.x
不拉 LVGL 组件、不配 component manager、不搭显示/触摸 BSP
不做写入审计;UI 层边界靠 skill 约定
不烧录、不接触串口:工具没有
flash命令,MCP 也不暴露任何串口/烧录能力。它只编译出一份 host 预览产物;把固件写进板子始终是人工步骤(idf.py flash)。同理,工具从不操作 eFuse、bootloader、分区表——这些才是真正不可逆的操作
故障排查
现象 | 处理 |
| 在 |
| 检查 |
找不到 vcvars/cmake/ninja | 装 VS2022 C++ 工具;或在 |
| 传 |
编译失败 | 看 |
中文显示方块 | 先 |
|
|
贡献者
Shinku_721 — 项目所有者、需求与验收
DeepSeek — AI 编程协作:架构、实现、测试、文档与发布工程
完整名单见 CONTRIBUTORS.md。
许可证
lvglui本体:AGPL-3.0-or-later,全文见LICENSE。ui-template/以及lvglui init/font add生成的文件:适用LICENSE-EXCEPTION的附加例外,可放入任意许可证的工程,AGPL 不延伸到你的工程。Noto Sans SC:SIL OFL 1.1,见
assets/fonts/OFL.txt。第三方依赖与声明见
NOTICE。
如果你修改并分发 lvglui 本体,AGPL 的源码提供义务适用;用 lvglui 生成的 UI/配置不受影响。
开发
npm test # 单测
npm run test:integration # 集成(my_lcd 不存在时跳过)
node cli/lvglui.mjs doctor --project D:/esps3_test/my_lcd回归基线:D:/esps3_test/my_lcd、240×320、sensor_ui_create、12 帧、PNG sha256 8f3a7ad7e177e94953547ae30e47149d5139de638d87a56449a2f9ea03ddd287。
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Connect ChatGPT, Claude, Cursor or VS Code to your Windows PC: files, terminal, browser, apps.
Agent-Native design tool - create and edit visual designs with agent assistance
Create, edit, preview, and build Flutter apps via FlutterGo.AI cloud MCP (OAuth).
Design circuits, simulate and verify embedded firmware, and lay out PCBs with AI agents.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables LLMs to capture and analyze screenshots of your screen, windows, or regions with smart detection capabilities. Features natural language queries, automatic window targeting, and text enhancement for UI debugging and visual inspection.2MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI-driven embedded development: generate, build, flash, and debug firmware using natural language commands through MCP.MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to control Windows GUI by listing and focusing windows, capturing element snapshots via UIA/OCR/CDP, performing clicks/inputs/scrolls, verifying changes, waiting for screen updates, taking screenshots, and obtaining visual descriptions.2-
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to build, flash, and monitor ESP-IDF projects on real hardware, including serial sessions and pytest-embedded hardware tests.1MIT