@ada-mcp/mcp-server 0.1.3 → 0.1.5
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 +32 -3
- package/dist/cli.cjs +1 -1
- package/package.json +4 -1
- package/scripts/preinstall-registry.mjs +70 -0
- package/scripts/registry-probe.mjs +76 -0
package/README.md
CHANGED
|
@@ -8,6 +8,14 @@ ADA MCP server package that supports:
|
|
|
8
8
|
|
|
9
9
|
## Run with pnpm(推荐,尤其 Windows)
|
|
10
10
|
|
|
11
|
+
**全程自动选最快镜像(推荐):**
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm dlx @ada-mcp/launcher
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
或直接(`0.1.5+` 在同次 dlx 安装依赖时 `preinstall` 测速):
|
|
18
|
+
|
|
11
19
|
```bash
|
|
12
20
|
pnpm dlx @ada-mcp/mcp-server
|
|
13
21
|
```
|
|
@@ -25,7 +33,6 @@ npx -y @ada-mcp/mcp-server
|
|
|
25
33
|
| 配置 | 含义 |
|
|
26
34
|
|------|------|
|
|
27
35
|
| (未配置) | 仅安装 **Playwright + 浏览器** |
|
|
28
|
-
| `playwright` | 同上 |
|
|
29
36
|
| `playwright` | 仅 Playwright(显式写法,与默认相同) |
|
|
30
37
|
| `selenium` | **仅** Selenium 原生驱动(GeckoDriver/ChromeDriver) |
|
|
31
38
|
| `appium` | **仅** Appium 包 + 移动端驱动 |
|
|
@@ -39,9 +46,28 @@ npx -y @ada-mcp/mcp-server
|
|
|
39
46
|
- `ADA_MCP_SKIP_INSTALL_DEPS=1`:跳过自动安装
|
|
40
47
|
- `ADA_MCP_INSTALL_DEPS_FORCE=1`:强制重装
|
|
41
48
|
- `ADA_MCP_GECKODRIVER_VERSION` / `ADA_MCP_CHROMEDRIVER_VERSION`:Selenium 驱动版本
|
|
42
|
-
- `ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS`:浏览器下载超时(默认 15
|
|
49
|
+
- `ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS`:浏览器下载超时(默认 15 分钟)
|
|
43
50
|
- `ADA_INSTALL_STRATEGY_TIMEOUT_MS`:npm 装包超时(默认 2 分钟)
|
|
44
51
|
|
|
52
|
+
## 代理与镜像(`0.1.3+`)
|
|
53
|
+
|
|
54
|
+
| 阶段 | 自动探测最快镜像 |
|
|
55
|
+
|------|------------------|
|
|
56
|
+
| `pnpm dlx @ada-mcp/launcher` | **是** — 拉包前测速(推荐) |
|
|
57
|
+
| `pnpm dlx @ada-mcp/mcp-server` | tarball 仍走本机源;**同次安装的依赖**由 `preinstall` 测速(0.1.5+) |
|
|
58
|
+
| 启动后 `install-deps` | 是 — 内置五家国内镜像测速(**无需配置**) |
|
|
59
|
+
|
|
60
|
+
默认 npm 探测候选(按优先级,延迟相同取靠前):阿里云 npmmirror → 腾讯云 → 清华 → 华为云 → 网易 → npm 官方。
|
|
61
|
+
|
|
62
|
+
| 变量 | 说明 |
|
|
63
|
+
|------|------|
|
|
64
|
+
| `npm_config_registry` | 可选;仅加速 **dlx** 拉包(推荐 `https://registry.npmmirror.com`) |
|
|
65
|
+
| `ADA_REGISTRY_CANDIDATES` | 可选;在默认五镜像**之外**追加候选 |
|
|
66
|
+
| `ADA_NPM_PROXY_REGISTRY` / `ADA_PNPM_PROXY_REGISTRY` | 可选;覆盖探测主候选(默认 npmmirror) |
|
|
67
|
+
| `PLAYWRIGHT_DOWNLOAD_HOST` | 可选;Playwright 浏览器 CDN |
|
|
68
|
+
|
|
69
|
+
详见 [ADA-MCP-接入手册 §3.9.2](../../docs/ADA-MCP-接入手册.md#392-代理与镜像配置)。
|
|
70
|
+
|
|
45
71
|
**CLI 参数**(写在 MCP `args` 末尾)
|
|
46
72
|
|
|
47
73
|
- `--install-deps=playwright,selenium`
|
|
@@ -87,7 +113,10 @@ npx -y @ada-mcp/mcp-server
|
|
|
87
113
|
"mcpServers": {
|
|
88
114
|
"ada-mcp": {
|
|
89
115
|
"command": "pnpm",
|
|
90
|
-
"args": ["dlx", "@ada-mcp/
|
|
116
|
+
"args": ["dlx", "@ada-mcp/launcher"]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
或 `["dlx", "@ada-mcp/mcp-server@0.1.5"]`(依赖安装走 preinstall 探测,无需 `npm_config_registry`)
|
|
91
120
|
}
|
|
92
121
|
}
|
|
93
122
|
}
|
package/dist/cli.cjs
CHANGED
|
@@ -6610,7 +6610,7 @@ var import_promises11 = __toESM(require("node:fs/promises"));
|
|
|
6610
6610
|
var import_node_path11 = __toESM(require("node:path"));
|
|
6611
6611
|
|
|
6612
6612
|
// src/bundled-config.generated.ts
|
|
6613
|
-
var bundledDefaultConfigYaml2 = 'agent:\r\n id: "ada-agent-local"\r\n mode: "foreground"\r\n setupOnFirstRun: true\r\n\r\nbootstrapUI:\r\n enabled: true\r\n mode: "auto" # auto | cli | gui\r\n host: "127.0.0.1"\r\n port: 17650\r\n autoOpenBrowser: true\r\n sessionTtlSec: 600\r\n secretsProvider: "auto" # auto | keychain | credman | file\r\n native:\r\n enabled: false\r\n command: "" # e.g. ./bootstrap-ui / .\\bootstrap-ui.exe\r\n args: []\r\n timeoutMs: 120000\r\n fallbackToWeb: true\r\n\r\ntransport:\r\n mode: "auto"\r\n streamProtocol: "websocket"\r\n requestPath: "/api/v1/execute"\r\n healthPath: "/health"\r\n streamPath: "/ws"\r\n requestTimeoutMs: 15000\r\n\r\ngraphics:\r\n enabled: false\r\n fallbackOnSemanticFailure: false\r\n minConfidence: 0.8\r\n\r\nmonitoring:\r\n enabled: false\r\n platforms: ["web", "android", "ios", "harmony"] # \u53EF\u9009\u5B50\u96C6\r\n sampleEvery: 1 # \u6BCF N \u6761\u64CD\u4F5C\u91C7\u6837\u4E00\u6B21\uFF0C1 \u8868\u793A\u5168\u91CF\r\n outputDir: "artifacts/monitoring"\r\n onFailureOnly: false # true \u65F6\u4EC5\u5931\u8D25\u64CD\u4F5C\u6293\u56FE\uFF0C\u6027\u80FD\u66F4\u4F18\r\n groupBySession: true # \u6309 sessionId/requestId \u5206\u5C42\u5F52\u6863\r\n nonBlocking: true # true \u65F6\u76D1\u63A7\u5F02\u6B65\u6267\u884C\uFF0C\u4E0D\u963B\u585E\u4E3B\u94FE\u8DEF\r\n resolution:\r\n maxWidth: 1280\r\n maxHeight: 720\r\n keepAspectRatio: true # \u4FDD\u6301\u6BD4\u4F8B\uFF0C\u907F\u514D\u76D1\u63A7\u56FE\u50CF\u53D8\u5F62\r\n\r\nqueue:\r\n inboxDir: "tasks/inbox"\r\n processedDir: "tasks/processed"\r\n failedDir: "tasks/failed"\r\n pollIntervalMs: 3000\r\n maxFileRetryAttempts: 2\r\n\r\ndependencies:\r\n autoInstallOnStart: true\r\n playwrightBrowser: "chromium" # chromium | firefox | webkit | all\r\n playwrightInstallTargets: ["chrome"] # chromium | chrome | msedge | firefox | webkit | all\r\n playwrightDownloadHost: "https://npmmirror.com/mirrors/playwright"\r\n npmRegistryCandidates:\r\n - "https://registry.npmmirror.com"\r\n - "https://mirrors.cloud.tencent.com/npm"\r\n - "https://repo.huaweicloud.com/repository/npm"\r\n - "https://registry.npmjs.org"\r\n playwrightHostCandidates:\r\n - "https://npmmirror.com/mirrors/playwright"\r\n - "https://playwright.azureedge.net"\r\n # \u539F\u751F WebDriver\uFF08geckodriver / chromedriver\uFF09\u7EDF\u4E00\u653E\u5728\u9879\u76EE dirver \u76EE\u5F55\r\n nativeDriversDir: "dirver"\r\n geckodriverVersion: "latest" # \u5982 0.36.0\uFF1Binstall-deps --only=selenium \u65F6\u4E0B\u8F7D\u5230\u6B64\u76EE\u5F55\r\n chromedriverVersion: "latest" # \u5982 137\u3001135\u3001match-chrome\uFF08\u5339\u914D\u672C\u673A Chrome \u4E3B\u7248\u672C\uFF09\r\n\r\nappium:\r\n serverUrl: "http://127.0.0.1:4723"\r\n requiredDrivers: ["uiautomator2", "xcuitest", "harmonyos"]\r\n';
|
|
6613
|
+
var bundledDefaultConfigYaml2 = 'agent:\r\n id: "ada-agent-local"\r\n mode: "foreground"\r\n setupOnFirstRun: true\r\n\r\nbootstrapUI:\r\n enabled: true\r\n mode: "auto" # auto | cli | gui\r\n host: "127.0.0.1"\r\n port: 17650\r\n autoOpenBrowser: true\r\n sessionTtlSec: 600\r\n secretsProvider: "auto" # auto | keychain | credman | file\r\n native:\r\n enabled: false\r\n command: "" # e.g. ./bootstrap-ui / .\\bootstrap-ui.exe\r\n args: []\r\n timeoutMs: 120000\r\n fallbackToWeb: true\r\n\r\ntransport:\r\n mode: "auto"\r\n streamProtocol: "websocket"\r\n requestPath: "/api/v1/execute"\r\n healthPath: "/health"\r\n streamPath: "/ws"\r\n requestTimeoutMs: 15000\r\n\r\ngraphics:\r\n enabled: false\r\n fallbackOnSemanticFailure: false\r\n minConfidence: 0.8\r\n\r\nmonitoring:\r\n enabled: false\r\n platforms: ["web", "android", "ios", "harmony"] # \u53EF\u9009\u5B50\u96C6\r\n sampleEvery: 1 # \u6BCF N \u6761\u64CD\u4F5C\u91C7\u6837\u4E00\u6B21\uFF0C1 \u8868\u793A\u5168\u91CF\r\n outputDir: "artifacts/monitoring"\r\n onFailureOnly: false # true \u65F6\u4EC5\u5931\u8D25\u64CD\u4F5C\u6293\u56FE\uFF0C\u6027\u80FD\u66F4\u4F18\r\n groupBySession: true # \u6309 sessionId/requestId \u5206\u5C42\u5F52\u6863\r\n nonBlocking: true # true \u65F6\u76D1\u63A7\u5F02\u6B65\u6267\u884C\uFF0C\u4E0D\u963B\u585E\u4E3B\u94FE\u8DEF\r\n resolution:\r\n maxWidth: 1280\r\n maxHeight: 720\r\n keepAspectRatio: true # \u4FDD\u6301\u6BD4\u4F8B\uFF0C\u907F\u514D\u76D1\u63A7\u56FE\u50CF\u53D8\u5F62\r\n\r\nqueue:\r\n inboxDir: "tasks/inbox"\r\n processedDir: "tasks/processed"\r\n failedDir: "tasks/failed"\r\n pollIntervalMs: 3000\r\n maxFileRetryAttempts: 2\r\n\r\ndependencies:\r\n autoInstallOnStart: true\r\n playwrightBrowser: "chromium" # chromium | firefox | webkit | all\r\n playwrightInstallTargets: ["chrome"] # chromium | chrome | msedge | firefox | webkit | all\r\n playwrightDownloadHost: "https://npmmirror.com/mirrors/playwright"\r\n # \u56FD\u5185 npm \u955C\u50CF\uFF08\u6309\u4F18\u5148\u7EA7\uFF1Binstall-deps \u542F\u52A8\u65F6\u6D4B\u901F\u9009\u6700\u5FEB\uFF0C\u65E0\u9700\u7528\u6237\u914D\u7F6E\uFF09\r\n npmRegistryCandidates:\r\n - "https://registry.npmmirror.com" # \u963F\u91CC\u4E91 / npmmirror\uFF08\u63A8\u8350\uFF09\r\n - "https://mirrors.cloud.tencent.com/npm" # \u817E\u8BAF\u4E91\r\n - "https://mirrors.tuna.tsinghua.edu.cn/npm" # \u6E05\u534E\u5927\u5B66\r\n - "https://repo.huaweicloud.com/repository/npm" # \u534E\u4E3A\u4E91\r\n - "https://mirrors.163.com/npm" # \u7F51\u6613\r\n - "https://registry.npmjs.org" # \u5B98\u65B9\u515C\u5E95\r\n playwrightHostCandidates:\r\n - "https://npmmirror.com/mirrors/playwright"\r\n - "https://playwright.azureedge.net"\r\n # \u539F\u751F WebDriver\uFF08geckodriver / chromedriver\uFF09\u7EDF\u4E00\u653E\u5728\u9879\u76EE dirver \u76EE\u5F55\r\n nativeDriversDir: "dirver"\r\n geckodriverVersion: "latest" # \u5982 0.36.0\uFF1Binstall-deps --only=selenium \u65F6\u4E0B\u8F7D\u5230\u6B64\u76EE\u5F55\r\n chromedriverVersion: "latest" # \u5982 137\u3001135\u3001match-chrome\uFF08\u5339\u914D\u672C\u673A Chrome \u4E3B\u7248\u672C\uFF09\r\n\r\nappium:\r\n serverUrl: "http://127.0.0.1:4723"\r\n requiredDrivers: ["uiautomator2", "xcuitest", "harmonyos"]\r\n';
|
|
6614
6614
|
|
|
6615
6615
|
// src/config.ts
|
|
6616
6616
|
var DEFAULT_CONFIG_RELATIVE2 = import_node_path11.default.join("config", "default.yaml");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ada-mcp/mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "ADA MCP server for web/mobile automation (stdio + remote HTTP)",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "commonjs",
|
|
@@ -12,9 +12,12 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"dist/cli.cjs",
|
|
14
14
|
"plugins",
|
|
15
|
+
"scripts/preinstall-registry.mjs",
|
|
16
|
+
"scripts/registry-probe.mjs",
|
|
15
17
|
"README.md"
|
|
16
18
|
],
|
|
17
19
|
"scripts": {
|
|
20
|
+
"preinstall": "node scripts/preinstall-registry.mjs",
|
|
18
21
|
"dev": "tsx src/cli.ts",
|
|
19
22
|
"prebuild": "node ../../scripts/generate-bundled-config.mjs",
|
|
20
23
|
"build": "tsc -p tsconfig.json",
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* pnpm dlx / npm install 本包时:在安装 dependencies 之前测速并写入 .npmrc,
|
|
4
|
+
* 使同一次安装中的 playwright 等依赖走最快 registry。
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { detectBestRegistry, registryCandidateList } from "./registry-probe.mjs";
|
|
9
|
+
|
|
10
|
+
function installRoot() {
|
|
11
|
+
const init = process.env.INIT_CWD?.trim();
|
|
12
|
+
if (init && fs.existsSync(init)) {
|
|
13
|
+
return init;
|
|
14
|
+
}
|
|
15
|
+
return process.cwd();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function shouldRunProbe() {
|
|
19
|
+
if (process.env.ADA_MCP_SKIP_REGISTRY_PROBE === "1") {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (process.env.ADA_MCP_FORCE_PREINSTALL_PROBE === "1") {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
const init = (process.env.INIT_CWD || "").replace(/\\/g, "/");
|
|
26
|
+
if (/[\\/]dlx[\\/]/.test(init) || init.includes("__npx")) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
if (init) {
|
|
30
|
+
try {
|
|
31
|
+
if (fs.existsSync(path.join(init, "pnpm-workspace.yaml"))) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
// ignore
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return init.length > 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function main() {
|
|
42
|
+
if (!shouldRunProbe()) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const root = installRoot();
|
|
46
|
+
const candidates = registryCandidateList();
|
|
47
|
+
const { best, probeResults } = await detectBestRegistry(candidates);
|
|
48
|
+
const npmrcPath = path.join(root, ".npmrc");
|
|
49
|
+
const line = `registry=${best}\n`;
|
|
50
|
+
let existing = "";
|
|
51
|
+
try {
|
|
52
|
+
existing = fs.readFileSync(npmrcPath, "utf8");
|
|
53
|
+
} catch {
|
|
54
|
+
// new file
|
|
55
|
+
}
|
|
56
|
+
if (!existing.includes(`registry=${best}`)) {
|
|
57
|
+
fs.writeFileSync(npmrcPath, `${existing}${line}`, "utf8");
|
|
58
|
+
}
|
|
59
|
+
console.error(
|
|
60
|
+
`[ada-mcp preinstall] registry probe: selected ${best} (candidates: ${candidates.join(", ")})`
|
|
61
|
+
);
|
|
62
|
+
for (const { candidate, latency } of probeResults) {
|
|
63
|
+
console.error(`[ada-mcp preinstall] ${candidate} -> ${latency === null ? "fail" : `${latency}ms`}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
main().catch((error) => {
|
|
68
|
+
console.error("[ada-mcp preinstall] registry probe failed:", error);
|
|
69
|
+
process.exit(0);
|
|
70
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 零依赖 npm registry 测速(供 preinstall / launcher 共用)
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_NPM_REGISTRY_CANDIDATES = [
|
|
5
|
+
"https://registry.npmmirror.com",
|
|
6
|
+
"https://mirrors.cloud.tencent.com/npm",
|
|
7
|
+
"https://mirrors.tuna.tsinghua.edu.cn/npm",
|
|
8
|
+
"https://repo.huaweicloud.com/repository/npm",
|
|
9
|
+
"https://mirrors.163.com/npm",
|
|
10
|
+
"https://registry.npmjs.org"
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
function normalizeRegistryUrl(url) {
|
|
14
|
+
return String(url).replace(/\/$/, "");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function registryCandidateList(extraEnv) {
|
|
18
|
+
const primary = normalizeRegistryUrl(
|
|
19
|
+
process.env.ADA_NPM_PROXY_REGISTRY?.trim() || DEFAULT_NPM_REGISTRY_CANDIDATES[0]
|
|
20
|
+
);
|
|
21
|
+
const extra = extraEnv?.trim()
|
|
22
|
+
? extraEnv.split(",").map((x) => normalizeRegistryUrl(x.trim())).filter(Boolean)
|
|
23
|
+
: process.env.ADA_REGISTRY_CANDIDATES?.trim()
|
|
24
|
+
? process.env.ADA_REGISTRY_CANDIDATES.split(",").map((x) => normalizeRegistryUrl(x.trim())).filter(Boolean)
|
|
25
|
+
: [];
|
|
26
|
+
const ordered = [primary, ...DEFAULT_NPM_REGISTRY_CANDIDATES, ...extra];
|
|
27
|
+
const seen = new Set();
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const url of ordered) {
|
|
30
|
+
const n = normalizeRegistryUrl(url);
|
|
31
|
+
if (!seen.has(n)) {
|
|
32
|
+
seen.add(n);
|
|
33
|
+
out.push(n);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function probeRegistryLatency(registry) {
|
|
40
|
+
const target = `${normalizeRegistryUrl(registry)}/appium`;
|
|
41
|
+
const started = Date.now();
|
|
42
|
+
const controller = new AbortController();
|
|
43
|
+
const timer = setTimeout(() => controller.abort(), 5000);
|
|
44
|
+
try {
|
|
45
|
+
const response = await fetch(target, { method: "GET", signal: controller.signal });
|
|
46
|
+
if (!response.ok) return null;
|
|
47
|
+
return Date.now() - started;
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
} finally {
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function detectBestRegistry(candidates = registryCandidateList()) {
|
|
56
|
+
const probeResults = await Promise.all(
|
|
57
|
+
candidates.map(async (candidate) => ({
|
|
58
|
+
candidate,
|
|
59
|
+
latency: await probeRegistryLatency(candidate)
|
|
60
|
+
}))
|
|
61
|
+
);
|
|
62
|
+
let best = candidates[0] ?? DEFAULT_NPM_REGISTRY_CANDIDATES[0];
|
|
63
|
+
let bestLatency = Number.POSITIVE_INFINITY;
|
|
64
|
+
let bestPriority = Number.POSITIVE_INFINITY;
|
|
65
|
+
for (const { candidate, latency } of probeResults) {
|
|
66
|
+
if (latency === null) continue;
|
|
67
|
+
const priority = candidates.indexOf(candidate);
|
|
68
|
+
const prio = priority >= 0 ? priority : Number.POSITIVE_INFINITY;
|
|
69
|
+
if (latency < bestLatency || (latency === bestLatency && prio < bestPriority)) {
|
|
70
|
+
best = candidate;
|
|
71
|
+
bestLatency = latency;
|
|
72
|
+
bestPriority = prio;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { best: normalizeRegistryUrl(best), candidates, probeResults };
|
|
76
|
+
}
|