@attson/atwebpilot-mcp 0.0.71 → 0.0.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -4
- package/dist/index.js +41 -14
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -49,8 +49,8 @@ listen 端口的能力,所以方向只能如此。这也是配对页存在的
|
|
|
49
49
|
## 工具面
|
|
50
50
|
|
|
51
51
|
- 控制面 4 个:`list_tabs / open_session / close_session / get_quota`
|
|
52
|
-
- 发现 1 个:`browser_discoverTools` ——
|
|
53
|
-
- 执行面默认 **core
|
|
52
|
+
- 发现 1 个:`browser_discoverTools` —— 已知工具时直接传 `enable: [...]`,已知分组时直接传 `enableGroups: ["export", ...]`;只有两者都未知时才不带参数读取目录。启用后会加入本进程的 `tools/list`(发送 `tools/list_changed`),并直接返回完整 schema。
|
|
53
|
+
- 执行面默认 **core 31 个** `browser_*`:浏览 / 采集 / 填表 / 导航 / 截图 闭环所需的工具。其余 20 个由 AI 按需 `discoverTools` 拉取,用户不用配置。
|
|
54
54
|
- 不暴露 `askUser`(MCP 会话没有人在侧边栏应答)和 `attachTab` / `detachTab`(目标 tab 已由 `open_session` 绑定)。
|
|
55
55
|
|
|
56
56
|
MCP 层的描述是精简英文(≈2.5k tokens for core),侧边栏内置 LLM 仍用中文长描述;两者共享同一份 `TOOL_DEFS`,靠 `mcp` 字段区分。
|
|
@@ -65,11 +65,25 @@ hover / uploadFile / scroll / waitFor`);`browser_storage` 也不会列出,
|
|
|
65
65
|
|
|
66
66
|
| 值 | 效果 |
|
|
67
67
|
|---|---|
|
|
68
|
-
| `core`(默认) |
|
|
68
|
+
| `core`(默认) | 31 个核心工具 + `browser_discoverTools`,其余按需发现 |
|
|
69
69
|
| `full` | 一开始就全部列出(51 个),适合不想让 AI 多一步发现的用户 |
|
|
70
70
|
|
|
71
71
|
无法识别的值(包括已移除的 `parity`)按 `core` 处理,并往 stderr 打一条提示。
|
|
72
72
|
|
|
73
|
+
## 本地会话效率分析
|
|
74
|
+
|
|
75
|
+
在仓库根目录运行:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pnpm analyze:sessions
|
|
79
|
+
pnpm analyze:sessions -- --since 7d --clients claude --format json
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
分析器只读扫描 `~/.claude/projects` 与 `~/.codex/sessions` 中最近 30 天的
|
|
83
|
+
JSONL,识别真实 AtWebPilot 工具调用及重复验证、固定等待、重复截图、可批量填表等
|
|
84
|
+
模式。输出只包含聚合计数、参数字段名与不可逆指纹;不会输出或保存 prompt、参数值、
|
|
85
|
+
工具结果正文、凭证或绝对会话路径。使用 `--help` 查看目录覆盖等选项。
|
|
86
|
+
|
|
73
87
|
### 从 0.0.70 及更早版本迁移
|
|
74
88
|
|
|
75
89
|
| 旧 | 新 |
|
|
@@ -95,7 +109,7 @@ hover / uploadFile / scroll / waitFor`);`browser_storage` 也不会列出,
|
|
|
95
109
|
| `browser_drag` / `browser_drop` | `browser_drag` / `browser_drop` |
|
|
96
110
|
| `browser_file_upload` | `browser_uploadFile` |
|
|
97
111
|
| `browser_navigate` / `browser_navigate_back` | `browser_navigate`(`action` 取 `goto` / `back` / `forward` / `reload`) |
|
|
98
|
-
| `browser_tabs` | `browser_listTabs` / `openTab` / `closeTab
|
|
112
|
+
| `browser_tabs` | `browser_listTabs` / `openTab` / `closeTab`; `switchToTab` 需按需发现,仅用于用户明确要求前台切换 |
|
|
99
113
|
| `browser_close` | `browser_closeTab` |
|
|
100
114
|
| `browser_resize` | `browser_resize` |
|
|
101
115
|
| `browser_take_screenshot` | `browser_screenshot`(含 `fullPage` / `format` / `scale`) |
|
package/dist/index.js
CHANGED
|
@@ -1425,7 +1425,9 @@ var TOOL_DEFS = [
|
|
|
1425
1425
|
{
|
|
1426
1426
|
name: "switchToTab",
|
|
1427
1427
|
description: "[META] \u628A Chrome \u524D\u53F0\u5207\u5230\u76EE\u6807 tab\u3002tabId \u5FC5\u987B\u5DF2\u5728 attachedTabs \u6216\u5F53\u524D tab\u3002",
|
|
1428
|
-
mcp: {
|
|
1428
|
+
mcp: {
|
|
1429
|
+
description: "Bring the session's tab and Chrome window to the foreground. Use only when the user explicitly asks to see that tab; all other browser tools already operate on the session-bound tab without this setup step."
|
|
1430
|
+
},
|
|
1429
1431
|
input_schema: {
|
|
1430
1432
|
type: "object",
|
|
1431
1433
|
properties: { tabId: { type: "integer" } },
|
|
@@ -1437,7 +1439,7 @@ var TOOL_DEFS = [
|
|
|
1437
1439
|
name: "screenshot",
|
|
1438
1440
|
description: "[VISION] \u622A\u5F53\u524D tab \u53EF\u89C1\u533A\u57DF\u4E3A PNG\uFF08\u81EA\u52A8\u4F5C\u4E3A image block \u6CE8\u5165\u4E0B\u8F6E\uFF09\u3002\u7528\u4E8E\u89C6\u89C9\u8C03\u8BD5\u3001\u770B\u56FE\u56DE\u7B54\u3001\u6838\u5BF9 page-index \u8BC1\u636E\u3002\n\u5982\u679C\u5DF2\u6709 searchPageIndex/extractPageFields \u8FD4\u56DE\u7684 blockId/indexId\uFF0C\u4F18\u5148\u4F20 {blockId,indexId}\uFF1B\u5DE5\u5177\u4F1A\u6EDA\u52A8\u5E76\u9AD8\u4EAE\u8BE5\u5C40\u90E8\u533A\u57DF\u540E\u622A\u56FE\u3002\u4E5F\u53EF\u4F20 selector\u3002",
|
|
1439
1441
|
mcp: {
|
|
1440
|
-
description: "PNG/JPEG
|
|
1442
|
+
description: "PNG/JPEG returned as an image block. With opt-in CDP enabled, captures viewport/fullPage/selector in the background without activating or scrolling the tab; compatibility mode may temporarily activate the tab.",
|
|
1441
1443
|
params: { blockId: "page-index blockId to frame", indexId: "indexId that produced blockId", scale: "0.1\u20131; smaller saves tokens" }
|
|
1442
1444
|
},
|
|
1443
1445
|
input_schema: {
|
|
@@ -1828,7 +1830,7 @@ var TOOL_DEFS = [
|
|
|
1828
1830
|
{
|
|
1829
1831
|
name: "resize",
|
|
1830
1832
|
description: "[FLOW] \u628A\u89C6\u53E3\u8C03\u6574\u5230\u6307\u5B9A\u5C3A\u5BF8\u3002main-world \u6863\u91CF\u53D6 outerWidth-innerWidth \u53CD\u63A8\u6D4F\u89C8\u5668\u8FB9\u6846\u540E\u6539\u7A97\u53E3\u5916\u6846\uFF0C\u89C6\u53E3\u7CBE\u786E\u4F46**\u7528\u6237\u7684\u7A97\u53E3\u4F1A\u771F\u7684\u53D8\u5927\u5C0F**\uFF1Bcdp \u6863\u7528 Emulation \u8986\u76D6\u8BBE\u5907\u5C3A\u5BF8\uFF0C\u4E0D\u52A8\u771F\u5B9E\u7A97\u53E3\u3002",
|
|
1831
|
-
mcp: { description: "Resize the viewport to width\xD7height." },
|
|
1833
|
+
mcp: { description: "Resize the viewport to width\xD7height and return the measured actualViewport plus verified status. Do not re-measure with runJS." },
|
|
1832
1834
|
input_schema: {
|
|
1833
1835
|
type: "object",
|
|
1834
1836
|
properties: {
|
|
@@ -1927,7 +1929,6 @@ var CORE_TOOLS = [
|
|
|
1927
1929
|
"listTabs",
|
|
1928
1930
|
"openTab",
|
|
1929
1931
|
"closeTab",
|
|
1930
|
-
"switchToTab",
|
|
1931
1932
|
"resize",
|
|
1932
1933
|
"scroll",
|
|
1933
1934
|
// observation
|
|
@@ -2072,7 +2073,8 @@ var DISCOVERABLE_GROUPS = {
|
|
|
2072
2073
|
"browser-data": ["browser_searchBookmarks", "browser_searchHistory"],
|
|
2073
2074
|
inspect: ["browser_inspectElement", "browser_highlight", "browser_getValue", "browser_extractFormState"],
|
|
2074
2075
|
"legacy-dom": ["browser_snapshotDOM", "browser_querySelector", "browser_querySelectorAll", "browser_extractImages", "browser_focus"],
|
|
2075
|
-
form: ["browser_submitForm"]
|
|
2076
|
+
form: ["browser_submitForm"],
|
|
2077
|
+
tabs: ["browser_switchToTab"]
|
|
2076
2078
|
};
|
|
2077
2079
|
var GROUP_BY_NAME = new Map(
|
|
2078
2080
|
Object.entries(DISCOVERABLE_GROUPS).flatMap(([g, names]) => names.map((n) => [n, g]))
|
|
@@ -2085,13 +2087,19 @@ function discoveryCatalog(all, advertised) {
|
|
|
2085
2087
|
}
|
|
2086
2088
|
|
|
2087
2089
|
// src/discover-tool.ts
|
|
2090
|
+
var DISCOVER_GROUPS = Object.keys(DISCOVERABLE_GROUPS);
|
|
2088
2091
|
var DISCOVER_TOOL = {
|
|
2089
2092
|
name: "browser_discoverTools",
|
|
2090
|
-
description: "The default tool list is the core set.
|
|
2093
|
+
description: "The default tool list is the core set. Enable known extras directly with enable=[names] or enableGroups=[groups]. Omit both only when you need the catalog. Groups: export, network, storage, browser-data, inspect, legacy-dom, form, tabs. Enabled tools join tools/list and the response includes their full schemas so you can call them immediately. Use this instead of rebuilding missing capabilities with runJS.",
|
|
2091
2094
|
inputSchema: {
|
|
2092
2095
|
type: "object",
|
|
2093
2096
|
properties: {
|
|
2094
|
-
enable: { type: "array", items: { type: "string" }, description: "Tool names from the catalog to advertise" }
|
|
2097
|
+
enable: { type: "array", items: { type: "string" }, description: "Tool names from the catalog to advertise" },
|
|
2098
|
+
enableGroups: {
|
|
2099
|
+
type: "array",
|
|
2100
|
+
items: { type: "string", enum: DISCOVER_GROUPS },
|
|
2101
|
+
description: "Known groups to advertise directly, without a catalog round trip"
|
|
2102
|
+
}
|
|
2095
2103
|
},
|
|
2096
2104
|
additionalProperties: false
|
|
2097
2105
|
}
|
|
@@ -2102,23 +2110,36 @@ function isRunnable(t, supported) {
|
|
|
2102
2110
|
function handleDiscover(input) {
|
|
2103
2111
|
const { all, advertised, args, supported } = input;
|
|
2104
2112
|
const byName = new Map(all.map((t) => [t.name, t]));
|
|
2105
|
-
const
|
|
2106
|
-
if (!
|
|
2113
|
+
const hasSelection = Array.isArray(args.enable) || Array.isArray(args.enableGroups);
|
|
2114
|
+
if (!hasSelection) {
|
|
2107
2115
|
const runnable = all.filter((t) => isRunnable(t, supported));
|
|
2108
2116
|
return { catalog: discoveryCatalog(runnable, advertised), changed: false };
|
|
2109
2117
|
}
|
|
2118
|
+
const explicit = Array.isArray(args.enable) ? args.enable.map(String) : [];
|
|
2119
|
+
const groups = Array.isArray(args.enableGroups) ? args.enableGroups.map(String) : [];
|
|
2120
|
+
const unknownGroups = groups.filter((group) => !DISCOVER_GROUPS.includes(group));
|
|
2121
|
+
const grouped = groups.flatMap(
|
|
2122
|
+
(group) => DISCOVERABLE_GROUPS[group] ?? []
|
|
2123
|
+
);
|
|
2124
|
+
const requestedByName = /* @__PURE__ */ new Map();
|
|
2125
|
+
for (const raw of explicit) {
|
|
2126
|
+
const name = raw.startsWith("browser_") ? raw : `browser_${raw}`;
|
|
2127
|
+
requestedByName.set(name, raw);
|
|
2128
|
+
}
|
|
2129
|
+
for (const name of grouped) {
|
|
2130
|
+
if (!requestedByName.has(name)) requestedByName.set(name, name);
|
|
2131
|
+
}
|
|
2110
2132
|
const enabled = [];
|
|
2111
2133
|
const unknown = [];
|
|
2112
2134
|
const unsupported = [];
|
|
2113
|
-
for (const
|
|
2114
|
-
const name = raw.startsWith("browser_") ? raw : `browser_${raw}`;
|
|
2135
|
+
for (const [name, reportAs] of requestedByName) {
|
|
2115
2136
|
const t = byName.get(name);
|
|
2116
2137
|
if (!t) {
|
|
2117
|
-
unknown.push(
|
|
2138
|
+
unknown.push(reportAs);
|
|
2118
2139
|
continue;
|
|
2119
2140
|
}
|
|
2120
2141
|
if (!isRunnable(t, supported)) {
|
|
2121
|
-
unsupported.push(
|
|
2142
|
+
unsupported.push(reportAs);
|
|
2122
2143
|
continue;
|
|
2123
2144
|
}
|
|
2124
2145
|
if (advertised.has(name)) continue;
|
|
@@ -2128,6 +2149,7 @@ function handleDiscover(input) {
|
|
|
2128
2149
|
return {
|
|
2129
2150
|
enabled,
|
|
2130
2151
|
...unknown.length ? { unknown } : {},
|
|
2152
|
+
...unknownGroups.length ? { unknownGroups } : {},
|
|
2131
2153
|
...unsupported.length ? { unsupported } : {},
|
|
2132
2154
|
changed: enabled.length > 0
|
|
2133
2155
|
};
|
|
@@ -2432,7 +2454,12 @@ function toolResult(gen, data) {
|
|
|
2432
2454
|
const d = data ?? {};
|
|
2433
2455
|
if (typeof d.data !== "string") return ok(data);
|
|
2434
2456
|
const mimeType = typeof d.media_type === "string" ? d.media_type : "image/png";
|
|
2435
|
-
|
|
2457
|
+
const { data: imageData, media_type: _mediaType, ...metadata } = d;
|
|
2458
|
+
const content = [{ type: "image", data: imageData, mimeType }];
|
|
2459
|
+
if (Object.keys(metadata).length > 0) {
|
|
2460
|
+
content.push({ type: "text", text: JSON.stringify(metadata) });
|
|
2461
|
+
}
|
|
2462
|
+
return { content };
|
|
2436
2463
|
}
|
|
2437
2464
|
var fail2 = (message) => ({ content: [{ type: "text", text: message }], isError: true });
|
|
2438
2465
|
async function dispatchCall(deps, name, args, onPairingRequired, state = DEFAULT_STATE, onListChanged) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@attson/atwebpilot-mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.73",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "MCP server for the atwebpilot browser extension - let Codex or Claude Code drive your browser.",
|
|
6
6
|
"homepage": "https://github.com/attson/atwebpilot#readme",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"typecheck": "tsc --noEmit",
|
|
28
28
|
"test": "vitest run",
|
|
29
29
|
"build": "tsup",
|
|
30
|
-
"start": "tsx src/index.ts"
|
|
30
|
+
"start": "tsx src/index.ts",
|
|
31
|
+
"analyze:sessions": "tsx src/session-analysis/cli.ts"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@modelcontextprotocol/sdk": "^1.0.0",
|