在 goose 中接入 Fetch MCP 扩展:让 AI Agent 自主抓取并处理网页内容
在 goose 中接入 Fetch MCP 扩展让 AI Agent 自主抓取并处理网页内容【免费下载链接】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/gooseFetch 是 goose 官方扩展目录servers.json中收录的第三方 MCP Server它以uvx mcp-server-fetch方式启动为 goose 提供网页抓取与内容处理能力。读完本文你将掌握在 goose Desktop 与 goose CLI 中安装、配置 Fetch 扩展的完整方法并跟随一个笑话问答网页实战示例理解 agent 如何调用 Fetch 工具获取远程数据再交给 Developer 等内置扩展 完成建站与文件操作。该指南的原始出处见 fetch-mcp.md。什么是 Fetch MCP Servergoose 的扩展机制建立在 Model Context ProtocolMCP 之上允许 goose 连接任意实现了该协议的 MCP Server从而获得新的工具与能力。Fetch 就是这样一个服务器它以标准输入输出stdio方式与 goose 通信向 agent 暴露抓取一个 URL 并返回其内容的fetch工具让 goose 可以读取普通网页、API 返回的 JSON/文本等远程资源作为后续推理与操作的素材。在本仓库中Fetch 被明确标注为endorsed: true官方认可推荐其元数据描述为Web content fetching and processing capabilities并附带一条重要的安装提示某些网站可能通过robots.txt屏蔽爬取抓取此类站点时会失败。这意味着 Fetch 遵循robots.txt协议适合抓取公开内容同时它也负责把抓取到的内容做精简/转 Markdown处理如后续示例中出现的Content type application/json; charsetutf-8 cannot be simplified to markdown日志所示原始格式数据则会原样返回给 agent。已知限制Google 系列模型暂不兼容在接入前必须先了解一个官方文档明确标注的已知限制参见 fetch-mcp.mdFetch 扩展的 JSON Schema 中使用了format: uri字段Google 模型例如 gemini-2.0-flash不支持该字段因此Fetch 扩展在 Google 模型上无法工作。如果你当前配置的 provider 是 Google 系模型请先切换到其他支持的模型如 Anthropic、OpenAI 或本地模型再使用 Fetch 扩展。安装前置条件Fetch 服务器通过uvx启动因此运行前你需要在本机安装 uvuv 内置的uvx命令用于直接运行 Python 包无需手动创建虚拟环境。这是唯一的依赖Fetch 本身不需要 API Key。快速安装Desktop 与 CLI 两种方式官方文档提供两种一键接入途径goose Desktop 快速安装直接点击扩展安装深度链接deep linkgoose://extension?cmduvxargmcp-server-fetchidfetchnameFetchdescriptionWeb%20content%20fetching%20and%20processing%20capabilities点击后 goose Desktop 会自动弹出安装确认将 Fetch 注册为一个cmduvx、参数为mcp-server-fetch的标准 IO 扩展。Deep link 协议各参数含义参见 using-extensions.mdcmd为启动命令arg可重复传递、id/name/description分别定义扩展的唯一标识、显示名与描述注意所有参数需做 URL 编码。goose CLI 快速验证直接在终端执行uvx mcp-server-fetch该命令会一次性拉取并启动 Fetch MCP Server。若终端没有任何报错并停留在前台运行说明服务器可正常工作CtrlC 退出即可。正式配置为 goose 扩展能运行服务器与配置成 goose 扩展是两回事。下面给出三种正式配置路径按使用场景任选其一。方式一goose Desktop推荐日常使用点击应用左上角的侧边栏按钮选择Extensions在Extensions面板点击Add custom extension在弹出的Add custom extension表单中填写TypeStandard IOIDfetch可自定义NameFetchDescriptionWeb content fetching and processing capabilitiesCommanduvxArgsmcp-server-fetch按需在Timeout字段设置 goose 等待该扩展单次工具调用完成的最长时间单位秒源码中默认常量为 300 秒见 crates/goose/src/config/extensions.rs点击Add完成注册。方式二goose CLI 交互式配置运行goose configure在菜单中选择Add Extension选择Command-Line Extension依次回答向导问题扩展名称填Fetch运行的命令填uvx mcp-server-fetch随后设置超时时间建议 300 秒如需环境变量则按提示补充向导结束提示Added Fetch extension即配置成功。完整的交互式配置流程与截图式输出可参考 using-extensions.md 中Adding Extensions一节。方式三直接编辑配置文件适合进阶与自动化对于高级用户可直接编辑 goose 全局配置文件例如 macOS/Linux 下的~/.config/goose/config.yaml为 Fetch 增加一个扩展条目extensions: fetch: name: Fetch cmd: uvx args: [mcp-server-fetch] enabled: true type: stdio timeout: 300从源码角度看这个 YAML 条目会被反序列化为 ExtensionConfig 枚举的Stdio变体其中cmdargs组成要启动的完整命令行timeout控制单次工具调用等待上限envs/env_keys用于注入环境变量。值得注意的两点实现细节可在 crates/goose/src/config/extensions.rs 的测试用例中验证若条目缺少name字段配置解析器会自动以 YAML 映射的 key如fetch补全为扩展名扩展名中的空格与非字母数字字符会被 name_to_key 规范化空格删除、其余特殊字符替换为_并转小写后作为存储 key因此Fetch与fetch可以互相定位。单次会话临时启用不落盘安装如果不想把 Fetch 写入默认配置只在本次会话中临时启用可直接在启动会话时指定goose session --with-extension uvx mcp-server-fetch--with-extension定义在 crates/goose-cli/src/cli.rs支持重复传参以一次挂载多个 stdio 扩展也支持VARvalue前缀形式内联环境变量例如带 API Key 的扩展可写成goose session --with-extension WEATHER_API_KEYxxx uvx mcp-server-fetch配合--no-profile可只加载命令行指定的扩展而忽略默认扩展。在 Docker / devcontainer 场景下goose session --container id --with-extension uvx mcp-server-fetch会把扩展跑在容器内详见 goose-in-docker.md。实战让 goose 抓取笑话 API 并生成交互网页配置完成后Fetch 的fetch工具会以FETCH动作出现在 goose 的可用工具列表中。下面复现官方文档的完整实战从 Official Joke API 获取程序员笑话并让 goose 生成一个可交互猜谜的网页。给 goose 的 Promptmake a web page that tells jokes for programmers. The page should ask the user the setup of the joke, allow them to guess the punchline and then tell them if they are right or wrong. Include a button that allows them to request another joke. you can fetch the jokes from the official joke apigoose 的执行过程节选自官方输出goose 首先自行规划了步骤然后调用 Fetch 验证 API 数据结构First, lets verify the API endpoint and see what kind of data we get Then create an HTML file with the necessary structure Add JavaScript to handle the interactions FETCH url: https://official-joke-api.appspot.com/jokes/programming/random Output Content type application/json; charsetutf-8 cannot be simplified to markdown, but here is the raw content: Contents of https://official-joke-api.appspot.com/jokes/programming/random: [{type:programming,setup:A SQL query walks into a bar, walks up to two tables and asks...,punchline:Can I join you?,id:23}] Perfect! Now Ill create an HTML file with the necessary structure and JavaScript code: TEXT_EDITOR command: write file_text: !DOCTYPE html html langen head meta charsetU... path: programmer_jokes.html Output programmer_jokes.html注意两个关键细节它们揭示了 goose 的扩展协作机制抓取验证先行goose 先用FETCH拉取接口样本确认返回的是 JSON 数组且字段为setup谜面与punchline谜底——这保证了后续生成的代码与真实 API 契约一致写文件动作交给了另一组工具Fetch 只负责读TEXT_EDITOR的write命令来自 Developer 等扩展。换句话说goose 在会话中统一编排多个扩展Fetch 是其中获取远程数据的一环。生成的网页goose 最终交付了一个带下述能力的programmer_jokes.html每次从/jokes/programming/random拉取一条随机编程笑话并展示谜面提供输入框让用户猜谜底提交后判断对错并给出视觉反馈对为绿色、错为红色展示真实谜底、猜过后禁用输入框防止重复提交提供 Get Another Joke 按钮加载下一条并对 API 失败做了错误兜底采用响应式布局桌面与移动端均可正常使用。官方文档在Results一节放出了该网页的运行截图见文首图并将完整源码收纳在details折叠块中可直接对照学习!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleProgrammer Jokes/title style body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; text-align: center; } .container { background-color: #f5f5f5; padding: 20px; border-radius: 10px; margin-top: 20px; } .setup { font-size: 1.2em; margin-bottom: 20px; } .guess-container { margin-bottom: 20px; } #guessInput { padding: 10px; width: 300px; margin-right: 10px; } button { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; } button:hover { background-color: #45a049; } .result { margin-top: 20px; font-weight: bold; } .correct { color: green; } .incorrect { color: red; } #punchline { display: none; margin-top: 20px; font-style: italic; } /style /head body h1Programmer Jokes/h1 div classcontainer div idsetup classsetupLoading joke.../div div classguess-container input typetext idguessInput placeholderGuess the punchline... button onclickcheckGuess()Submit Guess/button /div div idresult classresult/div div idpunchline/div button onclickgetNewJoke() stylemargin-top: 20px;Get Another Joke/button /div script let currentJoke null; async function getNewJoke() { try { const response await fetch(https://official-joke-api.appspot.com/jokes/programming/random); const jokes await response.json(); currentJoke jokes[0]; document.getElementById(setup).textContent currentJoke.setup; document.getElementById(guessInput).value ; document.getElementById(result).textContent ; document.getElementById(punchline).style.display none; document.getElementById(guessInput).disabled false; } catch (error) { document.getElementById(setup).textContent Error loading joke. Please try again.; } } function checkGuess() { const guess document.getElementById(guessInput).value.trim().toLowerCase(); const punchline currentJoke.punchline.toLowerCase(); const resultElement document.getElementById(result); const punchlineElement document.getElementById(punchline); if (guess punchline) { resultElement.textContent Correct! You got it! ; resultElement.className result correct; } else { resultElement.textContent Not quite! Here\s the punchline:; resultElement.className result incorrect; } punchlineElement.textContent currentJoke.punchline; punchlineElement.style.display block; document.getElementById(guessInput).disabled true; } // Load first joke when page loads getNewJoke(); /script /body /html需要 API Key 的接口怎么办优先走环境变量本示例中的 Official Joke API 无需鉴权但很多真实业务 API 需要 API Key。官方文档给出的最佳实践是不要直接把 Key 写进 Prompt 或代码而是把它设置为环境变量后告诉 goose 变量名让 goose 自行从环境中读取。原文档的示范句式如下get tomorrows weather for New Orleans from the weatherapi. Dont use the key directly but instead use a script that gets the value from the env var WEATHER_API_KEY落到配置层面有两种做法启动会话时内联goose session --with-extension WEATHER_API_KEYxxx uvx mcp-server-fetch在 config.yaml 的扩展条目中用envs声明键值extensions: fetch: name: Fetch cmd: uvx args: [mcp-server-fetch] enabled: true envs: WEATHER_API_KEY: YOUR_KEY type: stdio timeout: 300启用 / 禁用与二次安装后的管理会话级启用goose Desktop 中点按底部 Puzzle 图标即可在会话中开关扩展CLI 会话内可直接输入/extension uvx mcp-server-fetch动态添加仅当前会话生效重启即失效。默认启用CLI 运行goose configure→Toggle Extensions用空格键勾选/取消fetch回车保存。彻底移除必须先禁用再移除——goose configure→Remove Extension勾选已禁用的fetch后回车。该约束在源码层面对应 config/extensions.rs 的增删改逻辑。属性修改在 Desktop 的扩展设置齿轮中直接编辑超时、名称或环境变量或编辑配置文件后重启 goose。进阶用法把 Fetch 嵌入 RecipeFetch 不止能手动挂载还可以作为args声明在 goose 的 recipe YAML 中让特定自动化工作流自动拉起 Fetch。仓库内已有先例见无障碍审计 recipe web-accessibility-auditor.yaml它在扩展列表中写入args: [mcp-server-fetch]从而在每次执行该 recipe 时自动获得网页抓取能力用于对目标站点做可访问性检查。这一用法说明Fetch 适合作为爬取待分析页面的通用前置工具被任意面向 Web 内容的自动化任务复用。小结接入 Fetch MCP Server 后goose 就获得了读取互联网任意公开 URL的能力配合既有内置扩展即可完成诸如抓取 API → 生成网页/报告 → 落盘文件的完整闭环。本文从安装、四种配置途径Desktop、交互式 CLI、config.yaml、--with-extension、环境变量注入、启用禁用管理到 recipe 集成逐层展开并给出了可直接运行的实战示例与完整前端源码。唯一需要记住的坑是若使用 Google 系列模型请先规避format: uri不兼容问题再启用本扩展。【免费下载链接】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),仅供参考