内容
# @customaise/mcp
MCP 服务器连接 AI 编程代理到 [Customaise](https://customaise.com) Chrome 扩展。管理用户脚本,构建代理脚本,在用户登录的浏览器会话中调用 WebMCP 工具,视觉选择 DOM 元素,直接从 IDE 驱动标签页。
**18 种工具,5 种资源,WebSocket 桥** 连接您的 IDE 和真实的 Chrome 会话。
```
AI 代理 ←(stdio)→ MCP 服务器 ←(WebSocket)→ Customaise 扩展
```
## 快速开始
### 1. 安装 Customaise
安装 [Customaise Chrome 扩展](https://customaise.com) 并在设置中启用 **MCP 桥**。
### 2. 添加到您的 IDE
**Cursor** (`.cursor/mcp.json`):
```json
{
"mcpServers": {
"customaise": {
"command": "npx",
"args": ["-y", "@customaise/mcp"]
}
}
}
```
**Claude Desktop** (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"customaise": {
"command": "npx",
"args": ["-y", "@customaise/mcp"]
}
}
}
```
**Windsurf** (`.windsurf/mcp.json`):
```json
{
"mcpServers": {
"customaise": {
"command": "npx",
"args": ["-y", "@customaise/mcp"]
}
}
}
```
**Kiro** (`.kiro/mcp.json`):
```json
{
"mcpServers": {
"customaise": {
"command": "npx",
"args": ["-y", "@customaise/mcp"]
}
}
}
```
**Codex** (`~/.codex/config.toml`):
```toml
[mcp_servers.customaise]
command = "npx"
args = ["-y", "@customaise/mcp"]
```
**Antigravity** (`mcp_config.json`):
```json
{
"mcpServers": {
"customaise": {
"command": "npx",
"args": ["-y", "@customaise/mcp"]
}
}
}
```
### 3. 完成
您的代理现在可以读取和编辑用户脚本,构建代理脚本,调用 WebMCP 工具,选择 DOM 元素,检查控制台,并捕获活动标签页的截图。
## 工具(18 个)
### 脚本生命周期
| 工具 | 描述 |
|------|-------------|
| `list_scripts` | 列出由扩展程序管理的每个脚本(用户脚本和代理脚本) |
| `import_script` | 将脚本拉取到本地文件进行编辑 |
| `export_script` | 将本地文件推送到 Customaise(验证并安装) |
| `delete_script` | 永久删除脚本 |
| `toggle_script` | 启用或禁用脚本 |
### 浏览器上下文
| 工具 | 描述 |
|------|-------------|
| `get_page_context` | 当前页面的 DOM 快照 |
| `get_console_context` | 控制台日志,错误和 `GM_log` 输出 |
| `list_tabs` | 列出所有打开的浏览器标签页 |
### 标签页控制
| 工具 | 描述 |
|------|-------------|
| `open_tab` | 在给定 URL 处打开新标签页 |
| `close_tab` | 按 ID 关闭标签页 |
| `focus_tab` | 通过 ID 切换到标签页 |
| `reload_tab` | 重新加载标签页以重新注入脚本 |
### 视觉 DOM 目标
| 工具 | 描述 |
|------|-------------|
| `get_selected_elements` | 获取用户视觉选定的 DOM 元素,具有防弹选择器和截图 |
| `take_screenshot` | 捕获可见标签页,可选突出显示特定元素 |
### WebMCP 代理工具
| 工具 | 描述 |
|------|-------------|
| `list_webmcp_tools` | 列出代理脚本当前在标签页上注册的 WebMCP 工具 |
| `call_webmcp_tool` | 调用 WebMCP 工具;提示门控工具在用户同意之前阻塞(见下文) |
### UI 控制和批量
| 工具 | 描述 |
|------|-------------|
| `toggle_ui` | 显示或隐藏 Customaise UI 叠加层 |
| `sync_scripts` | 将所有脚本批量导出到本地目录 |
## 资源(5 个)
任意连接的代理可以通过 `resources/read` 读取的 5 种资源。两个约定手册定义了 Customaise 如何期望编写用户脚本和代理脚本。代理应该在触摸脚本之前阅读相关手册。
| URI | 描述 |
|-----|-------------|
| `customaise://scripts` | 扩展程序管理的每个脚本的实时 JSON 列表(ID,名称,启用状态,匹配模式,共享标志) |
| `customaise://scripts/{scriptId}` | 特定脚本的完整源代码和元数据 |
| `customaise://conventions` | 指向您正在使用的脚本类型的正确手册 |
| `customaise://userscript-conventions` | 完整用户脚本参考:文件结构,IIFE 模式,`GM_*` API,符号级编辑,`@match` 和 `@namespace` 规则 |
| `customaise://agentscript-conventions` | 完整代理脚本参考:`// ==AgentScript==` 块,`// @webmcp <tool> <permission>` 声明,`navigator.modelContext.registerTool()`,同意模型 |
## WebMCP 工具调用和同意(HITL)
代理脚本通过 `navigator.modelContext.registerTool(...)` 在网页上注册工具。每个工具在代理脚本的 `// @webmcp <toolName> <permission>` 头部中以三种权限之一声明:
- **`allow`**:工具立即执行。~50 到 100ms 往返时间每次调用(扩展程序仍运行权限检查)。
- **`prompt`**:每次调用都会显示浏览器中的同意模态窗口,并阻塞直到用户批准或拒绝。最多 **5 分钟**。为此设计。不要在紧密循环中链接提示门控调用,并将长时间的 `call_webmcp_tool` 视为正常。
- **`deny`**:工具被抑制,调用立即失败。
"始终允许”和“始终拒绝”按钮在同意模态窗口上持续保存每个脚本每个工具的决定,直到用户在扩展程序设置中重置它。这些覆盖存储在用户的设备上的 `chrome.storage.local` 中;MCP 服务器对此无可见性。
### 远程批准(可选)
如果用户具有 Power User 并在 Customaise 帐户页面启用了远程 HITL 批准,则提示门控调用也会在那里镜像。他们可以从任何登录的浏览器(包括手机)批准或拒绝。扩展程序模态窗口或远程界面可以解析;首先签署的决定获胜。从 MCP 客户端的角度来看,这是透明的:`call_webmcp_tool` 只需在任何授权界面批准时返回结果,如果被拒绝或超时,则返回错误。
### MCP 客户端看到的内容
- 提示门控 `call_webmcp_tool` 响应可能需要长达 5 分钟。向最终用户显示待定状态,而不是激进超时。
- 如果用户拒绝,`call_webmcp_tool` 返回错误。MCP 服务器不会重试。
- 工具调用参数通过 HTTPS 以明文传输到我们的后端,并 **KMS-encrypted 静止** 存储在 Firestore 中。元数据(toolName,scriptName,origin)保持明文。参见 Customaise [隐私政策](https://customaise.com/privacy)。
## 视觉 DOM 选择
用户可以在浏览器中视觉选择元素,扩展程序实时将上下文文件推送到您的工作区:
```
.customaise/dom-context/<script-name>/
├── element-name.dom.md # 选择器,元素上下文,用户注释
├── element-name.screenshot.png # 选定元素的截图
└── ...
```
> [!NOTE]
> **文件保存在哪里?**
> MCP 服务器将其写入 `.customaise/` 到其当前工作目录(通常是 Cursor 或 Windsurf 中的项目根目录)。
> 如果您使用的是全局 IDE,如 Claude Desktop,它默认为您的主目录 (`~/.customaise/`)。要强制特定项目文件夹,请在 MCP 配置中设置 `CUSTOMAISE_WORKSPACE`:
>
> ```json
> "env": { "CUSTOMAISE_WORKSPACE": "/absolute/path/to/your/project" }
> ```
使用 `get_selected_elements` 以编程方式检索选择,或直接从工作区读取 `.dom.md` 文件。
每个选择包括 **防弹分层选择器** (稳定 ID → 数据属性 → ARIA → 语义类 → 结构定位),以便定位在页面更新后仍然存活。
## 工作流程
### 用户脚本
```
1. get_page_context → 了解目标页面
2. 用户选择元素 → .dom.md 文件自动推送到工作区
3. 编写 .user.js 文件 → AI 使用 IDE 工具编写脚本
4. export_script → Customaise 验证并安装
5. reload_tab → 重新注入脚本
6. get_console_context → 检查错误
7. take_screenshot → 验证视觉结果
```
### 代理脚本
```
1. 读取 customaise://agentscript-conventions → 在编写之前获取正确的结构
2. get_page_context → 在目标页面上查找稳定选择器
3. 编写 .agent.js 文件 → 通过 // @webmcp 声明工具,注册 navigator.modelContext.registerTool()
4. export_script → Customaise 验证并注入
5. reload_tab → 代理脚本在其工具注册到页面
6. list_webmcp_tools → 确认工具显示
7. call_webmcp_tool → 调用一个;提示门控调用等待用户同意
```
## 约定资源
两种 MCP 资源记录了脚本格式和授予表面,扩展程序公开:
- `customaise://userscript-conventions` — `==UserScript==` 元数据块,`@match` / `@grant` / `@connect` / `@require` / `@resource`,`GM_*` API 表,以及 Customaise `CM_*` 授予:`CM_promptAI` (设备 Gemini Nano 通过 Chrome 148+ 提示 API,具有会话,流式传输和多模态输入),`CM_devtools` / `CM_withDevtools` (Chrome DevTools 协议,具有每个会话的用户选择加入),以及 `CM_findElement` / `CM_findExternalElement` (选择器助手,在页面更新后存活)。
- `customaise://agentscript-conventions` — `==AgentScript==` 元数据块,`// @webmcp <tool> <permission>` 声明,`navigator.modelContext.registerTool()` 注册模式,同意门,相同的 `CM_*` 和 `GM_*` 表面可用于用户脚本。
在编写脚本之前阅读其中一个。
## 文件同步
使用 `sync_scripts` 将所有脚本批量导出到本地目录:
```
sync_scripts({ directory: "~/customaise-scripts" })
```
这会创建:
- **每个脚本一个 `.user.js` 文件。** 文件名源自脚本名称(小写,短线,例如 `my-cool-script.user.js`)。
- **`.customaise-manifest.json`**:映射文件名到脚本 ID 以进行往返编辑。
### 清单格式
```json
{
"dark-mode-fix.user.js": "vm_script_1774225715376_lus75sdzn",
"my-cool-script.user.js": "vm_script_1774225800123_abc12defg"
}
```
### 往返
1. `sync_scripts` 将所有脚本导出到目录。
2. 在 IDE 中编辑任意 `.user.js` 文件。
3. 调用带有文件路径和 `scriptId` 的 `export_script` 更新该脚本。
4. 调用 `export_script` 时省略 `scriptId` 以创建新脚本。
### 文件监视器(自动导出)
`sync_scripts` 调用后,MCP 服务器监视目录中的 `.user.js` 更改。在 IDE 中保存文件会自动将文件推送到 Customaise,无需手动 `export_script`。
## 配置
| 环境变量 | 默认值 | 描述 |
|---------------------|---------|-------------|
| `CUSTOMAISE_WS_PORT` | `4050` | WebSocket 服务器端口 |
| `CUSTOMAISE_MCP_EXTRA_EXTENSION_IDS` | _(空)_ | 允许连接的额外扩展 ID 列表。需要用于具有非标准扩展 ID 的解包开发版本 |
| `CUSTOMAISE_MCP_ALLOW_INSECURE` | _(未设置)_ | 设置为 `1` 以禁用源白名单。**仅限测试。** 启动时发出大声警告 |
| `CUSTOMAISE_WORKSPACE` | _(cwd)_ | `.customaise/` 文件应写入的绝对路径。对于不将 cwd 设置为项目根目录的 IDE 很有用(Claude Desktop,Antigravity) |
## 安全边界
MCP 服务器在 `ws://localhost:4050` 上以明文监听环回接口。连接通过 **HTTP 源标头白名单** 进行身份验证:
- **允许**:`chrome-extension://anmpijcpaobaabcdncjjmnhdeibipmko` (生产)和 `chrome-extension://ijjaffggglamocdapoihpkcpealflopp` (暂存)。Chrome 在扩展程序服务工作者的 WebSocket 握手上自动标记此标头;您无需配置任何内容。
- **拒绝**:常规网页(`https://...`),未知扩展 ID 和没有源标头的握手。返回 HTTP 403。
**这阻止了什么**:恶意网页打开 `new WebSocket('ws://localhost:4050')` 并在您不知情的情况下调用 WebMCP 工具。这是最可能的滥用向量。
**这不阻止**:以您的用户身份运行的恶意本地进程。Node 的 `ws` 客户端(以及大多数 HTTP 库)允许调用者伪造任何源标头。如果您不信任以您的 OS 用户身份运行的进程,则威胁模型已经比此桥接更广泛。
**深度防御**:每个 `prompt` 权限工具仍需要您在 Customaise 同意模态窗口中明确批准后运行。声明为 `allow` 的工具无需询问即可运行,因此仅安装来自您信任的来源的代理脚本。
**开发版本**:如果您加载具有自定义密钥的解包扩展,请设置 `CUSTOMAISE_MCP_EXTRA_EXTENSION_IDS=<your-extension-id>` 在 MCP 服务器的环境中。
## 要求
- **Node.js** ≥ 18
- **Chrome** 安装 Customaise 扩展(≥ 1.2.3 for v2 桥协议 - 旧扩展仍然有效,但不显示 cap-usage 显示)
- **MCP Bridge** 在 Customaise 设置中启用(免费,登录)
## 计划层级
MCP 桥对任何登录的 Customaise 用户免费。免费使用限制为 **每天 50 次调用** 和 **每 7 天滚动窗口 150 次调用**。**Power User** 解锁无限 MCP。限制涵盖每次成功的工具调度(包括内置工具和 WebMCP 调用);失败的调用和协议级流量不计入。
当限制触发时,服务器在实现定义的 `-32029` 插槽中返回 JSON-RPC 错误,并带有人类可读的消息 + 带有范围、已使用/限制和重置时间戳的结构化 `data`。显示工具错误的 IDE 原样渲染消息。无论层级如何,都需要登录;如果没有新的 Firebase ID token,服务器返回 `-32028 MCP_AUTH_REQUIRED`。
## 故障排除
**"Customaise 扩展未连接"**
- 确保 Chrome 正在运行 Customaise 扩展。
- 检查扩展程序设置中是否启用了 MCP Bridge。
- 扩展程序在几秒内自动连接。
**端口冲突 4050 上**
- 设置不同的端口:`CUSTOMAISE_WS_PORT=4051 npx @customaise/mcp`。
**导出后脚本未运行**
- 调用 `reload_tab` 以触发脚本重新注入。
- 检查 `@match` 模式是否涵盖当前 URL。
**`call_webmcp_tool` 挂起数分钟**
- 工具是 `prompt`-gated。用户必须在浏览器中批准,或如果启用远程 HITL 批准,则远程批准。5 分钟预算前自动拒绝。显示待定状态而不是激进超时。
**`call_webmcp_tool` 返回类似“拒绝同意”的错误**
- 用户拒绝模态窗口后预期返回。5 分钟预算过期或之前在该工具上设置了“始终拒绝”覆盖。用户可以在扩展程序设置中重置每个工具的覆盖。
**`list_webmcp_tools` 加载后返回空**
- 行走约定手册的故障排除检查清单。最常见的是 Customaise 设置中的全局 AgentScripts 切换为关闭,或者 `@match` 模式不涵盖 URL。有关完整列表,请参见 `customaise://agentscript-conventions`。
## 许可证
MIT