AI-Extension 浏览器扩展实战:用 WXT 框架把 MCP 协议接进 TaoToken

发布时间:2026/10/2 1:18:01

AI-Extension 浏览器扩展实战:用 WXT 框架把 MCP 协议接进 TaoToken 1. 浏览器里跑通 MCPAI-Extension 与 WXT 到底解决了什么问题AI-Extension 是 OpenTiny 团队基于 WXT 框架开发的一款智能浏览器扩展核心思路是把 MCPModel Context Protocol协议搬进浏览器让 AI 助手不再只是“读网页”而是能真正“点按钮、填表单、跳页面”。如果你之前用过 Cursor、Claude、Coze 这类工具会发现它们对网页的感知基本停留在文本或截图层面遇到动态渲染的 Vue/React 组件、需要登录态的内部系统就很容易卡住。AI-Extension 的价值就在于它作为浏览器扩展运行天然复用你的 Cookie、缓存和登录态同时通过无障碍树解析和视觉模型拿到页面结构快照再把 click、fill、select 这些操作封装成 MCP 工具暴露给 AI。WXT 是这套方案的工程底座。它是一个面向现代浏览器扩展的开发框架支持 Manifest V3、多浏览器构建、热更新和 TypeScript 开箱即用。相比手写 manifest.json 和 webpack 配置WXT 的目录约定和自动导入能省掉大量样板代码。我这次的目标很明确用 WXT 搭一个最小扩展骨架把 MCP 客户端接进去然后把请求端点统一改到 TaoToken 的 API 通道最后在本地 Chrome 里跑通一次完整的 MCP 调用链路。适合谁适合想自己动手做浏览器侧 AI 自动化、又不想从零造轮子的前端或全栈同学。整个链路可以拆成四层WXT 扩展骨架负责生命周期和页面注入MCP 客户端负责和模型侧通信TaoToken 统一 Key/API 通道负责鉴权和模型路由浏览器侧工具层负责把 DOM 操作注册成 MCP 工具。下面按可跟做的顺序展开每一步都给到可复制的配置和命令。2. 前置准备TaoToken 统一 Key 与 API 通道配置在写代码之前先把模型侧的入口准备好。TaoToken 在这里扮演的是统一 Key/API 通道的角色你不需要在扩展里硬编码多个厂商的 Key而是通过一个端点做模型路由。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。第一步是拿到 API Key。进入控制台后创建密钥建议按项目维度命名比如wxt-mcp-extension方便后续轮换。创建完成后你会得到一串以sk-开头的 Key先复制到本地临时文件后面写进.env时用。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API Keys 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。第二步是确认模型 ID。不同任务对模型能力要求不同MCP 工具调用场景建议选支持 function calling 的模型。你可以在模型对话页先做一次简单验证地址是 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 输入一句“请用 JSON 返回一个 click 工具的定义”看返回结构是否符合预期。第三步是理解鉴权方式。TaoToken 的 API 走标准 Bearer Token请求头形如Authorization: Bearer sk-xxxx。在浏览器扩展里这个 Key 不能直接写进前端代码因为扩展包是可以被解压查看的。推荐做法是开发阶段用.env注入构建时通过 WXT 的import.meta.env读取生产环境则应该走你自己的后端做代理扩展只持有短期令牌。这一点在后面的配置片段里会体现。如果你后续要做长期编码或 Agent 类任务可以了解 Coding Plan地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 它更适合持续性的开发场景。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 遇到参数疑问优先查这里。3. WXT 项目骨架与 MCP 客户端可复制配置先初始化 WXT 项目。确保 Node 版本在 18 以上然后执行npx wxtlatest init ai-extension-mcp --template react-ts cd ai-extension-mcp npm installWXT 的目录约定是entrypoints/放各个入口components/放 UI 组件public/放静态资源。默认会生成entrypoints/background.ts和entrypoints/popup/。我们要加一个 content script 用来注入页面工具层再加一个 sidepanel 作为对话界面。先改wxt.config.ts声明权限和 host 权限import { defineConfig } from wxt; export default defineConfig({ manifest: { name: AI-Extension MCP, permissions: [storage, scripting, activeTab, sidePanel], host_permissions: [all_urls], side_panel: { default_path: sidepanel.html, }, }, });接着配置环境变量。在项目根目录建.envVITE_TAOTOKEN_BASE_URLhttps://taotoken.net/api VITE_TAOTOKEN_API_KEYsk-你的Key VITE_MCP_MODEL_ID你的模型ID注意.env要加进.gitignore别提交。然后在entrypoints/background.ts里写 MCP 客户端的最小实现。这里用 fetch 直接调 TaoToken 的 chat completions 端点把工具定义传进去export default defineBackground(() { const BASE_URL import.meta.env.VITE_TAOTOKEN_BASE_URL; const API_KEY import.meta.env.VITE_TAOTOKEN_API_KEY; const MODEL_ID import.meta.env.VITE_MCP_MODEL_ID; const tools [ { type: function, function: { name: click_element, description: 点击页面上的元素, parameters: { type: object, properties: { selector: { type: string, description: CSS 选择器 }, }, required: [selector], }, }, }, { type: function, function: { name: fill_input, description: 向输入框填写内容, parameters: { type: object, properties: { selector: { type: string }, value: { type: string }, }, required: [selector, value], }, }, }, ]; chrome.runtime.onMessage.addListener(async (msg, _sender, sendResponse) { if (msg.type ! MCP_CALL) return; const res await fetch(${BASE_URL}/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${API_KEY}, }, body: JSON.stringify({ model: MODEL_ID, messages: msg.messages, tools, tool_choice: auto, }), }); const data await res.json(); sendResponse(data); return true; }); });这段代码的关键点tools数组就是 MCP 工具在模型侧的声明模型返回tool_calls后由 content script 执行真实 DOM 操作。Base URL、Key、Model ID 三件套全部来自环境变量符合统一通道的接入方式。再写 content script负责执行工具调用export default defineContentScript({ matches: [all_urls], main() { chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) { if (msg.type ! EXEC_TOOL) return; const { name, args } msg; try { if (name click_element) { const el document.querySelector(args.selector); if (!el) throw new Error(元素未找到); (el as HTMLElement).click(); sendResponse({ ok: true }); } else if (name fill_input) { const el document.querySelector(args.selector) as HTMLInputElement; if (!el) throw new Error(输入框未找到); el.value args.value; el.dispatchEvent(new Event(input, { bubbles: true })); sendResponse({ ok: true }); } } catch (e) { sendResponse({ ok: false, error: (e as Error).message }); } return true; }); }, });到这里WXT 骨架、MCP 客户端、工具执行层就齐了。接下来是加载验证。4. 加载扩展并验证一次完整 MCP 调用链路构建开发版本npm run devWXT 会输出一个.output/chrome-mv3-dev目录。打开 Chrome地址栏输入chrome://extensions右上角开启“开发者模式”点“加载已解压的扩展程序”选择.output/chrome-mv3-dev。加载成功后扩展列表里会出现 AI-Extension MCP。接着打开任意一个测试页面比如一个带登录表单的本地 HTML。点扩展图标打开 sidepanel在输入框里发一句“帮我点击 id 为 login-btn 的按钮”。sidepanel 会把消息发给 backgroundbackground 调 TaoToken 的 chat completions模型返回tool_callsbackground 再把EXEC_TOOL消息发给 content scriptcontent script 执行document.querySelector(#login-btn).click()。验证成功的标志有三个一是 sidepanel 里能看到模型返回的 tool_calls 结构二是页面上的按钮真的被点击了三是 background 的 Network 面板里能看到对https://taotoken.net/api/v1/chat/completions的 200 响应。如果这三步都通说明 MCP 调用链路在浏览器侧跑通了。如果你想更直观地看模型返回可以在 sidepanel 里加一段渲染逻辑把data.choices[0].message.tool_calls打印出来。实测下来第一次调用可能会有几百毫秒延迟属于正常范围。另外注意content script 默认运行在隔离环境拿不到页面 JS 内存里的变量如果你要读 Vue/React 状态需要把world改成MAIN但那样会牺牲一部分安全性按需选择。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节按真实报错来对照都是我在接入过程中遇到或社区里高频出现的。401 Unauthorized最常见的原因是 Key 没读到或格式不对。先检查.env里VITE_TAOTOKEN_API_KEY是否以sk-开头然后确认构建时环境变量真的被注入——WXT 只暴露VITE_前缀的变量。如果 Key 正确但仍 401检查请求头是不是写成了Authorization: sk-xxx正确格式是Bearer sk-xxx。另外 Key 被删除或过期也会 401去 API Keys 页面确认状态。local proxy failed这个报错通常出现在你本地起了代理服务、但扩展请求没走通的情况下。排查顺序是先确认VITE_TAOTOKEN_BASE_URL写的是https://taotoken.net/api而不是带路径的完整端点再确认扩展的 host_permissions 包含all_urls最后看 background 的 console 有没有跨域报错。如果是 Manifest V3fetch 在 background service worker 里发起不受页面 CORS 限制但需要确保 service worker 没被浏览器休眠中断。reading choices of undefined这个报错说明data.choices是 undefined通常是响应体不是预期的 JSON 结构。可能原因有三个一是请求打到了错误端点比如漏了/v1二是模型 ID 写错服务端返回了错误对象三是响应被拦截成了 HTML。排查方法是在 background 里先console.log(await res.text())看原始返回。确认端点、模型 ID、Key 三件套一致后这个问题基本就消失了。OAuth 相关报错如果你在扩展里接了需要 OAuth 的第三方服务可能会遇到 token 过期或 scope 不足。注意 MCP 工具调用本身不依赖 OAuth它走的是 TaoToken 的 Bearer Token。如果你看到 OAuth 报错先确认是不是把两套鉴权混在一起了。扩展侧的 OAuth 应该单独走chrome.identity和模型通道分开管理。另外提一个容易忽略的点如果你同时装了 Cline、CC Switch 或 Codex 这类工具它们的auth.json或 MCP 配置可能会和扩展的配置冲突。建议把扩展的 Base URL、Key、Model ID 三件套单独放在.env里不要和编辑器侧的配置混用。CC Switch 的配置里如果出现 MCP server 定义记得 Base URL 指向https://taotoken.net/apiKey 用同一套Model ID 保持一致这样排查时变量最少。6. 把链路固定下来后续接入与验证入口跑通一次之后建议把验证步骤固化成一个小脚本或 checklist避免每次改配置都重新摸索。我的做法是在项目里放一个scripts/verify-mcp.mjs用 Node 直接调一次 chat completions确认 Key 和模型 ID 可用再去浏览器里验证工具执行。这样能把“模型侧问题”和“扩展侧问题”分开定位。如果你要验证模型返回结构模型对话页是最快的入口https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果你要管理或轮换 Key去 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入参数和端点细节以文档为准https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。长期做编码或 Agent 任务的话Coding Plan 更适合持续调用https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。最后说一个实操细节WXT 的npm run dev在改动 background 后会自动重载扩展但 content script 的改动有时需要手动刷新页面才生效。如果你发现工具执行没反应先刷新目标页面再看 background 的 service worker console。这个坑我踩过排查了半小时才发现是 content script 没重新注入。把这一步写进你的验证流程能省不少时间。
延伸阅读

更多相关文章

2026/10/2 1:18:01

Codex桌面版打不开?手动清理缓存与配置修复指南

1. 先搞清楚 Codex 桌面版为什么打不开Codex 桌面版这东西,装的时候挺顺,用着用着突然某天双击图标没反应,或者转两圈就消失,这种场景我遇到过不止一次。很多人第一反应是重装,但重装往往解决不了问题,因为…

2026/10/2 1:13:01

海康MV_CC_SetIntValue报错七类原因与实战避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 1:13:01

DeepSeek 与 MySQL 集成实战:自然语言问数链路搭建与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 4:48:11

轻量级AI代理工具箱:用Coding Plan打造高效AI编程工作流

最近整理自己的AI编程工作流时,我发现一个很有意思的现象:大家手头的AI工具越来越多,GPT、Claude、各种代码补全插件,但效率并没有因此提升多少。工具之间是孤立的,上下文全靠手动复制粘贴,代码段从一个窗口…

2026/10/2 4:48:11

大模型驱动的AI芯片设计新范式:算力密度与软硬协同

1. 这不是“又一个芯片故事”,而是大模型倒逼出的硬科技分水岭“大模型时代的芯片机遇”——这八个字最近频繁出现在半导体展会海报、投资人尽调报告和高校实验室门牌上,但很多人其实没想清楚:它到底指什么?是给GPU厂商多下几单&a…

2026/10/2 4:48:11

MCP协议实战:从原理到商业级AI编程智能体落地全路径

把 AI 从“聊天对象”变成“能干活的下属”,我花了大半年。这半年里最深的体会是:真正卡住智能体落地的,从来不是模型不够聪明,而是模型和外部系统之间能不能稳定、可控、可审计地对话。MCP 协议(Model Context Protoc…

2026/10/2 4:48:11

exe4j打包Java程序:jar转exe与内嵌JRE完整指南

简介:这份资源面向需要将 Java 工程打包为脱离 JDK 环境独立运行程序的开发者,重点解决 exe4j 生成可执行文件时的配置流程与运行异常问题。内容围绕 jar 文件导出、exe4j 的 JAR EXE mode 选择、依赖 jar 引入、Java 版本与 JRE 搜索路径配置等关键环节…

2026/10/2 4:43:11

游戏引擎底层架构设计:从团队分工到模块边界的工程实践

1. 团队分工:底层架构设计的隐藏前提聊游戏引擎架构,大多数人第一反应是渲染管线、内存管理、ECS 那套东西。但我在实际项目里踩过最大的坑,反而不是技术选型,而是团队分工和架构边界互相打架。好几年前我们启动过一个自研移动端引…

2026/10/1 5:21:14

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/10/1 17:09:46

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/2 0:02:57

PWN入门:从栈溢出原理到ROP链实战

1. 这不是“学PWN”,是重新理解你每天敲的每一行C代码我第一次在CTF赛场上写出能控制程序流的exp时,手抖得连gdb的c命令都输错三次。那道题只有23行C代码,一个gets()调用,一个printf(),一个return——它甚至没开NX&…

2026/10/2 0:02:57

Windows下cudaMallocHost显存占用之谜:WDDM与TCC模式差异及优化方案

1. 一个反直觉的显存占用现象第一次在 Windows 上看到cudaMallocHost把显存吃掉的时候,我的反应是打开任务管理器反复确认了三遍。明明调用的是主机端锁页内存分配,按 CUDA 文档的说法,这块内存应该落在系统 RAM 里,跟 GPU 的显存…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑