Debugg AI

官方

使您的代码生成代理能够通过Debugg AI测试平台,在远程浏览器中针对新的代码变更创建并运行零配置的端到端测试。

你可以用 Debugg AI MCP 做什么?

  • 运行 AI 浏览器测试 — 让助手对任意 URL 或 localhost 执行 check_app_in_browser,用自然语言描述要测试的内容,即可获得通过/失败结果及截图。
  • 快速探测多个页面 — 使用 probe_page 批量检查 1–20 个 URL 的控制台错误、网络问题和渲染状态,无需 LLM 成本或代理循环。
  • 触发知识图谱爬取 — 调用 trigger_crawl 触发服务端浏览器代理爬取,将 HAR 和控制台日志产物填充到项目的知识图谱中。
  • 管理测试套件和用例 — 创建、运行并查看 test_suitetest_case 实体的结果,包含每项测试的结论和通过率。
  • 检查执行产物 — 通过 executions 获取完整执行详情,包括截图、HAR 网络追踪和控制台日志,用于调试运行时问题。
  • 管理环境和会话 — 通过 environment 创建或更新带凭据的环境,并使用 sessions/clearSessions 控制热登录会话的复用。

文档

Debugg AI — MCP 服务器

通过模型上下文协议实现 AI 驱动的浏览器测试。将其指向任意 URL(或 localhost)并描述要测试的内容——AI 代理会浏览你的应用并返回通过/失败结果及截图。

Debugg AI MCP server

设置

需要 Node.js 20.20.0 或更高版本(来自 posthog-node@^5.26.0 的传递依赖)。

测试 http://localhost:... URL 需要 caddy 二进制文件 —— check_app_in_browserprobe_pagetrigger_crawl 通过本地 Caddy 反向代理隧道传输 localhost 目标。 这会自动安装:@radically-straightforward/caddy npm 依赖会在 npm install/npx 期间 为你的平台下载固定版本的 Caddy 发行版,就像本项目已经为 ngrok 二进制文件所做的那样—— 正常情况下无需自行安装。如果该下载从未执行(npm install --ignore-scripts、离线/隔离环境安装), 请将 CADDY_BIN 指向你自己的安装(brew install caddy / apt install caddy / 参见 caddyserver.com/docs/install)——缺失时会在首次 localhost-URL 调用时 以清晰的错误提示,而不是静默挂起。公共 URL 调用、所有非浏览器工具以及 test_suite {action:"run"}(使用自己专用的隧道并完全绕过 Caddy)无论哪种情况都不需要它。

debugg.ai 获取 API 密钥,然后添加到你的 MCP 客户端配置中:

{
  "mcpServers": {
    "debugg-ai": {
      "command": "npx",
      "args": ["-y", "@debugg-ai/debugg-ai-mcp"],
      "env": {
        "DEBUGGAI_API_KEY": "your_api_key_here"
      }
    }
  }
}

或者使用 Docker:

docker run -i --rm --init -e DEBUGGAI_API_KEY=your_api_key quinnosha/debugg-ai-mcp

Dockerfilenpm install 步骤原则上会以本地安装相同的方式自动获取 caddy——但截至撰写本文时,Dockerfile 没有 COPY 构建现在 需要的几个目录(handlerstoolstypesconfig), 并且仍然引用一个不再存在的 tunnels/ 目录,因此全新构建很可能在此之前就失败了。 这是一个预先存在的缺口,与 Caddy 无关。当前已发布quinnosha/debugg-ai-mcp 镜像 无论如何都早于 Caddy 依赖——在该镜像中,对 check_app_in_browser/probe_page/trigger_crawl 的 localhost-URL 调用会以 CaddyBinaryNotFoundError 失败,直到镜像被重新构建(修复 Dockerfile) 并重新发布,或者 CADDY_BIN 指向单独内置的版本。公共 URL 调用、非浏览器工具 和 test_suite {action:"run"} 无论哪种情况都不受影响。

工具

服务器暴露 8 个工具:三个 浏览器 工具,外加每个受管实体一个基于操作的工具。 核心工具是 check_app_in_browser(完整 AI 代理)和 probe_page(轻量级无 LLM 页面探测)。 其余工具——projectenvironmenttest_suitetest_caseexecutions——各自接受一个 action 判别器(例如 {"action":"list"})来选择操作。 破坏性的 delete 操作需要确认(在支持的地方通过提示询问,否则使用 confirm: true)。

浏览器

check_app_in_browser

针对你的应用运行 AI 浏览器代理。代理会导航、交互并返回带截图的报告。 localhost URL 通过 ngrok 自动隧道传输。

参数类型描述
description字符串 必填要测试的内容(自然语言)
url字符串 必填目标 URL——http://localhost:3000 会自动隧道传输
environmentId字符串特定环境的 UUID
credentialId字符串特定凭据的 UUID
credentialRole字符串按角色选择凭据(例如 adminguest
username字符串登录用户名(临时——不持久化)
password字符串登录密码(临时——不持久化)
loginCredentials数组代理在任务期间遇到的登录账户——[{username, password, label?}]
useEnvironmentCredentials布尔值默认 truefalse 禁止自动填充环境存储的凭据;未指定账户时意味着完全不登录
freshSession布尔值默认 falsetrue 强制真实登录而不是重用该账户持有的预热会话
auth对象认证前置条件——{precondition, entryUrl, deepUrl, environmentId, username, password}
repoName字符串覆盖自动检测的 git 仓库名称(例如 my-org/my-repo

每次调用只做一项聚焦检查。代理有约 25 步的内部预算;将更广泛的测试套件拆分为多次调用。

凭据:作为参数传递,而不是写在描述中

仅在 description 中命名账户不会让代理使用它——代理会回退到环境存储的凭据, 而应用拒绝错误账户的结果看起来就像应用故障。你作为参数传递的任何内容在运行中的 每次登录都会优先于环境默认值,而不仅仅是第一次:

  • username / password(或 credentialId / credentialRole)——运行的身份。
  • auth.username / auth.password——当你同时使用 auth.precondition: "login" 时固定前置条件登录。
  • loginCredentials——代理在任务中途遇到的登录表单的账户。这适用于诸如 设置密码 → 被跳转到登录页 → 以刚创建的账户登录 之类的流程,如果拆分为多次调用会丢失浏览器状态。

当静默回退到默认测试用户会使检查失效时,请设置 useEnvironmentCredentials: false

需要检查一个完全不需要登录的页面? 传递 useEnvironmentCredentials: false 且不指定任何账户。 这个组合的含义正是它所说的——不要登录——运行会完全跳过身份验证,而不是寻找登录表单。 适用于公共页面、营销网站、文档以及任何登录前的内容。它也更快:在默认(auto) 模式下,代理会跟随页面上的"登录"链接并尝试环境存储的账户,然后才会评估任何内容。

会话重用:为什么检查会报告"无登录表单"

运行不会每次都登录。验证登录后,后端会捕获该账户的会话并在下次运行时恢复相同身份的会话, 这会完全跳过登录——这就是为什么检查可以合理地返回 submitted: false 且没有登录表单: 它已经登录了。恢复的运行会在 logins 中报告自身带有 reason: "restored_session", 因此你可以将其与真正未找到表单的运行区分开来。

会话按账户键控,因此指定不同的账户永远不会重用其他人的会话。有两种方法绕过重用:

  • 单次调用设置 freshSession: true——这次真实登录,然后重新捕获。当登录流程就是你要检查的内容、 怀疑存储的会话已过期、或应用在角色之间唯一的路径是注销时使用。
  • environment 工具,action: "clearSessions"——使存储的会话失效,以便后续运行重新登录。 使用 username / credentialId 缩小范围;无范围的清除需要确认, 因为环境中的每个账户随后都会重新认证。

使用 action: "sessions" 查看环境当前持有的内容以及每个是否会被重用。

结果会报告实际使用的身份,因此错误的身份是可见的,而不会伪装成应用故障:

"logins": [
  { "username": "qa+invitefix@example.com", "source": "task", "submitted": true, "authenticated": true }
],
"credentialWarning": {
  "requested": "qa+invitefix@example.com",
  "used": ["qatest123@example.com"],
  "message": "This run signed in with an environment default credential even though '…' was specified. …"
}

sourcetask | explicit | credential_id(你指定的账户) 或 env | env_default(环境存储的账户)。credentialWarning 仅在你指定了账户 但仍使用了环境默认值时出现。loginError 在指定账户无法解析且运行拒绝替换为其他账户时出现。

每次成功运行都会返回一个 browserSession 块以及截图——捕获的 HAR(完整网络跟踪) 和控制台日志(每条 JS 控制台消息)的预签名 S3 URL。使用它们来检测重取循环、 水合错误以及其他通过类型检查和单元测试的运行时问题:

"browserSession": {
  "harUrl": "https://...session_18139.har?X-Amz-...",
  "consoleLogUrl": "https://...session_18139_console.json?X-Amz-...",
  "recordingUrl": "https://...session_18139_recording.webm?X-Amz-...",
  "harStatus": "downloaded",
  "consoleLogStatus": "downloaded",
  "harRedactionStatus": "redacted",
  "consoleLogRedactionStatus": "redacted"
}

URL 是短期的预签名 S3——通过 executions {action:"get", uuid} 重新获取父执行以续期。 harStatus / consoleLogStatus 区分 'downloaded'(URL 可获取)、 'not_available'(页面未产生任何内容)、'failed'(捕获中断)。 在新运行时,URL 通常为 null,因为捕获在代理完成后异步上传—— 轮询 executions {action:"get", uuid: executionId} 直到状态达到 'downloaded'。授权 / Cookie / token/secret/api_key 头会在工件持久化之前在服务端被清除。

trigger_crawl

触发服务端浏览器代理爬取以填充项目的知识图谱。localhost URL 自动隧道传输。 成功摄取后返回 {executionId, status, targetUrl, durationMs, outcome?, crawlSummary?, knowledgeGraph?, browserSession?}knowledgeGraph.imported === truebrowserSession 块 (HAR + 控制台日志 URL,与上述格式相同)在完成的爬取中也会出现。

probe_page

轻量级无 LLM 批量页面探测。 传递 1-20 个 URL;每个都会导航、等待内容稳定 (DOM 静默,有界——绝不会等待网络静默,因为活跃应用永远不会达到), 并返回渲染状态——截图 + 页面元数据 + 结构化控制台错误 + 网络摘要。 没有代理循环、没有 LLM 成本、没有场景断言。用于"我是不是刚破坏了 /settings?"、 重构后的多路由冒烟测试、CI 每次 PR 的扫描,以及快速可用性检查, 这些场景下 check_app_in_browser 的 60-150 秒代理循环过于冗余。

参数类型描述
targets数组 必填1-20 个条目:[{url, waitForSelector?, waitForLoadState?, timeoutMs?}]
targets[].url字符串 必填公共 URL 或 localhost(自动隧道传输)
targets[].waitForLoadState枚举'domcontentloaded'(默认,+ 有界内容稳定)/ 'load'(还阻塞第三方嵌入)/ 'networkidle'(接受但从不发出——活跃站点的网络不会空闲)
targets[].waitForSelector字符串可选 CSS 选择器,导航后等待
targets[].timeoutMs数字每个 URL 的超时时间,1000-30000(默认 10000)
includeHtml布尔值在每个结果中返回原始 HTML(默认 false)
captureScreenshots布尔值每个目标返回一张 PNG(默认 true)

批次中的所有目标共享一个会话隧道,但只有同端口(或全公共)的批次共享单个后端执行—— 一次调用中同一端口上的 5 个 URL 比 5 个并行的单 URL 调用快得多。 混合多个本地端口的批次会分解为每个端口组一个顺序后端执行 (仍然是一次调用,仍然是一个按原始顺序合并的 results[],但是 N 次后端往返 而不是一次——更慢,但不会被拒绝)。每个 URL 的 error 字段保证了批次的弹性: 单个目标失败不会导致其他目标失败。

networkSummary 聚合键是 origin + pathname ——重取循环(?n=0..4 反复命中同一端点)会折叠为带计数的单个条目,因此 /api/pollcount: 47 出现就是用户最初要求的可操作的"无限重取循环"信号。

性能预算:1 个 URL <10 秒,20 个 <25 秒。localhost 死端口在 <2 秒内返回 LocalServerUnreachable,不会消耗工作流执行。

project

操作参数结果
get{uuid}精选项目详情
list{q?, page?, pageSize?}分页摘要
create{name, platform, (teamUuid|teamName), (repoUuid|repoName)}已创建项目

团队和仓库通过 uuid名称解析(不区分大小写的精确匹配;无匹配时 NotFound,多个匹配时 AmbiguousMatch)。没有 update/delete—— 请从 DebuggAI Web 应用重命名或删除项目。

environment

操作参数结果
get{uuid, projectUuid?}环境(内联凭据,密码永不返回)
list{projectUuid?, q?, page?, pageSize?}分页环境列表,每个环境带凭据数组
create{name, url, description?, projectUuid?, credentials?}已创建的环境(可选种子凭据)
update{uuid, name?, url?, description?, addCredentials?, updateCredentials?, removeCredentialIds?}已修补的环境;凭据操作按 移除 → 更新 → 添加 顺序执行
delete{uuid, projectUuid?, confirm?}删除环境(级联删除凭据)— 需要确认
sessions{uuid, username?, credentialId?}环境持有的已捕获登录会话,按账户分组,含 isUsableusableCount
clearSessions{uuid, username?, credentialId?, confirm?}使其失效,以便下次运行真正登录 — 无范围清除需要确认

省略时,projectUuid 会从 git 仓库自动解析。单个凭据失败会显示在 credentialWarnings[] 中,不会阻塞环境操作。

sessions / clearSessions 管理后端复用以跳过登录的预热认证会话(参见 会话复用)。会话内容永不返回——会话 cookie 即承载凭据。clearSessions 将会话标记为无效而非删除行,因此复用会立即停止,同时捕获历史保持可读。

test_suite

操作参数结果
list{projectUuid|projectName, search?, page?, pageSize?}分页套件列表,含状态和通过率
create{name, description, projectUuid|projectName}已创建的套件
run{suiteUuid|(suiteName+project), targetUrl?}异步触发所有测试
results{suiteUuid|(suiteName+project)}套件 + 每个测试的结果
delete{suiteUuid|(suiteName+project), confirm?}软删除 — 需要确认

test_case

操作参数结果
create{name, description, agentTaskDescription, suiteUuid|(suiteName+project), relativeUrl?, maxSteps?}已创建的测试用例(不自动运行)
update{testUuid, name?, description?, agentTaskDescription?}已修补的测试用例
delete{testUuid, confirm?}软删除 — 需要确认

executions

操作参数结果
get{uuid}完整详情(nodeExecutions + 状态 + errorInfo)+ 截图/GIF 工件
list{status?, projectUuid?, page?, pageSize?}分页摘要

后端的 404 会以 isError: true{error: 'NotFound', message, uuid} 形式呈现。凭据始终在返回时不带密码。

分页

每个过滤模式响应都是分页的。响应结构:

{
  "filter": { "...echoed query params..." },
  "pageInfo": { "page": 1, "pageSize": 20, "totalCount": 47, "totalPages": 3, "hasMore": true },
  "<items>": [ ... ]
}

可传递可选的 page(从 1 开始,默认 1)和 pageSize(默认 20,最大 200;超限值会被截断)。任何响应都不会被静默截断。

资源

除工具外,服务器还将只读实体作为 MCP 资源 暴露,以便客户端浏览并作为上下文 @提及它们:

URI内容
debugg-ai://projects所有项目(第一页)
debugg-ai://environments自动检测项目的环境
debugg-ai://executions最近的执行(第一页)
debugg-ai://project/{uuid}单个项目,完整详情
debugg-ai://environment/{uuid}单个环境(内联凭据,密码已编辑)
debugg-ai://execution/{uuid}单个执行,完整节点详情 + 工件链接

读取操作分派到与 project / environment / executions 工具相同的处理器,因此数据和认证完全相同。资源是附加的——不支持资源的客户端可继续使用工具。

安全不变量

  • 密码是只写的。它们永远不会出现在任何工具的任何响应体中。
  • 隧道 URL(*.ngrok.debugg.ai)会从所有浏览器代理响应中剥离,包括代理撰写的文本。
  • 后端的 404 以 isError: true{error: 'NotFound', ...} 形式呈现,绝不会作为抛出的异常。
  • 缺少 DEBUGGAI_API_KEY 会在首次调用时以结构化工具错误呈现——服务器仍会正常注册和列出工具。

迁移到 v3.0.0(基于操作的工具)

v3 将 20 个按动词划分的工具整合为 8 个基于操作的工具。旧工具 → 新 tool {action}

已移除替代
search_projectsproject {action:"get"} / project {action:"list"}
create_projectproject {action:"create"}
update_projectdelete_project已弃用 — 请使用 DebuggAI Web 应用
search_environmentsenvironment {action:"get"} / {action:"list"}
create_environment / update_environment / delete_environmentenvironment {action:"create"|"update"|"delete"}
create_test_suite / search_test_suites / run_test_suite / get_test_suite_results / delete_test_suitetest_suite {action:"create"|"list"|"run"|"results"|"delete"}
create_test_case / update_test_case / delete_test_casetest_case {action:"create"|"update"|"delete"}
search_executionsexecutions {action:"get"|"list"}
trigger_crawl headless 参数已弃用 — 始终无头模式

delete 操作现在需要确认(提示提示,或 confirm: true)。客户端在 MCP 重启后获取新界面。

从 v1.x 迁移(v2.0.0 中的破坏性变更)

v2 将 22 个工具的界面缩减为 11 个。旧工具 → 新工具映射:

已移除替代
list_projectsget_projectsearch_projects(uuid 模式 vs 过滤模式)
list_environmentsget_environmentsearch_environments
list_credentialsget_credentialsearch_environments — 凭据内联在每个环境上
create_credentialcreate_environment({credentials: [...]}) 种子,或 update_environment({addCredentials: [...]})
update_credentialupdate_environment({updateCredentials: [{uuid, ...patch}]})
delete_credentialupdate_environment({removeCredentialIds: [uuid]})
list_teamslist_reposcreate_project({teamName, repoName}) — 名称解析,带歧义处理
list_executionsget_executionsearch_executions
cancel_execution已弃用 — 后端自动缩减

响应结构变更:列表响应上的裸 count 字段已移除 — 请使用 pageInfo.totalCount

配置

环境变量必需用途
DEBUGGAI_API_KEY后端 API 密钥。别名:DEBUGGAI_API_TOKENDEBUGGAI_JWT_TOKEN
DEBUGGAI_API_URL后端基础 URL。默认为 https://api.debugg.ai
DEBUGGAI_TOKEN_TYPEtoken(默认)或 bearer
DEBUGGAI_EVAL_TEMPLATE覆盖 check_app_in_browser 分派到的 App Evaluation 工作流 slug。默认为 flow/e2es/app-eval。分派固定到此 slug,因此后端模板重命名不会破坏它。
LOG_LEVELerror / warn / info(默认) / debug
POSTHOG_API_KEY覆盖嵌入式遥测项目密钥(例如私有 fork)。
DEBUGGAI_TELEMETRY_DISABLED设置为 1 / true / yes / on 以完全禁用遥测。
DEBUGGAI_API_KEY=your_api_key

远程 / HTTP 传输(可选)

默认情况下,服务器使用 stdio(本地 npx)。它也可以作为托管的多用户远程 MCP 运行,基于无状态 Streamable HTTP + OAuth:

DEBUGGAI_MCP_TRANSPORT=http PORT=3000 DEBUGGAI_TOKEN_TYPE=bearer npx -y @debugg-ai/debugg-ai-mcp@latest

它是一个 OAuth 资源服务器:每个 POST /mcp 都需要 Authorization: Bearer <token>;缺失/无效令牌会收到 401,其中包含指向 RFC 9728 元数据的 WWW-Authenticate,客户端会针对通告的授权服务器运行 OAuth 流程。承载令牌是请求范围的——api.debugg.ai 会验证它。

端点用途
POST /mcpMCP Streamable HTTP(承载令牌保护)
GET /.well-known/oauth-protected-resourceRFC 9728 元数据(授权服务器发现)
GET /health负载均衡器 / ECS 健康检查
环境变量默认用途
DEBUGGAI_MCP_TRANSPORTstdio设置为 http 以启用远程传输
PORT3000HTTP 监听端口
DEBUGGAI_MCP_PUBLIC_URLhttps://mcp.debugg.ai此服务器的公共资源 URL(RFC 9728 resource
DEBUGGAI_OAUTH_ISSUERhttps://auth.debugg.ai向客户端通告的授权服务器
DEBUGGAI_TOKEN_TYPEtoken设置为 bearer 以便 OAuth 令牌作为 Authorization: Bearer 转发

stdio 安装不需要这些。

多副本部署(上线前必须确认): 隧道状态(ngrok 会话隧道、其 Caddy 实例及其端口路由锁)是进程内的,按调用者以承载令牌的哈希为键——没有跨进程协调。在普通轮询负载均衡器后运行多个副本意味着一个调用者的调用可能落在不同副本上,并为其命中的每个副本创建一个隧道,而不是整个会话一个隧道(额外的 ngrok 成本,受副本数量限制,通过现有的 55 分钟空闲自动关闭自愈——绝不是跨会话的正确性错误,因为任何单个工具调用在其整个持续时间内都停留在单个副本上)。要在多副本 HTTP 部署上获得预期的"每个会话一个隧道"行为,请在负载均衡器上配置会话亲和路由(基于 getSessionKey() 派生的同一身份进行粘性/一致性哈希——实际上,即调用者的 Authorization 承载令牌)。有关完整推理和未配置时的诚实降级路径,请参阅 docs/local-tunnel-multiplexer-architecture-2026-07-31.md §2.1。

遥测

MCP 服务器默认启用遥测——一个嵌入的只写 PostHog 项目密钥(phc_*),以便团队观察整个安装群的缓存命中率、轮询节奏、隧道可靠性和其他运营指标。捕获的事件:

事件时机
tool.executed / tool.failed每次工具调用
workflow.executed每次浏览器代理执行(携带 pollCountdurationMsfinalIntervalMs
tunnel.provisioned / tunnel.provision_retry / tunnel.stopped每次隧道生命周期事件
template.lookup / project.lookup缓存命中/未命中,冷调用时带 durationMs

隐私立场:

  • 唯一 ID 是 SHA-256(api_key).slice(0, 16) — 绝不是原始密钥,无 PII。
  • phc_* 密钥按 PostHog 约定是只写的;可安全嵌入源代码。
  • 设置 DEBUGGAI_TELEMETRY_DISABLED=1 可完全退出(解析为无操作提供程序;无事件离开进程)。

活动模式在启动时记录:

Telemetry enabled (PostHog, DebuggAI default project). Set DEBUGGAI_TELEMETRY_DISABLED=1 to opt out.
Telemetry enabled (PostHog, custom POSTHOG_API_KEY)
Telemetry disabled (DEBUGGAI_TELEMETRY_DISABLED is set)

本地开发

npm install
npm run build
npm run test:e2e        # real end-to-end evals against the backend

评估套件将构建的 MCP 服务器作为子进程启动,针对真实后端练习每个工具,并将每个流程的工件写入 scripts/evals/artifacts/<timestamp>/。有关各个场景,请参阅 scripts/evals/flows/

MCP 注册:debugg-ai-local vs debugg-ai

此仓库附带一个 .mcp.json,注册一个名为 debugg-ai-local项目范围服务器,指向 node dist/index.js — 刚构建的本地代码。它仅在 Claude Code 的工作目录为此仓库时激活。

您的其他项目应使用用户范围debugg-ai 注册,从已发布的 npm 包中拉取:

npm run mcp:global      # registers debugg-ai in ~/.claude.json to npx -y @debugg-ai/debugg-ai-mcp

在此处编辑代码后,运行 npm run mcp:local(仅重新构建),以便下次调用 debugg-ai-local 时获取您的更改。

链接

仪表盘 · 文档 · 问题 · Discord


Apache-2.0 许可证 © 2025 DebuggAI