@coofly/agent-browser-mcp 1.0.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.
Files changed (69) hide show
  1. package/.dockerignore +7 -0
  2. package/CLAUDE.md +82 -0
  3. package/Dockerfile +41 -0
  4. package/LICENSE +674 -0
  5. package/README.md +191 -0
  6. package/README_ZH.md +191 -0
  7. package/config.example.yaml +44 -0
  8. package/dist/config.d.ts +43 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +21 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/index.d.ts +3 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +15 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/server.d.ts +43 -0
  17. package/dist/server.d.ts.map +1 -0
  18. package/dist/server.js +334 -0
  19. package/dist/server.js.map +1 -0
  20. package/dist/test-cli.d.ts +2 -0
  21. package/dist/test-cli.d.ts.map +1 -0
  22. package/dist/test-cli.js +22 -0
  23. package/dist/test-cli.js.map +1 -0
  24. package/dist/test.d.ts +2 -0
  25. package/dist/test.d.ts.map +1 -0
  26. package/dist/test.js +17 -0
  27. package/dist/test.js.map +1 -0
  28. package/dist/tools/advanced.d.ts +19 -0
  29. package/dist/tools/advanced.d.ts.map +1 -0
  30. package/dist/tools/advanced.js +40 -0
  31. package/dist/tools/advanced.js.map +1 -0
  32. package/dist/tools/information.d.ts +23 -0
  33. package/dist/tools/information.d.ts.map +1 -0
  34. package/dist/tools/information.js +41 -0
  35. package/dist/tools/information.js.map +1 -0
  36. package/dist/tools/interaction.d.ts +27 -0
  37. package/dist/tools/interaction.d.ts.map +1 -0
  38. package/dist/tools/interaction.js +49 -0
  39. package/dist/tools/interaction.js.map +1 -0
  40. package/dist/tools/navigation.d.ts +21 -0
  41. package/dist/tools/navigation.d.ts.map +1 -0
  42. package/dist/tools/navigation.js +37 -0
  43. package/dist/tools/navigation.js.map +1 -0
  44. package/dist/tools/storage.d.ts +16 -0
  45. package/dist/tools/storage.d.ts.map +1 -0
  46. package/dist/tools/storage.js +28 -0
  47. package/dist/tools/storage.js.map +1 -0
  48. package/dist/utils/configLoader.d.ts +19 -0
  49. package/dist/utils/configLoader.d.ts.map +1 -0
  50. package/dist/utils/configLoader.js +163 -0
  51. package/dist/utils/configLoader.js.map +1 -0
  52. package/dist/utils/executor.d.ts +26 -0
  53. package/dist/utils/executor.d.ts.map +1 -0
  54. package/dist/utils/executor.js +71 -0
  55. package/dist/utils/executor.js.map +1 -0
  56. package/package.json +35 -0
  57. package/src/config.ts +60 -0
  58. package/src/index.ts +16 -0
  59. package/src/server.ts +388 -0
  60. package/src/test-cli.ts +27 -0
  61. package/src/test.ts +20 -0
  62. package/src/tools/advanced.ts +55 -0
  63. package/src/tools/information.ts +54 -0
  64. package/src/tools/interaction.ts +74 -0
  65. package/src/tools/navigation.ts +51 -0
  66. package/src/tools/storage.ts +36 -0
  67. package/src/utils/configLoader.ts +195 -0
  68. package/src/utils/executor.ts +100 -0
  69. package/tsconfig.json +18 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction.js","sourceRoot":"","sources":["../../src/tools/interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAkB,MAAM,sBAAsB,CAAC;AAEtE;;GAEG;AAEH,WAAW;AACX,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,QAAgB,EAChB,OAAmE;IAEnE,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACjC,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,WAAW;AACX,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB,EAAE,OAAwB;IACvE,OAAO,cAAc,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,aAAa;AACb,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,QAAgB,EAAE,OAAwB;IACpE,OAAO,cAAc,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC;AAED,gBAAgB;AAChB,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,QAAgB,EAChB,IAAY,EACZ,OAAwB;IAExB,OAAO,cAAc,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,kBAAkB;AAClB,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,QAAgB,EAChB,IAAY,EACZ,OAAwB;IAExB,OAAO,cAAc,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,YAAY;AACZ,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,QAAgB,EAAE,OAAwB;IACpE,OAAO,cAAc,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC;AAED,SAAS;AACT,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,GAAW,EAAE,OAAwB;IAC/D,OAAO,cAAc,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,aAAa;AACb,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,QAAgB,EAChB,KAAa,EACb,OAAwB;IAExB,OAAO,cAAc,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED,YAAY;AACZ,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,QAAgB,EAAE,OAAwB;IACpE,OAAO,cAAc,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC;AAED,cAAc;AACd,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,QAAgB,EAAE,OAAwB;IACtE,OAAO,cAAc,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { ExecuteOptions } from '../utils/executor.js';
2
+ /**
3
+ * 导航相关工具
4
+ */
5
+ /** 打开 URL */
6
+ export declare function open(url: string, options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
7
+ /** 后退 */
8
+ export declare function back(options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
9
+ /** 前进 */
10
+ export declare function forward(options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
11
+ /** 刷新页面 */
12
+ export declare function reload(options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
13
+ /** 获取当前 URL */
14
+ export declare function getUrl(options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
15
+ /** 获取页面标题 */
16
+ export declare function getTitle(options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
17
+ /** 等待页面加载 */
18
+ export declare function waitForLoad(state?: 'load' | 'domcontentloaded' | 'networkidle', options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
19
+ /** 等待 URL 匹配 */
20
+ export declare function waitForUrl(pattern: string, options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
21
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/tools/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtE;;GAEG;AAEH,aAAa;AACb,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,yDAE/D;AAED,SAAS;AACT,wBAAsB,IAAI,CAAC,OAAO,CAAC,EAAE,cAAc,yDAElD;AAED,SAAS;AACT,wBAAsB,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,yDAErD;AAED,WAAW;AACX,wBAAsB,MAAM,CAAC,OAAO,CAAC,EAAE,cAAc,yDAEpD;AAED,eAAe;AACf,wBAAsB,MAAM,CAAC,OAAO,CAAC,EAAE,cAAc,yDAEpD;AAED,aAAa;AACb,wBAAsB,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,yDAEtD;AAED,aAAa;AACb,wBAAsB,WAAW,CAC/B,KAAK,GAAE,MAAM,GAAG,kBAAkB,GAAG,aAAsB,EAC3D,OAAO,CAAC,EAAE,cAAc,yDAGzB;AAED,gBAAgB;AAChB,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,yDAGzB"}
@@ -0,0 +1,37 @@
1
+ import { executeCommand } from '../utils/executor.js';
2
+ /**
3
+ * 导航相关工具
4
+ */
5
+ /** 打开 URL */
6
+ export async function open(url, options) {
7
+ return executeCommand(['open', url], options);
8
+ }
9
+ /** 后退 */
10
+ export async function back(options) {
11
+ return executeCommand(['back'], options);
12
+ }
13
+ /** 前进 */
14
+ export async function forward(options) {
15
+ return executeCommand(['forward'], options);
16
+ }
17
+ /** 刷新页面 */
18
+ export async function reload(options) {
19
+ return executeCommand(['reload'], options);
20
+ }
21
+ /** 获取当前 URL */
22
+ export async function getUrl(options) {
23
+ return executeCommand(['get', 'url'], options);
24
+ }
25
+ /** 获取页面标题 */
26
+ export async function getTitle(options) {
27
+ return executeCommand(['get', 'title'], options);
28
+ }
29
+ /** 等待页面加载 */
30
+ export async function waitForLoad(state = 'load', options) {
31
+ return executeCommand(['wait', 'load', state], options);
32
+ }
33
+ /** 等待 URL 匹配 */
34
+ export async function waitForUrl(pattern, options) {
35
+ return executeCommand(['wait', 'url', pattern], options);
36
+ }
37
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/tools/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAkB,MAAM,sBAAsB,CAAC;AAEtE;;GAEG;AAEH,aAAa;AACb,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,OAAwB;IAC9D,OAAO,cAAc,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC;AAED,SAAS;AACT,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAwB;IACjD,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS;AACT,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAwB;IACpD,OAAO,cAAc,CAAC,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,WAAW;AACX,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAwB;IACnD,OAAO,cAAc,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED,eAAe;AACf,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAwB;IACnD,OAAO,cAAc,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,aAAa;AACb,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAwB;IACrD,OAAO,cAAc,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAED,aAAa;AACb,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAqD,MAAM,EAC3D,OAAwB;IAExB,OAAO,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,gBAAgB;AAChB,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAe,EACf,OAAwB;IAExB,OAAO,cAAc,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { ExecuteOptions } from '../utils/executor.js';
2
+ /**
3
+ * 存储相关工具
4
+ */
5
+ /** 获取所有 Cookie */
6
+ export declare function getCookies(options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
7
+ /** 设置 Cookie */
8
+ export declare function setCookie(name: string, value: string, options?: ExecuteOptions & {
9
+ domain?: string;
10
+ path?: string;
11
+ }): Promise<import("../utils/executor.js").ExecuteResult>;
12
+ /** 删除 Cookie */
13
+ export declare function deleteCookie(name: string, options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
14
+ /** 清除所有 Cookie */
15
+ export declare function clearCookies(options?: ExecuteOptions): Promise<import("../utils/executor.js").ExecuteResult>;
16
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/tools/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtE;;GAEG;AAEH,kBAAkB;AAClB,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,cAAc,yDAExD;AAED,gBAAgB;AAChB,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,cAAc,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,yDAU9D;AAED,gBAAgB;AAChB,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,yDAExE;AAED,kBAAkB;AAClB,wBAAsB,YAAY,CAAC,OAAO,CAAC,EAAE,cAAc,yDAE1D"}
@@ -0,0 +1,28 @@
1
+ import { executeCommand } from '../utils/executor.js';
2
+ /**
3
+ * 存储相关工具
4
+ */
5
+ /** 获取所有 Cookie */
6
+ export async function getCookies(options) {
7
+ return executeCommand(['cookie', 'list'], options);
8
+ }
9
+ /** 设置 Cookie */
10
+ export async function setCookie(name, value, options) {
11
+ const args = ['cookie', 'set', name, value];
12
+ if (options?.domain) {
13
+ args.push('--domain', options.domain);
14
+ }
15
+ if (options?.path) {
16
+ args.push('--path', options.path);
17
+ }
18
+ return executeCommand(args, options);
19
+ }
20
+ /** 删除 Cookie */
21
+ export async function deleteCookie(name, options) {
22
+ return executeCommand(['cookie', 'delete', name], options);
23
+ }
24
+ /** 清除所有 Cookie */
25
+ export async function clearCookies(options) {
26
+ return executeCommand(['cookie', 'clear'], options);
27
+ }
28
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/tools/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAkB,MAAM,sBAAsB,CAAC;AAEtE;;GAEG;AAEH,kBAAkB;AAClB,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAwB;IACvD,OAAO,cAAc,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC;AAED,gBAAgB;AAChB,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,KAAa,EACb,OAA6D;IAE7D,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5C,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,gBAAgB;AAChB,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,OAAwB;IACvE,OAAO,cAAc,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7D,CAAC;AAED,kBAAkB;AAClB,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAwB;IACzD,OAAO,cAAc,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 配置加载器
3
+ * 支持从文件、环境变量、命令行参数加载配置
4
+ */
5
+ import { AppConfig } from '../config.js';
6
+ /**
7
+ * 加载完整配置
8
+ * 优先级: 命令行参数 > 环境变量 > 配置文件 > 默认值
9
+ */
10
+ export declare function loadConfig(): AppConfig;
11
+ /**
12
+ * 获取全局配置(单例)
13
+ */
14
+ export declare function getConfig(): AppConfig;
15
+ /**
16
+ * 重置配置(用于测试)
17
+ */
18
+ export declare function resetConfig(): void;
19
+ //# sourceMappingURL=configLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configLoader.d.ts","sourceRoot":"","sources":["../../src/utils/configLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,SAAS,EAAiB,MAAM,cAAc,CAAC;AAoIxD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,SAAS,CA8BtC;AAKD;;GAEG;AACH,wBAAgB,SAAS,IAAI,SAAS,CAKrC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * 配置加载器
3
+ * 支持从文件、环境变量、命令行参数加载配置
4
+ */
5
+ import { readFileSync, existsSync } from 'fs';
6
+ import { resolve } from 'path';
7
+ import { parse as parseYaml } from 'yaml';
8
+ import { defaultConfig } from '../config.js';
9
+ /**
10
+ * 解析命令行参数
11
+ */
12
+ function parseCliArgs() {
13
+ const args = process.argv.slice(2);
14
+ const result = {};
15
+ for (let i = 0; i < args.length; i++) {
16
+ const arg = args[i];
17
+ if (arg === '--sse') {
18
+ result.sse = true;
19
+ }
20
+ else if (arg === '--port' && args[i + 1]) {
21
+ result.port = parseInt(args[++i], 10);
22
+ }
23
+ else if (arg === '--host' && args[i + 1]) {
24
+ result.host = args[++i];
25
+ }
26
+ else if (arg === '--cdp' && args[i + 1]) {
27
+ result.cdp = args[++i];
28
+ }
29
+ else if (arg === '--config' && args[i + 1]) {
30
+ result.config = args[++i];
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ /**
36
+ * 从文件加载配置(仅支持 YAML 格式)
37
+ */
38
+ function loadConfigFile(configPath) {
39
+ const paths = configPath
40
+ ? [configPath]
41
+ : [
42
+ resolve(process.cwd(), 'config.yaml'),
43
+ resolve(process.cwd(), 'config.yml'),
44
+ ];
45
+ for (const path of paths) {
46
+ if (existsSync(path)) {
47
+ try {
48
+ const content = readFileSync(path, 'utf-8');
49
+ console.error(`[配置] 从文件加载: ${path}`);
50
+ return parseYaml(content);
51
+ }
52
+ catch (err) {
53
+ console.error(`[配置] 解析配置文件失败: ${path}`, err);
54
+ }
55
+ }
56
+ }
57
+ return {};
58
+ }
59
+ /**
60
+ * 从环境变量加载配置
61
+ */
62
+ function loadEnvConfig() {
63
+ const config = {};
64
+ // CDP 配置
65
+ if (process.env.CDP_ENDPOINT) {
66
+ config.cdp = {
67
+ enabled: true,
68
+ endpoint: process.env.CDP_ENDPOINT,
69
+ };
70
+ }
71
+ // 服务器配置
72
+ if (process.env.MCP_TRANSPORT === 'sse' || process.env.MCP_TRANSPORT === 'stdio') {
73
+ config.server = {
74
+ ...defaultConfig.server,
75
+ transport: process.env.MCP_TRANSPORT,
76
+ };
77
+ }
78
+ if (process.env.MCP_PORT) {
79
+ config.server = {
80
+ ...defaultConfig.server,
81
+ ...config.server,
82
+ port: parseInt(process.env.MCP_PORT, 10),
83
+ };
84
+ }
85
+ if (process.env.MCP_HOST) {
86
+ config.server = {
87
+ ...defaultConfig.server,
88
+ ...config.server,
89
+ host: process.env.MCP_HOST,
90
+ };
91
+ }
92
+ // 浏览器配置
93
+ if (process.env.BROWSER_TIMEOUT) {
94
+ config.browser = {
95
+ timeout: parseInt(process.env.BROWSER_TIMEOUT, 10),
96
+ };
97
+ }
98
+ return config;
99
+ }
100
+ /**
101
+ * 深度合并配置对象
102
+ */
103
+ function deepMerge(target, source) {
104
+ const result = { ...target };
105
+ if (source.cdp) {
106
+ result.cdp = { ...result.cdp, ...source.cdp };
107
+ }
108
+ if (source.server) {
109
+ result.server = { ...result.server, ...source.server };
110
+ }
111
+ if (source.browser) {
112
+ result.browser = { ...result.browser, ...source.browser };
113
+ }
114
+ return result;
115
+ }
116
+ /**
117
+ * 加载完整配置
118
+ * 优先级: 命令行参数 > 环境变量 > 配置文件 > 默认值
119
+ */
120
+ export function loadConfig() {
121
+ const cliArgs = parseCliArgs();
122
+ // 1. 从默认配置开始
123
+ let config = { ...defaultConfig };
124
+ // 2. 合并配置文件
125
+ const fileConfig = loadConfigFile(cliArgs.config);
126
+ config = deepMerge(config, fileConfig);
127
+ // 3. 合并环境变量
128
+ const envConfig = loadEnvConfig();
129
+ config = deepMerge(config, envConfig);
130
+ // 4. 合并命令行参数(最高优先级)
131
+ if (cliArgs.sse) {
132
+ config.server.transport = 'sse';
133
+ }
134
+ if (cliArgs.port !== undefined) {
135
+ config.server.port = cliArgs.port;
136
+ }
137
+ if (cliArgs.host) {
138
+ config.server.host = cliArgs.host;
139
+ }
140
+ if (cliArgs.cdp) {
141
+ config.cdp.enabled = true;
142
+ config.cdp.endpoint = cliArgs.cdp;
143
+ }
144
+ return config;
145
+ }
146
+ /** 全局配置实例 */
147
+ let globalConfig = null;
148
+ /**
149
+ * 获取全局配置(单例)
150
+ */
151
+ export function getConfig() {
152
+ if (!globalConfig) {
153
+ globalConfig = loadConfig();
154
+ }
155
+ return globalConfig;
156
+ }
157
+ /**
158
+ * 重置配置(用于测试)
159
+ */
160
+ export function resetConfig() {
161
+ globalConfig = null;
162
+ }
163
+ //# sourceMappingURL=configLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configLoader.js","sourceRoot":"","sources":["../../src/utils/configLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 执行 agent-browser CLI 命令
3
+ */
4
+ export interface ExecuteOptions {
5
+ session?: string;
6
+ profile?: string;
7
+ json?: boolean;
8
+ headed?: boolean;
9
+ timeout?: number;
10
+ /** CDP 远程端点地址 */
11
+ cdp?: string;
12
+ }
13
+ export interface ExecuteResult {
14
+ success: boolean;
15
+ output: string;
16
+ error?: string;
17
+ }
18
+ /**
19
+ * 执行 agent-browser 命令
20
+ */
21
+ export declare function executeCommand(args: string[], options?: ExecuteOptions): Promise<ExecuteResult>;
22
+ /**
23
+ * 解析 JSON 输出
24
+ */
25
+ export declare function parseJsonOutput<T>(output: string): T | null;
26
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/utils/executor.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA6DxB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAM3D"}
@@ -0,0 +1,71 @@
1
+ import { spawn } from 'child_process';
2
+ /**
3
+ * 执行 agent-browser 命令
4
+ */
5
+ export async function executeCommand(args, options = {}) {
6
+ const cmdArgs = [];
7
+ // 添加全局选项
8
+ if (options.cdp) {
9
+ cmdArgs.push('--cdp', options.cdp);
10
+ }
11
+ if (options.session) {
12
+ cmdArgs.push('--session', options.session);
13
+ }
14
+ if (options.profile) {
15
+ cmdArgs.push('--profile', options.profile);
16
+ }
17
+ if (options.json !== false) {
18
+ cmdArgs.push('--json');
19
+ }
20
+ if (options.headed) {
21
+ cmdArgs.push('--headed');
22
+ }
23
+ // 添加命令参数
24
+ cmdArgs.push(...args);
25
+ return new Promise((resolve) => {
26
+ const timeout = options.timeout || 30000;
27
+ let stdout = '';
28
+ let stderr = '';
29
+ const proc = spawn('agent-browser', cmdArgs, {
30
+ shell: true,
31
+ timeout,
32
+ });
33
+ proc.stdout.on('data', (data) => {
34
+ stdout += data.toString();
35
+ });
36
+ proc.stderr.on('data', (data) => {
37
+ stderr += data.toString();
38
+ });
39
+ proc.on('close', (code) => {
40
+ if (code === 0) {
41
+ resolve({ success: true, output: stdout.trim() });
42
+ }
43
+ else {
44
+ resolve({
45
+ success: false,
46
+ output: stdout.trim(),
47
+ error: stderr.trim() || `命令退出码: ${code}`,
48
+ });
49
+ }
50
+ });
51
+ proc.on('error', (err) => {
52
+ resolve({
53
+ success: false,
54
+ output: '',
55
+ error: `执行错误: ${err.message}`,
56
+ });
57
+ });
58
+ });
59
+ }
60
+ /**
61
+ * 解析 JSON 输出
62
+ */
63
+ export function parseJsonOutput(output) {
64
+ try {
65
+ return JSON.parse(output);
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/utils/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAqBtC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAc,EACd,UAA0B,EAAE;IAE5B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,SAAS;IACT,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAED,SAAS;IACT,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAEtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;QACzC,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,MAAM,IAAI,GAAG,KAAK,CAAC,eAAe,EAAE,OAAO,EAAE;YAC3C,KAAK,EAAE,IAAI;YACX,OAAO;SACR,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9B,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9B,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC;oBACN,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;oBACrB,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE;iBACzC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACvB,OAAO,CAAC;gBACN,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,EAAE;gBACV,KAAK,EAAE,SAAS,GAAG,CAAC,OAAO,EAAE;aAC9B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAI,MAAc;IAC/C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAM,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@coofly/agent-browser-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for agent-browser - headless browser automation for AI agents",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "agent-browser-mcp": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "dev": "tsx src/index.ts",
14
+ "test": "node --test dist/**/*.test.js"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "agent-browser",
19
+ "browser-automation",
20
+ "ai-agent"
21
+ ],
22
+ "license": "GPL-3.0",
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^1.0.0",
25
+ "yaml": "^2.8.2"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^20.10.0",
29
+ "tsx": "^4.7.0",
30
+ "typescript": "^5.3.0"
31
+ },
32
+ "engines": {
33
+ "node": ">=18.0.0"
34
+ }
35
+ }
package/src/config.ts ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * 配置接口定义
3
+ */
4
+
5
+ /**
6
+ * CDP 配置
7
+ */
8
+ export interface CdpConfig {
9
+ /** 是否启用 CDP 远程连接 */
10
+ enabled: boolean;
11
+ /** CDP 远程端点地址,如 http://10.0.0.20:9222 */
12
+ endpoint: string;
13
+ }
14
+
15
+ /**
16
+ * 服务器配置
17
+ */
18
+ export interface ServerConfig {
19
+ /** 传输模式: stdio 或 sse */
20
+ transport: 'stdio' | 'sse';
21
+ /** SSE 模式下的端口号 */
22
+ port: number;
23
+ /** SSE 模式下的监听地址 */
24
+ host: string;
25
+ }
26
+
27
+ /**
28
+ * 浏览器配置
29
+ */
30
+ export interface BrowserConfig {
31
+ /** 命令执行超时时间(毫秒) */
32
+ timeout: number;
33
+ }
34
+
35
+ /**
36
+ * 完整配置接口
37
+ */
38
+ export interface AppConfig {
39
+ cdp: CdpConfig;
40
+ server: ServerConfig;
41
+ browser: BrowserConfig;
42
+ }
43
+
44
+ /**
45
+ * 默认配置
46
+ */
47
+ export const defaultConfig: AppConfig = {
48
+ cdp: {
49
+ enabled: false,
50
+ endpoint: '',
51
+ },
52
+ server: {
53
+ transport: 'stdio',
54
+ port: 9223,
55
+ host: '0.0.0.0',
56
+ },
57
+ browser: {
58
+ timeout: 30000,
59
+ },
60
+ };
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { startServer } from './server.js';
3
+ import { getConfig } from './utils/configLoader.js';
4
+
5
+ // 加载配置并显示启动信息
6
+ const config = getConfig();
7
+ console.error('[agent-browser-mcp] 启动中...');
8
+ console.error(`[配置] 传输模式: ${config.server.transport}`);
9
+ if (config.cdp.enabled) {
10
+ console.error(`[配置] CDP 端点: ${config.cdp.endpoint}`);
11
+ }
12
+
13
+ startServer().catch((error) => {
14
+ console.error('服务器启动失败:', error);
15
+ process.exit(1);
16
+ });