@coofly/agent-browser-mcp 1.0.0 → 1.0.2
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/.github/workflows/release.yml +51 -0
- package/CLAUDE.md +14 -13
- package/LICENSE +674 -674
- package/README.md +16 -47
- package/README_ZH.md +16 -47
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +10 -2
- package/dist/server.js.map +1 -1
- package/dist/utils/configLoader.d.ts +1 -6
- package/dist/utils/configLoader.d.ts.map +1 -1
- package/dist/utils/configLoader.js +7 -119
- package/dist/utils/configLoader.js.map +1 -1
- package/package.json +2 -3
- package/src/server.ts +16 -3
- package/src/utils/configLoader.ts +8 -142
- package/config.example.yaml +0 -44
- package/dist/test-cli.d.ts +0 -2
- package/dist/test-cli.d.ts.map +0 -1
- package/dist/test-cli.js +0 -22
- package/dist/test-cli.js.map +0 -1
- package/dist/test.d.ts +0 -2
- package/dist/test.d.ts.map +0 -1
- package/dist/test.js +0 -17
- package/dist/test.js.map +0 -1
- package/src/test-cli.ts +0 -27
- package/src/test.ts +0 -20
|
@@ -1,81 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 配置加载器
|
|
3
|
-
*
|
|
3
|
+
* 从环境变量加载配置
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { readFileSync, existsSync } from 'fs';
|
|
7
|
-
import { resolve } from 'path';
|
|
8
|
-
import { parse as parseYaml } from 'yaml';
|
|
9
6
|
import { AppConfig, defaultConfig } from '../config.js';
|
|
10
7
|
|
|
11
|
-
/**
|
|
12
|
-
* 命令行参数解析结果
|
|
13
|
-
*/
|
|
14
|
-
interface CliArgs {
|
|
15
|
-
sse?: boolean;
|
|
16
|
-
port?: number;
|
|
17
|
-
host?: string;
|
|
18
|
-
cdp?: string;
|
|
19
|
-
config?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* 解析命令行参数
|
|
24
|
-
*/
|
|
25
|
-
function parseCliArgs(): CliArgs {
|
|
26
|
-
const args = process.argv.slice(2);
|
|
27
|
-
const result: CliArgs = {};
|
|
28
|
-
|
|
29
|
-
for (let i = 0; i < args.length; i++) {
|
|
30
|
-
const arg = args[i];
|
|
31
|
-
|
|
32
|
-
if (arg === '--sse') {
|
|
33
|
-
result.sse = true;
|
|
34
|
-
} else if (arg === '--port' && args[i + 1]) {
|
|
35
|
-
result.port = parseInt(args[++i], 10);
|
|
36
|
-
} else if (arg === '--host' && args[i + 1]) {
|
|
37
|
-
result.host = args[++i];
|
|
38
|
-
} else if (arg === '--cdp' && args[i + 1]) {
|
|
39
|
-
result.cdp = args[++i];
|
|
40
|
-
} else if (arg === '--config' && args[i + 1]) {
|
|
41
|
-
result.config = args[++i];
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 从文件加载配置(仅支持 YAML 格式)
|
|
50
|
-
*/
|
|
51
|
-
function loadConfigFile(configPath?: string): Partial<AppConfig> {
|
|
52
|
-
const paths = configPath
|
|
53
|
-
? [configPath]
|
|
54
|
-
: [
|
|
55
|
-
resolve(process.cwd(), 'config.yaml'),
|
|
56
|
-
resolve(process.cwd(), 'config.yml'),
|
|
57
|
-
];
|
|
58
|
-
|
|
59
|
-
for (const path of paths) {
|
|
60
|
-
if (existsSync(path)) {
|
|
61
|
-
try {
|
|
62
|
-
const content = readFileSync(path, 'utf-8');
|
|
63
|
-
console.error(`[配置] 从文件加载: ${path}`);
|
|
64
|
-
return parseYaml(content) as Partial<AppConfig>;
|
|
65
|
-
} catch (err) {
|
|
66
|
-
console.error(`[配置] 解析配置文件失败: ${path}`, err);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return {};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
8
|
/**
|
|
75
9
|
* 从环境变量加载配置
|
|
76
10
|
*/
|
|
77
|
-
function loadEnvConfig():
|
|
78
|
-
const config:
|
|
11
|
+
function loadEnvConfig(): AppConfig {
|
|
12
|
+
const config: AppConfig = { ...defaultConfig };
|
|
79
13
|
|
|
80
14
|
// CDP 配置
|
|
81
15
|
if (process.env.CDP_ENDPOINT) {
|
|
@@ -87,88 +21,20 @@ function loadEnvConfig(): Partial<AppConfig> {
|
|
|
87
21
|
|
|
88
22
|
// 服务器配置
|
|
89
23
|
if (process.env.MCP_TRANSPORT === 'sse' || process.env.MCP_TRANSPORT === 'stdio') {
|
|
90
|
-
config.server =
|
|
91
|
-
...defaultConfig.server,
|
|
92
|
-
transport: process.env.MCP_TRANSPORT,
|
|
93
|
-
};
|
|
24
|
+
config.server.transport = process.env.MCP_TRANSPORT;
|
|
94
25
|
}
|
|
95
26
|
|
|
96
27
|
if (process.env.MCP_PORT) {
|
|
97
|
-
config.server =
|
|
98
|
-
...defaultConfig.server,
|
|
99
|
-
...config.server,
|
|
100
|
-
port: parseInt(process.env.MCP_PORT, 10),
|
|
101
|
-
};
|
|
28
|
+
config.server.port = parseInt(process.env.MCP_PORT, 10);
|
|
102
29
|
}
|
|
103
30
|
|
|
104
31
|
if (process.env.MCP_HOST) {
|
|
105
|
-
config.server =
|
|
106
|
-
...defaultConfig.server,
|
|
107
|
-
...config.server,
|
|
108
|
-
host: process.env.MCP_HOST,
|
|
109
|
-
};
|
|
32
|
+
config.server.host = process.env.MCP_HOST;
|
|
110
33
|
}
|
|
111
34
|
|
|
112
35
|
// 浏览器配置
|
|
113
36
|
if (process.env.BROWSER_TIMEOUT) {
|
|
114
|
-
config.browser =
|
|
115
|
-
timeout: parseInt(process.env.BROWSER_TIMEOUT, 10),
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return config;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* 深度合并配置对象
|
|
124
|
-
*/
|
|
125
|
-
function deepMerge(target: AppConfig, source: Partial<AppConfig>): AppConfig {
|
|
126
|
-
const result = { ...target };
|
|
127
|
-
|
|
128
|
-
if (source.cdp) {
|
|
129
|
-
result.cdp = { ...result.cdp, ...source.cdp };
|
|
130
|
-
}
|
|
131
|
-
if (source.server) {
|
|
132
|
-
result.server = { ...result.server, ...source.server };
|
|
133
|
-
}
|
|
134
|
-
if (source.browser) {
|
|
135
|
-
result.browser = { ...result.browser, ...source.browser };
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return result;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* 加载完整配置
|
|
143
|
-
* 优先级: 命令行参数 > 环境变量 > 配置文件 > 默认值
|
|
144
|
-
*/
|
|
145
|
-
export function loadConfig(): AppConfig {
|
|
146
|
-
const cliArgs = parseCliArgs();
|
|
147
|
-
|
|
148
|
-
// 1. 从默认配置开始
|
|
149
|
-
let config: AppConfig = { ...defaultConfig };
|
|
150
|
-
|
|
151
|
-
// 2. 合并配置文件
|
|
152
|
-
const fileConfig = loadConfigFile(cliArgs.config);
|
|
153
|
-
config = deepMerge(config, fileConfig);
|
|
154
|
-
|
|
155
|
-
// 3. 合并环境变量
|
|
156
|
-
const envConfig = loadEnvConfig();
|
|
157
|
-
config = deepMerge(config, envConfig);
|
|
158
|
-
|
|
159
|
-
// 4. 合并命令行参数(最高优先级)
|
|
160
|
-
if (cliArgs.sse) {
|
|
161
|
-
config.server.transport = 'sse';
|
|
162
|
-
}
|
|
163
|
-
if (cliArgs.port !== undefined) {
|
|
164
|
-
config.server.port = cliArgs.port;
|
|
165
|
-
}
|
|
166
|
-
if (cliArgs.host) {
|
|
167
|
-
config.server.host = cliArgs.host;
|
|
168
|
-
}
|
|
169
|
-
if (cliArgs.cdp) {
|
|
170
|
-
config.cdp.enabled = true;
|
|
171
|
-
config.cdp.endpoint = cliArgs.cdp;
|
|
37
|
+
config.browser.timeout = parseInt(process.env.BROWSER_TIMEOUT, 10);
|
|
172
38
|
}
|
|
173
39
|
|
|
174
40
|
return config;
|
|
@@ -182,7 +48,7 @@ let globalConfig: AppConfig | null = null;
|
|
|
182
48
|
*/
|
|
183
49
|
export function getConfig(): AppConfig {
|
|
184
50
|
if (!globalConfig) {
|
|
185
|
-
globalConfig =
|
|
51
|
+
globalConfig = loadEnvConfig();
|
|
186
52
|
}
|
|
187
53
|
return globalConfig;
|
|
188
54
|
}
|
package/config.example.yaml
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# agent-browser-mcp 配置文件
|
|
2
|
-
# 复制此文件为 config.yaml 并根据需要修改
|
|
3
|
-
|
|
4
|
-
# ===================
|
|
5
|
-
# CDP 远程调试配置
|
|
6
|
-
# ===================
|
|
7
|
-
cdp:
|
|
8
|
-
# 是否启用 CDP 远程连接
|
|
9
|
-
# 启用后将连接到远程 Chrome/Edge 浏览器实例
|
|
10
|
-
enabled: false
|
|
11
|
-
|
|
12
|
-
# CDP 远程端点地址
|
|
13
|
-
# 格式: http://<host>:<port>
|
|
14
|
-
# 示例: http://10.0.0.20:9222
|
|
15
|
-
#
|
|
16
|
-
# 如何启动支持 CDP 的浏览器:
|
|
17
|
-
# Chrome: chrome --remote-debugging-port=9222
|
|
18
|
-
# Edge: msedge --remote-debugging-port=9222
|
|
19
|
-
endpoint: "http://10.0.0.20:9222"
|
|
20
|
-
|
|
21
|
-
# ===================
|
|
22
|
-
# MCP 服务器配置
|
|
23
|
-
# ===================
|
|
24
|
-
server:
|
|
25
|
-
# 传输模式
|
|
26
|
-
# - stdio: 标准输入输出模式(默认,用于 Claude Desktop 等)
|
|
27
|
-
# - sse: HTTP/SSE 模式(用于 Web 客户端或远程访问)
|
|
28
|
-
transport: stdio
|
|
29
|
-
|
|
30
|
-
# SSE 模式下的监听端口
|
|
31
|
-
port: 9223
|
|
32
|
-
|
|
33
|
-
# SSE 模式下的监听地址
|
|
34
|
-
# - 0.0.0.0: 监听所有网络接口(允许远程访问)
|
|
35
|
-
# - 127.0.0.1: 仅本地访问
|
|
36
|
-
host: "0.0.0.0"
|
|
37
|
-
|
|
38
|
-
# ===================
|
|
39
|
-
# 浏览器操作配置
|
|
40
|
-
# ===================
|
|
41
|
-
browser:
|
|
42
|
-
# 命令执行超时时间(毫秒)
|
|
43
|
-
# 建议值: 30000-60000
|
|
44
|
-
timeout: 30000
|
package/dist/test-cli.d.ts
DELETED
package/dist/test-cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-cli.d.ts","sourceRoot":"","sources":["../src/test-cli.ts"],"names":[],"mappings":""}
|
package/dist/test-cli.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { executeCommand } from './utils/executor.js';
|
|
2
|
-
async function test() {
|
|
3
|
-
console.log('测试 agent-browser CLI 命令执行...\n');
|
|
4
|
-
// 测试打开页面
|
|
5
|
-
console.log('1. 测试打开百度...');
|
|
6
|
-
const openResult = await executeCommand(['open', 'https://www.baidu.com']);
|
|
7
|
-
console.log('结果:', openResult);
|
|
8
|
-
// 测试获取标题
|
|
9
|
-
console.log('\n2. 测试获取页面标题...');
|
|
10
|
-
const titleResult = await executeCommand(['get', 'title']);
|
|
11
|
-
console.log('结果:', titleResult);
|
|
12
|
-
// 测试获取快照
|
|
13
|
-
console.log('\n3. 测试获取页面快照...');
|
|
14
|
-
const snapshotResult = await executeCommand(['snapshot']);
|
|
15
|
-
console.log('结果:', snapshotResult.success ? '成功' : snapshotResult.error);
|
|
16
|
-
if (snapshotResult.success) {
|
|
17
|
-
console.log('快照长度:', snapshotResult.output.length, '字符');
|
|
18
|
-
}
|
|
19
|
-
console.log('\n测试完成!');
|
|
20
|
-
}
|
|
21
|
-
test().catch(console.error);
|
|
22
|
-
//# sourceMappingURL=test-cli.js.map
|
package/dist/test-cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-cli.js","sourceRoot":"","sources":["../src/test-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAE/B,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAEhC,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACzE,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACzB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
|
package/dist/test.d.ts
DELETED
package/dist/test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":""}
|
package/dist/test.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { createServer } from './server.js';
|
|
2
|
-
async function test() {
|
|
3
|
-
console.log('创建 MCP 服务器...');
|
|
4
|
-
const server = await createServer();
|
|
5
|
-
console.log('服务器创建成功');
|
|
6
|
-
// 测试列出工具
|
|
7
|
-
console.log('\n测试列出工具...');
|
|
8
|
-
const toolsHandler = server._requestHandlers?.get('tools/list');
|
|
9
|
-
if (toolsHandler) {
|
|
10
|
-
const result = await toolsHandler({});
|
|
11
|
-
console.log(`找到 ${result.tools.length} 个工具:`);
|
|
12
|
-
result.tools.forEach((t) => console.log(` - ${t.name}: ${t.description}`));
|
|
13
|
-
}
|
|
14
|
-
console.log('\n测试完成!');
|
|
15
|
-
}
|
|
16
|
-
test().catch(console.error);
|
|
17
|
-
//# sourceMappingURL=test.js.map
|
package/dist/test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEvB,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,MAAM,YAAY,GAAI,MAAc,CAAC,gBAAgB,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;IACzE,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACzB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
|
package/src/test-cli.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { executeCommand } from './utils/executor.js';
|
|
2
|
-
|
|
3
|
-
async function test() {
|
|
4
|
-
console.log('测试 agent-browser CLI 命令执行...\n');
|
|
5
|
-
|
|
6
|
-
// 测试打开页面
|
|
7
|
-
console.log('1. 测试打开百度...');
|
|
8
|
-
const openResult = await executeCommand(['open', 'https://www.baidu.com']);
|
|
9
|
-
console.log('结果:', openResult);
|
|
10
|
-
|
|
11
|
-
// 测试获取标题
|
|
12
|
-
console.log('\n2. 测试获取页面标题...');
|
|
13
|
-
const titleResult = await executeCommand(['get', 'title']);
|
|
14
|
-
console.log('结果:', titleResult);
|
|
15
|
-
|
|
16
|
-
// 测试获取快照
|
|
17
|
-
console.log('\n3. 测试获取页面快照...');
|
|
18
|
-
const snapshotResult = await executeCommand(['snapshot']);
|
|
19
|
-
console.log('结果:', snapshotResult.success ? '成功' : snapshotResult.error);
|
|
20
|
-
if (snapshotResult.success) {
|
|
21
|
-
console.log('快照长度:', snapshotResult.output.length, '字符');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
console.log('\n测试完成!');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
test().catch(console.error);
|
package/src/test.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { createServer } from './server.js';
|
|
2
|
-
|
|
3
|
-
async function test() {
|
|
4
|
-
console.log('创建 MCP 服务器...');
|
|
5
|
-
const server = await createServer();
|
|
6
|
-
console.log('服务器创建成功');
|
|
7
|
-
|
|
8
|
-
// 测试列出工具
|
|
9
|
-
console.log('\n测试列出工具...');
|
|
10
|
-
const toolsHandler = (server as any)._requestHandlers?.get('tools/list');
|
|
11
|
-
if (toolsHandler) {
|
|
12
|
-
const result = await toolsHandler({});
|
|
13
|
-
console.log(`找到 ${result.tools.length} 个工具:`);
|
|
14
|
-
result.tools.forEach((t: any) => console.log(` - ${t.name}: ${t.description}`));
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
console.log('\n测试完成!');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
test().catch(console.error);
|