@opentiny/webmcp-cli 0.0.9 → 0.1.0

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 CHANGED
@@ -44,6 +44,7 @@ CI 中浏览器任务使用 [browser-actions/setup-chrome](https://github.com/br
44
44
 
45
45
  全局命令为 **`webmcp-cli`**,支持全局参数:
46
46
  - `-w, --workspace <path>`: 指定自定义的浏览器工作空间(用户配置目录)路径。如果不传默认使用 `~/.webmcp_chrome_profile`。
47
+ - `--ignore-certificate-errors`: 关闭受控 Chrome 的 HTTPS 证书校验,用于打开自签名、过期或主机名不匹配的站点。也可设置环境变量 `WEBMCP_IGNORE_CERTIFICATE_ERRORS=1`。默认仍校验证书。仅 CDP 模式有效。该设置作用于当前受控浏览器进程,直到进程退出;重启后需要再次传入。打开时会在 stderr 提示「当前受控浏览器已关闭 TLS 证书校验。」
47
48
 
48
49
  ---
49
50
 
package/dist/bin.cjs CHANGED
@@ -46,6 +46,38 @@ function shouldLaunchHeadless() {
46
46
  if (process.env.WEBMCP_HEADLESS === "0") return false;
47
47
  return process.env.WEBMCP_HEADLESS === "1" || process.env.CI === "true" || process.env.CI === "1";
48
48
  }
49
+ function shouldIgnoreCertificateErrors() {
50
+ return process.env.WEBMCP_IGNORE_CERTIFICATE_ERRORS === "1";
51
+ }
52
+ function buildChromeLaunchArgs(input) {
53
+ const launchArgs = [
54
+ `--remote-debugging-port=${input.cdpPort}`,
55
+ `--user-data-dir=${input.userDataDir}`,
56
+ "--no-first-run",
57
+ "--no-default-browser-check"
58
+ ];
59
+ if (input.headless) {
60
+ launchArgs.push(
61
+ "--headless=new",
62
+ "--no-sandbox",
63
+ "--disable-setuid-sandbox",
64
+ "--disable-gpu",
65
+ "--disable-dev-shm-usage"
66
+ );
67
+ }
68
+ const ignoreCertificateErrors = input.ignoreCertificateErrors ?? shouldIgnoreCertificateErrors();
69
+ if (ignoreCertificateErrors) {
70
+ launchArgs.push("--ignore-certificate-errors");
71
+ }
72
+ return launchArgs;
73
+ }
74
+ function buildPuppeteerConnectOptions(browserBaseUrl) {
75
+ return {
76
+ browserURL: browserBaseUrl,
77
+ defaultViewport: null,
78
+ ...shouldIgnoreCertificateErrors() ? { ignoreHTTPSErrors: true } : {}
79
+ };
80
+ }
49
81
  function readActivePortFromProfile(userDataDir) {
50
82
  try {
51
83
  const content = import_fs2.default.readFileSync(import_path2.default.join(userDataDir, "DevToolsActivePort"), "utf-8");
@@ -140,7 +172,7 @@ async function findAvailableCdpUrl(addresses, retries = 2) {
140
172
  async function connectPuppeteer(browserBaseUrl, attempt = 1, maxAttempts = 3) {
141
173
  try {
142
174
  return await promiseWithTimeout(
143
- import_puppeteer_core.default.connect({ browserURL: browserBaseUrl, defaultViewport: null }),
175
+ import_puppeteer_core.default.connect(buildPuppeteerConnectOptions(browserBaseUrl)),
144
176
  1e4,
145
177
  `puppeteer.connect to ${browserBaseUrl} timed out`
146
178
  );
@@ -215,21 +247,11 @@ async function startBrowserInBackground() {
215
247
  import_fs2.default.unlinkSync(import_path2.default.join(userDataDir, "DevToolsActivePort"));
216
248
  } catch {
217
249
  }
218
- const launchArgs = [
219
- `--remote-debugging-port=${cdpPort}`,
220
- `--user-data-dir=${userDataDir}`,
221
- "--no-first-run",
222
- "--no-default-browser-check"
223
- ];
224
- if (shouldLaunchHeadless()) {
225
- launchArgs.push(
226
- "--headless=new",
227
- "--no-sandbox",
228
- "--disable-setuid-sandbox",
229
- "--disable-gpu",
230
- "--disable-dev-shm-usage"
231
- );
232
- }
250
+ const launchArgs = buildChromeLaunchArgs({
251
+ cdpPort,
252
+ userDataDir,
253
+ headless: shouldLaunchHeadless()
254
+ });
233
255
  const child = (0, import_child_process.spawn)(
234
256
  browserInfo.path,
235
257
  launchArgs,
@@ -526,7 +548,7 @@ var init_package = __esm({
526
548
  "package.json"() {
527
549
  package_default = {
528
550
  name: "@opentiny/webmcp-cli",
529
- version: "0.0.9",
551
+ version: "0.1.0",
530
552
  type: "module",
531
553
  description: "WebMCP CLI for AI Agents to interact with browser via Puppeteer",
532
554
  main: "dist/index.js",
@@ -3568,11 +3590,20 @@ function handleCommandError(error, commandName, args) {
3568
3590
  }
3569
3591
  program.name("webmcp-cli").description(
3570
3592
  "WebMCP CLI \u2014 \u652F\u6301\u4E24\u79CD\u6D4F\u89C8\u5668\u8FDE\u63A5\u6A21\u5F0F\uFF1A\n --mode cdp\uFF08\u9ED8\u8BA4\uFF09: \u57FA\u4E8E Puppeteer + CDP \u76F4\u8FDE\u6D4F\u89C8\u5668\uFF08\u72EC\u7ACB profile\uFF09\n --mode wxt : \u57FA\u4E8E WebSocket + Chrome \u6269\u5C55\u6865\u63A5\uFF08\u590D\u7528\u7528\u6237\u6570\u636E\uFF09"
3571
- ).version(package_default.version).option("-w, --workspace <path>", "\u6307\u5B9A\u81EA\u5B9A\u4E49\u7684\u6D4F\u89C8\u5668\u5DE5\u4F5C\u7A7A\u95F4\uFF08\u7528\u6237\u914D\u7F6E\u76EE\u5F55\uFF09\u8DEF\u5F84\uFF0C\u4EC5 CDP \u6A21\u5F0F\u6709\u6548").hook("preAction", (thisCommand) => {
3593
+ ).version(package_default.version).option("-w, --workspace <path>", "\u6307\u5B9A\u81EA\u5B9A\u4E49\u7684\u6D4F\u89C8\u5668\u5DE5\u4F5C\u7A7A\u95F4\uFF08\u7528\u6237\u914D\u7F6E\u76EE\u5F55\uFF09\u8DEF\u5F84\uFF0C\u4EC5 CDP \u6A21\u5F0F\u6709\u6548").option(
3594
+ "--ignore-certificate-errors",
3595
+ "\u5173\u95ED\u53D7\u63A7\u6D4F\u89C8\u5668\u7684 HTTPS \u8BC1\u4E66\u6821\u9A8C\uFF08\u81EA\u7B7E\u540D\u3001\u8FC7\u671F\u6216\u4E3B\u673A\u540D\u4E0D\u5339\u914D\uFF09\u3002\u4E5F\u53EF\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF WEBMCP_IGNORE_CERTIFICATE_ERRORS=1\u3002\u9ED8\u8BA4\u4ECD\u6821\u9A8C\u3002\u4EC5 CDP \u6A21\u5F0F\u6709\u6548"
3596
+ ).hook("preAction", (thisCommand) => {
3572
3597
  const opts = thisCommand.opts();
3573
3598
  if (opts.workspace) {
3574
3599
  process.env.WEBMCP_WORKSPACE = opts.workspace;
3575
3600
  }
3601
+ if (opts.ignoreCertificateErrors) {
3602
+ process.env.WEBMCP_IGNORE_CERTIFICATE_ERRORS = "1";
3603
+ }
3604
+ if (process.env.WEBMCP_IGNORE_CERTIFICATE_ERRORS === "1") {
3605
+ console.error(import_picocolors2.default.yellow("\u5F53\u524D\u53D7\u63A7\u6D4F\u89C8\u5668\u5DF2\u5173\u95ED TLS \u8BC1\u4E66\u6821\u9A8C\u3002"));
3606
+ }
3576
3607
  });
3577
3608
  program.command("state").description("\u83B7\u53D6\u6D4F\u89C8\u5668\u5F53\u524D\u9875\u7B7E\u6216\u6307\u5B9A\u9875\u7B7E\u7684\u5BFC\u822A\u5143\u6570\u636E\uFF08url\u3001title\u3001webmcpTools\u3001\u6240\u6709\u9875\u7B7E\u5217\u8868\uFF09").option("-t, --tabid <id>", "\u6307\u5B9A\u9875\u7B7E\u7684 ID").action(async (options) => {
3578
3609
  const args = { tabid: parseTabId(options.tabid) };