关于 fenestra-mcp
fenestra-mcp 让 AI Agent 渲染并检查 fenestra 构建的原生 Rust GUI。其工具支持无头的设计与验证流程,包括界面查询、交互和动画捕获。
主要功能
- 01无头渲染 fenestra 界面
- 02查询和检查界面结构
- 03与渲染后的界面交互
- 04验证界面属性
- 05将动画捕获为胶片条
- 06渲染 A2UI 内容
适用场景
- 01在 CI 工作流中检查界面变更
- 02检查 Agent 编写的界面
- 03验证布局和无障碍语义
- 04无需录屏即可检查过渡效果
MCP 相关
fenestra-mcp 服务提供 14 个 MCP 工具,用于渲染、查询、交互和验证界面,其中包括 `render_a2ui` 和 `film_ui`。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
fenestra

为 Agent 循环打造的 UI 技术栈。 用 JSON 描述 UI,原生渲染,并在 CI 中检查。这个循环无需编译,也不会遇到不稳定的截图。
fenestra 是一个纯 Rust GUI 框架。它的无头渲染器具有确定性,这意味着开发者和 AI 编码 Agent 都能查看自己构建的内容,并验证其正确性。它也支持 A2UI,即开放的 Agent-to-UI 标准——这是首个原生 Rust 渲染器(fenestra-a2ui)。下面的控件套件和设计系统,就是这个循环可以生成的内容。
▶ 体验在线演示 — 仪表盘和控件画廊通过 WebGPU 在浏览器中运行。没有 DOM,也没有 CSS:每个像素都由 vello 在 wgpu 上绘制,使用的代码与原生窗口相同。想要循序渐进地了解,请查看**这本指南**。
| 浅色 | 深色 |
|---|---|
![]() | ![]() |
上方的主视觉截图展示的是真实工具,而非样机:examples/agent_dashboard.rs
是一个实时仪表盘,用于监控 AI 编码会话,包含虚拟化信息流、图表,以及通过效果层实时滚动显示的内容。SaaS 风格的控件展示则保留在 examples/dashboard.rs 中:
| 浅色 | 深色 |
|---|---|
![]() | ![]() |
这里没有浏览器、WebView,也没有 HTML 或 CSS 解析器。fenestra 使用 vello 在 wgpu 上自行绘制所有内容。它使用 taffy 进行布局(flexbox 和 grid),并使用 parley 排版文本。
其上构建了一套带主题的控件,外观如同精致现代的 Web 应用:柔和的分层阴影、OKLCH 色阶、清晰的字体层级、悬停和聚焦时的过渡效果,以及同样受到一等对待的浅色和深色主题。
快速开始
use fenestra::prelude::*;
struct Counter { n: i64 }
#[derive(Clone)]
enum Msg { Inc, Dec }
impl App for Counter {
type Msg = Msg;
fn update(&mut self, msg: Msg) {
match msg { Msg::Inc => self.n += 1, Msg::Dec => self.n -= 1 }
}
fn view(&self) -> Element<Msg> {
col().p(SP6).gap(SP4).items_center().children([
text(self.n.to_string()).size(TextSize::Xl2).weight(Weight::Semibold),
row().gap(SP3).children([
button("Decrement").variant(ButtonVariant::Secondary).on_click(Msg::Dec),
button("Increment").on_click(Msg::Inc),
]),
])
}
}
fn main() { fenestra::run(Counter { n: 0 }, WindowOptions::titled("Counter")) }
运行 cargo add fenestra,粘贴代码,然后运行 cargo run。如果你想从模板开始,运行 cargo generate richer-richard/fenestra-template,即可获取一个已配置无头 UI 测试和 CI 的模板。
每次重绘时,整个视图都会重新构建、布局并重新绘制。没有差异比较,也没有宏,因此所有内容都能自动补全。
Agent 可以查看自己构建的内容
将 (element tree, theme, size) 渲染为像素是一项纯函数,而且可以在没有窗口或显示服务器的情况下运行:
use fenestra::shell::{SyntheticEvent, render_app, render_element};
// A picture of any element tree:
let image = render_element(my_view(), &Theme::dark(), (800, 600));
image.save("preview.png")?;
// Or drive a full app with scripted input and look at the result:
let image = render_app(
&mut app,
&[
SyntheticEvent::MouseMove { x: 50.0, y: 34.0 },
SyntheticEvent::MouseDown,
SyntheticEvent::MouseUp,
SyntheticEvent::Text("hello".into()),
],
(800, 600),
&Theme::light(),
);
assert_eq!(app.value, "hello");
无头渲染具有确定性(嵌入字体、固定缩放比例、减少动态效果),因此可以实际进行像素精确的黄金测试——fenestra 自带的组件套件就通过这种方式在 CI 上测试,无需连接 GPU 显示器。
同一条管线还支持一种名为 fenestra/1 的 JSON 编写格式,供不想编译 Rust 的 Agent 和工具使用。你只需用 JSON 描述 UI,fenestra-describe 就会将其解析为与构建器生成的相同 Element 树。该格式涵盖整个组件套件:数据表、树、弹出框、命令面板、OKLCH 颜色选择器、图像、图表和 markdown。
接下来有几种使用方式。fenestra render 会写入 PNG。fenestra preview <file> 会打开一个窗口,每次保存时都会重新渲染。而 fenestra-mcp 服务则通过十四个 MCP 工具(包括 render_a2ui),为 Agent 提供完整流程:渲染、查询、交互、验证。你还可以查看动态效果,而不只是单帧:Harness::film(也可通过 fenestra film 或 MCP film_ui 工具使用)会在启用真实动态效果的情况下捕获一系列画面,并将它们合成为一张带说明文字的胶片。
无头渲染涵盖和不涵盖的内容。 它会渲染实时窗口所显示内容中的一个特定子集。正是这个子集让渲染具有确定性,因此了解其边界很有价值。
文本使用嵌入字体,因此拉丁文字渲染准确。真实的等宽字体、CJK 字体、表情符号和 RTL 字体来自操作系统,只会在真实窗口中显示。动态效果始终强制设为减少。像素以 macOS/Metal 为基准,Linux/lavapipe 则允许更大的容差。缩放比例不固定——render_element_scaled 会在任意设备缩放比例下运行相同的两阶段管线,因此也能在无头环境中捕获仅在视网膜屏幕上出现的回归问题,例如细线和模糊半径。
有两处在该渲染路径之外看起来会有所不同。完整的 Liquid-Glass 光学效果(背景模糊、边缘透镜效果、自适应活力效果)只会在无头黄金测试路径中渲染;实时单通道窗口则会呈现半透明色调、镜面边缘和光泽。在 Web 上,复制内容可以写入系统剪贴板,但从其他应用粘贴内容仍仅限于应用内部;玻璃效果与原生实时窗口一致,而 AccessKit 仍在等待上游 Web 适配器。
因此,对于布局、语义、颜色以及绝大多数像素,无头渲染是值得信赖的。请在真实窗口中检查非拉丁文本、等宽字体和完整玻璃效果。ARCHITECTURE.md 记录了精确的差异清单。
正在与 AI Agent 协作? AGENTS.md 是构建 → 渲染 → 查看 → 验证这一流程的手册(提供给上下文加载器的内容见 llms.txt)。
理念:不依赖 Web 平台,实现 Web 美学
Web 的外观——柔和的立体效果、带色调的中性色、OKLCH 色阶、基于 4px 网格的间距、焦点环、处于 120–300ms 范围内的缓动——是我们在软件中验证最充分的视觉语言。Web 平台却是一种沉重的实现方式。
因此,fenestra 将这种语言编码为有类型的 Rust 值。Theme 由单一强调色相生成。间距、圆角、阴影和动态效果都来自令牌。构建器词汇(row()、.p(SP4)、.rounded(R_MD)、.shadow(ShadowToken::Sm))小到足以记住,规则性又足以让 rust-analyzer——或语言模型——为其提供自动补全。每个组件都会通过主题处理所有颜色,因此切换一个 Mode 就能让整个应用变为深色。
组件库
下方的每个组件都会随所有状态和两种主题一同提供。
控件。 Button、IconButton、Checkbox、Switch、Radio、Slider、 SegmentedControl、Select,以及一个颜色选择器,包含 OKLCH 明度 × 色度调节面板、色相和透明度滑条,以及宽容的十六进制输入。
文本输入。 TextInput(支持 parley 编辑、剪贴板和 IME)和 TextArea (多行、自动增长)。
表面与反馈。 Tooltip、Modal(焦点陷阱和背景遮罩)、 Toasts、Tabs、Card、StatCard、Badge、Avatar、StatusIndicator(带实时脉冲效果)、Kbd 按键帽、Skeleton 加载器、Divider、Spinner、Table、Callout 和 Progress——包括一个 Material-3 Expressive 波浪条。另附一组精简的 Lucide 图标。
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
随时运行 cargo run --example gallery 重新生成这组内容——它会在无头模式下渲染。
动效
fenestra-motion 可在无头模式下渲染逐帧纯净的动画合成,无需运行窗口或屏幕录制工具。fenestra film 和 MCP film_ui 工具也使用同一条管线,让 Agent 能够观看过渡动画。
下面是一个 fenestra-charts 柱状图,每帧都会根据按排名排序、按轨道插值的数据重新构建:

cargo run -p fenestra-motion --example chart_race -- --mp4 会渲染这段完整序列——领先者在中途易主;这一点已在示例本身中通过结构验证,而不只是靠目测。另外还有两个同样方式渲染的示例:广播式下三分之一字幕
(examples/lower_third.rs)和逐词标题交错出现效果
(examples/title_stagger.rs)。
工作区
| Crate | 作用 |
|---|---|
fenestra | 门面:prelude、run()、示例 |
fenestra-core | Element IR、主题/令牌、布局、文本、绘制、输入、过渡 |
fenestra-shell | 基于 winit + wgpu 的窗口运行器和无头渲染器 |
fenestra-kit | 主题化组件套件,仅基于 core 的公共 API 构建 |
fenestra-charts | 迷你图、折线图和柱状图——第三方组件 Crate 参考实现 |
fenestra-markdown | 将 CommonMark 渲染为原生 fenestra 元素 |
fenestra-looks | 六种开箱即用的设计语言(产品、编辑、终端、控制台、温暖编辑、趣味),一次调用即可应用 |
fenestra-describe | 将 fenestra/1 JSON 解析为与构建器生成的相同 Element 树 |
fenestra-a2ui | 原生 Rust 渲染器,支持 A2UI v0.9——开放的 Agent-to-UI 标准 |
fenestra-render | fenestra CLI:从命令行进行渲染、预览、录制、查询、验证和 lint |
fenestra-mcp | MCP 服务,向 AI Agent 提供渲染、查询、交互和验证等十四种工具 |
fenestra-motion | 帧纯函数动态图形:时间线、无头帧/视频渲染、时间相关 lint、motion CLI |
fenestra-anim | 关键帧动画数学:缓动、弹簧、精确有理数时基 |
fenestra-anim 独立进行版本管理(0.1.x)。它是一个独立的叶子 Crate,不依赖任何 fenestra Crate,也不依赖 wgpu、vello、parley、taffy 或 winit。它从 fenestra-core 和 fenestra-motion 中拆出,让任何按帧或时钟周期采样的项目——无论在本工作区内还是外部——都只需依赖动画数学。fenestra-mcp 也单独进行版本管理,因此 MCP 服务可以按自己的节奏发布。
请参阅 ARCHITECTURE.md,了解管线、组件身份、过渡和叠加层的工作方式——其中按决策顺序记录了框架的构建过程;另请参阅 BENCHMARKS.md,查看真实的帧耗时数据(完整屏幕的重建、布局和绘制约需 0.3 ms;包含 10 万行的列表经虚拟化后约需 0.09 ms)。
设计范围
同一框架、同一令牌,不同的设计语言。
fenestra-looks Crate 集成了六种开箱即用的风格——产品、编辑、终端、控制台、温暖编辑和趣味,可通过 all() 枚举。除此之外,只需调整个别选项,就能为整个组件套件换肤。Theme::with_radius(RadiusScale::sharp()) 可呈现棱角分明的科技风界面。Theme::with_elevation(Elevation::Flat) 会用边框而非阴影绘制表面。Theme::duotone 会将中性灰替换为富有氛围感的色域。如果想使用自定义展示字体,可通过 Fonts::register 按字体角色注册。
下方展示的是与上方柔和默认仪表盘相反的风格:采用石板色调、锐利线条、细线分隔的 控制台,搭配一种荧光绿强调色和等宽数字。与这里的其他内容一样,它以无头模式渲染,并经过黄金测试。
| 浅色 | 深色 |
|---|---|
![]() | ![]() |
组合、命令、无障碍
围绕自身消息类型编写的组件可以通过 Element::map 组合。
后台工作通过 App::init 接入,它会向应用提供可克隆的 Proxy<Msg>。启动一个线程,发送消息回来,窗口就会重新绘制——examples/clock.rs 和 examples/toasts.rs 都采用了这种方式。
每个组件都会从两个方向公开其角色、状态和名称:无头模式下通过 Frame::access_tree(),以便你在 CI 中断言 UI 已添加标签;窗口运行器中则通过 AccessKit 提供给真实的辅助技术。
环境动效来自循环播放的 Keyframes 时间线,图像则来自 image_rgba8(圆形头像可使用 .rounded_full())。
状态
fenestra 当前版本为 0.41.0。ARCHITECTURE.md 逐项记录了它的发展历程。
已发布的内容:
- 交互式小组件套件,包含浅色和深色主题。
- 六种即用型设计语言(
fenestra-looks)和磨砂玻璃材质系统。 - 图表和 Markdown,作为第三方小组件 crate 的参考。
fenestra/1JSON 格式,可用于编写整个套件。该格式由fenestra-describe解析,再由fenestraCLI 和十四个fenestra-mcp工具渲染并验证。- A2UI v0.9 渲染器(
fenestra-a2ui)。 - 效果层(
Cmd/Sub),带有确定性测试框架。 - macOS 上的声明式原生菜单、任意缩放比例下的高 DPI 无头渲染,以及可实时重新加载的
fenestra preview窗口。 fenestra-motion,用于帧纯净的动态图形,支持时间相关 lint 和胶片条捕获。
每项更改在合并前都必须通过相同的检查:cargo fmt --check、clippy -D warnings、完整测试套件,以及在 macOS/Metal 和 Linux/lavapipe 上进行的无头黄金 PNG 对比。此外,每次推送时以及每周还会运行 cargo audit 和 cargo deny。
未完成的工作以优先级排序,列在 ARCHITECTURE.md 的“Deferred”备注中。需要提前了解的缺口包括:A2UI 的 DateTimeInput 是 ISO 文本字段,而非日历;被遮挡的文本字段会以未遮蔽的形式渲染(渲染器会对此报告备注,而不是将其隐藏);Web 端的 AccessKit 仍在等待上游适配器。
许可证
可自行选择 MIT 或 Apache-2.0 许可证。嵌入的 Inter 字体、Playfair Display 字体样式(海报和编辑风格)、Fraunces 可变文本衬线字体(暖色编辑风格中的 opsz/光学尺寸衬线字体)以及 JetBrains Mono(终端风格)均采用 SIL Open Font License 1.1 许可;随附的 Lucide 图标路径数据采用 ISC 许可(参见 fenestra-kit/LICENSE-LUCIDE.txt)。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。











