goose Apps 扩展实战:让 AI 在聊天中直接创建、迭代与启动 HTML 单文件应用
【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose
Goose 的Apps 扩展让 Agent 不必接触底层文件系统,即可在对话中为用户创建、修改和删除可运行的 HTML 应用——每个应用都以单文件 HTML 的形式保存在本机,并以 MCP App 资源 的形式暴露,随后在独立、沙箱化的窗口中启动运行。阅读本文你将掌握:Apps 扩展的启用方式、应用文件的存储格式与原理、底层list_apps/create_app/iterate_app/delete_app四个工具的真实调用机制,以及如何通过一段自然语言从零构建并持续打磨一个 JSON 格式化工具。
Apps 扩展能做什么
根据文档定义,Apps 扩展面向“通过对话创建、管理、启动简单自定义应用”的场景,尤其适合以下几类轻量工具:
- 快捷小工具:计算器、单位换算器、JSON 格式化器等;
- 数据可视化:图表、仪表盘等;
- 简单游戏与交互组件:小游戏、交互式小组件等。
这类应用被刻意约束为单文件 HTML 应用——由 HTML、CSS 与 JavaScript 构成,不允许引入外部依赖或 npm 包。正因如此,它们可以在任何支持 MCP UI 的客户端(如 goose Desktop)中以独立窗口方式运行,且渲染进程处于沙箱之中。全部创建、修改、删除动作都可以通过聊天完成,无需手工编辑文件。
应用存储在哪儿
Apps 扩展在后台把每一个应用保存为一个 HTML 文件,存储位置与平台相关:
| 平台 | 路径 |
|---|---|
| macOS / Linux | ~/.local/share/goose/apps/ |
| Windows | %APPDATA%\Block\goose\data\apps\ |
源码侧的实现与之完全对应:在 apps.rs 中,扩展初始化时通过Paths::in_data_dir("apps")解析数据目录并create_dir_all创建它,随后遍历目录中所有*.html文件来枚举应用(list_stored_apps)。也就是说,“apps 库”本质上就是磁盘上一个普通目录,每个应用是其中的一个<应用名>.html文件,应用名即文件名的主干部分。
一个应用文件里有什么
虽然扩展面向用户隐藏了文件细节,但了解文件结构对排查问题与进阶定制非常有帮助。GooseApp::from_html/to_html的实现位于 goose_apps/app.rs,从中可以看到一个合法的应用 HTML 由三部分组成:
- 干净的应用 HTML:即用户看到、运行的界面本体;
- JSON-LD 元数据块:
<script type="application/ld+json">,记录应用的机器可读元数据; - 可选 PRD 块:
<script type="application/x-goose-prd">,保存“这个应用最初想做什么”的产品需求说明,供后续迭代参考。
JSON-LD 元数据中的核心字段(序列化时使用 camelCase)如下:
| 字段 | 含义 | 说明 |
|---|---|---|
@context/@type | 命名空间与类型 | 固定为urn:goose.ai:schema与GooseApp |
name | 应用名 | 唯一标识,同时用于组成资源 URI 与文件名 |
description | 简述 | 一至两句、建议不超过 100 字符 |
width/height | 窗口宽高 | 像素;生成时推荐区间为 400–1600 / 300–1200 |
resizable | 是否可缩放 | 布尔值 |
mcpServers | 关联扩展 | 声明应用依赖哪些 MCP 扩展,便于应用内进一步调用工具 |
元数据块会被嵌入 HTML 的<head>(无<head>时自动补充完整文档骨架),写文件前由to_html完成注入,读取时再由from_html通过正则抽取并从 HTML 中剥离这些脚本块,还原出干净页面。uri的统一格式为ui://apps/<name>,MIME 类型为text/html;profile=mcp-app。
启用与配置 Apps 扩展
Apps 属于 goose 的内置平台扩展(platform extension)。在不同的客户端上启用方式略有差异。
goose Desktop(图形界面)
在桌面端的扩展管理界面中直接安装内置的Apps扩展即可,其官方描述为:
Create and manage custom goose apps through chat. Apps are HTML/CSS/JavaScript and run in sandboxed windows.
goose CLI(命令行)
- 运行配置命令:
goose configure- 选择
Toggle Extensions,在扩展列表中勾选apps(用空格切换、回车提交):
┌ goose-configure │ ◇ What would you like to configure? │ Toggle Extensions │ ◆ Enable extensions: (use "space" to toggle and "enter" to submit) │ ● apps │ └ Extension settings updated successfully在源码中,该扩展名为apps(常量EXTENSION_NAME: &str = "apps"),MCP 握手时以Apps Manager作为服务名、同时声明了tools与resources两类能力(见 apps.rs)。
扩展暴露的四个核心工具
Apps 扩展通过标准 MCP 工具接口向外暴露能力。从 list_tools 可以看到四个工具及其实参:
| 工具 | 参数 | 作用 | 可见性 |
|---|---|---|---|
list_apps | 无 | 列出所有已有应用及其名称、尺寸与描述 | Agent 与 UI 均可见 |
create_app | prd(需求描述/PRD) | 基于描述生成一个新应用并自动打开 | 仅 Agent(model-only) |
iterate_app | name+feedback | 依据反馈改进既有应用 | 仅 Agent(model-only) |
delete_app | name | 永久删除一个应用 | 仅 Agent(model-only) |
工具可见性由元数据控制:create_app、iterate_app、delete_app被标记为ui.visibility = ["model"],因此只有模型可以看到并调用它们;而list_apps对模型与界面同时开放。这一设计在源码测试management_tools_are_model_only_while_listing_remains_shared(apps.rs)中有直接验证:管理类工具不会出现在面向 App 的工具清单里。
真实的创建流程:Agent 生成内容再落盘
值得强调的是,create_app并不直接写文件,而是由扩展代调 LLM 生成内容。整体链路为:
- Agent 调用
create_app,传入prd; - 扩展读取系统提示模板 apps_create.md,将 PRD 与“已存在的应用名列表”一并拼入用户消息(避免撞名);
- 扩展调用当前会话的 Provider,并要求其返回结构化工具调用
create_app_content,输出name、description、完整html、width/height/resizable; - 校验名字不重复后,扩展将结果组装为
GooseApp(URIui://apps/<name>、mcp_servers = ["apps"]、PRD 存档)并写入apps数据目录; - 通过平台通知事件
app_created告知界面打开新窗口。
同时代码内置了截断保护:若 LLM 输出 token 数触及max_tokens,会报错提示“生成被截断,请简化应用描述后重试”,避免落盘残缺应用。
iterate_app走类似链路(模板为 apps_iterate.md),区别在于把“原始 PRD + 当前完整 HTML + feedback”一并交给模型,让其调用update_app_content返回更新后的html、description、prd与可选的窗口尺寸。每次迭代都会同步刷新 HTML 内嵌的 PRD,保证后续迭代始终基于最新的产品意图。
实战示例:从一句话到 JSON 格式化应用
启用扩展后,可以直接在聊天窗口下达创建指令。文档以“创建 JSON 格式化应用”为例(该示例使用 Anthropic Claude Sonnet 4.5 模型演示)。
用户的 goose Prompt
Create a JSON formatter app
goose 的响应
I'll create a JSON formatter app for you. This will be a useful tool for formatting, validating, and beautifying JSON data.
Perfect! I've created a JSON formatter app called "json-beautifier" that should have opened in a new window.
生成的应用具备以下完整功能(均来自 goose 首次生成即交付的内容清单):
- 输入 / 输出双栏布局:左侧粘贴输入,右侧展示格式化结果;
- Format 按钮:按缩进规则美化 JSON;
- Minify 按钮:将 JSON 压缩为单行;
- Validate 按钮:校验 JSON 合法性并显示错误;
- Copy 按钮:复制格式化结果到剪贴板;
- Clear 按钮:一键清空重来;
- 语法高亮:键、字符串、数字、布尔值使用不同颜色区分;
- 缩进选项:支持 2 或 4 空格切换;
- 错误提示:红色醒目标注错误信息;
- 字符 / 行数统计:实时展示数据规模;
- 深色主题:舒适的现代化观感。
创建成功后应用会自动弹出新窗口(即文档首页截图中的效果),可直接把 JSON 粘贴到左栏,通过各按钮执行格式化、压缩、校验或复制。
第一版“看起来不错、用起来顺手”,但这不是终点——你可以继续告诉 goose“加一个暗色/亮色切换”“把校验错误展示得更友好”“增加 Base64 解码功能”,它都会通过iterate_app读取当前 HTML 与既有 PRD,围绕你新增的反馈精准修改,而非从头重写。
管理、删除与内置默认应用
- 查看已有应用:可通过
list_apps获取全部应用名、窗口尺寸与描述;也可以直接打开桌面端Apps页面统一管理。 - 删除应用:对 Agent 说“删除某个应用”,或使用
delete_app,对应 HTML 文件会从数据目录移除。删除是永久性的。 - 内置默认应用:首次初始化时,扩展会自动写入一个
clock(时钟)默认应用,对应 HTML 内嵌于 goose_apps/clock.html,URI 为ui://apps/clock。它是只读的“守护资源”——源码对这类 bundled default app 做了三重保护:修改/删除会返回Cannot modify bundled default app错误、即使磁盘缓存被伪造篡改,重载时也会用编译进二进制的原始内容恢复(restore_bundled_default_apps)。相关测试见 goose_apps/cache.rs 与 apps.rs。
安全与沙箱设计
从源码结构看,Apps 的安全边界建立在多层约束上:
- 文件路径防穿越:所有按名读写文件的路径都会经过
is_single_file_name校验,拒绝包含/、\、盘符前缀(如C:)及../等越界形态;测试load_and_resource_read_reject_unsafe_app_names、delete_rejects_unsafe_app_names等对非法命名进行了穷举验证。 - 沙箱渲染:应用以
text/html;profile=mcp-app资源进入渲染层,客户端在独立、受限的窗口中加载。资源模型还预留了细粒度的安全元数据(见 goose_apps/resource.rs):CspMetadata用于声明允许的connect-src(fetch/XHR/WebSocket)、资源加载、iframe 嵌套域名等 CSP 白名单;PermissionsMetadata则对应 iframe Permission Policy 的camera、microphone、geolocation、clipboard-write能力开关。默认情况下这些敏感能力均为关闭状态。 - 无外部依赖的硬约束:由于应用只能是单文件 HTML(禁 npm 与外部依赖),攻击面与供应链风险被天然压缩。
- 二级缓存加固:桌面端 UI 通过
McpAppCache(位于mcp-apps-cache目录,键为“扩展名 + URI”的 SHA-256 摘要)缓存应用,默认应用同样不可删除、不可被伪造替换。
适用边界与建议
结合文档与实现,有几个实践要点值得注意:
- 应用是“小而美”的:单文件、无构建、无依赖的定位决定了它适合交互工具、可视化与小游戏,而不适合承载重型工程逻辑或需要专用依赖的场景。
- 创建质量取决于模型能力:HTML 由当前会话的 LLM 现场生成,不同模型的代码产出与审美会有差异;好在
iterate_app提供了低成本、可反复试错的正反馈闭环——不满意就继续提要求。 - 窗口尺寸与能力声明:首次生成时即可通过描述影响窗口尺寸与是否可缩放;若想让应用读取剪贴板或调用其他扩展能力,需要由宿主客户端按权限策略(Permission Policy)显式放行。
- 宿主依赖:应用虽由扩展管理,但“独立窗口”的呈现依赖支持 MCP UI 的客户端(如 goose Desktop 的 Apps 页面);仅启用 CLI 扩展时可进行管理与文件操作,视觉呈现需在支持端完成。
总结
Apps 扩展是 goose “Agent 驱动 UI”能力的落地形态之一:模型不再只输出文本,而是能端到端地完成“理解需求 → 生成单文件 HTML 应用 → 注册为 MCP App 资源 → 弹出沙箱窗口运行 → 依据反馈持续迭代”的完整循环。想深入机制,可以继续阅读:
- 扩展主实现与四个工具:crates/goose/src/agents/platform_extensions/apps.rs
- 应用模型与 JSON-LD 编解码:crates/goose/src/goose_apps/app.rs
- 资源、CSP 与权限元数据:crates/goose/src/goose_apps/resource.rs
- 桌面缓存与内置默认应用保护:crates/goose/src/goose_apps/cache.rs
- 内容生成提示模板:crates/goose/src/prompts/apps_create.md、crates/goose/src/prompts/apps_iterate.md
- MCP App / MCP UI 资源机制:documentation/docs/guides/interactive-chat/mcp-ui.md
【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考