claude-flow-novice 2.14.14 → 2.14.16
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/.claude/commands/cfn-loop-cli.md +21 -27
- package/claude-assets/commands/cfn-loop-cli.md +21 -27
- package/claude-assets/skills/cfn-multi-coordinator-planning/map-dependencies-conflicts.sh +375 -375
- package/claude-assets/skills/cfn-multi-coordinator-planning/plan-coordinator-resources.sh +257 -257
- package/claude-assets/skills/cfn-multi-coordinator-planning/plan-multi-coordinator-work.sh +266 -266
- package/claude-assets/skills/cfn-multi-coordinator-planning/plan-risk-rollout.sh +349 -349
- package/claude-assets/skills/cfn-multi-coordinator-planning/test-multi-coordinator-planning.sh +337 -337
- package/claude-assets/skills/cfn-multi-coordinator-planning/validate-task-planning.sh +188 -188
- package/dist/agent/skill-mcp-selector.js +459 -0
- package/dist/agent/skill-mcp-selector.js.map +1 -0
- package/dist/cli/agent-token-manager.js +382 -0
- package/dist/cli/agent-token-manager.js.map +1 -0
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/mcp/auth-middleware.js +367 -0
- package/dist/mcp/auth-middleware.js.map +1 -0
- package/dist/mcp/playwright-mcp-server-auth.js +515 -0
- package/dist/mcp/playwright-mcp-server-auth.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Enhanced Playwright MCP Server with Authentication
|
|
4
|
+
* Includes token-based authentication and authorization
|
|
5
|
+
*/ const { chromium } = require('playwright');
|
|
6
|
+
const readline = require('readline');
|
|
7
|
+
const MCPAuthMiddleware = require('./auth-middleware.js');
|
|
8
|
+
let AuthenticatedPlaywrightMCPServer = class AuthenticatedPlaywrightMCPServer {
|
|
9
|
+
constructor(options = {}){
|
|
10
|
+
this.browser = null;
|
|
11
|
+
this.page = null;
|
|
12
|
+
this.rl = readline.createInterface({
|
|
13
|
+
input: process.stdin,
|
|
14
|
+
output: process.stdout,
|
|
15
|
+
terminal: false
|
|
16
|
+
});
|
|
17
|
+
// Initialize authentication middleware
|
|
18
|
+
this.auth = new MCPAuthMiddleware({
|
|
19
|
+
redisUrl: options.redisUrl || process.env.MCP_REDIS_URL || 'redis://localhost:6379',
|
|
20
|
+
authRequired: options.authRequired !== false && process.env.MCP_AUTH_REQUIRED !== 'false',
|
|
21
|
+
agentConfigPath: options.agentConfigPath || process.env.MCP_AGENT_CONFIG || './config/agent-whitelist.json',
|
|
22
|
+
skillConfigPath: options.skillConfigPath || process.env.MCP_SKILL_CONFIG || './config/skill-requirements.json',
|
|
23
|
+
rateLimitMax: options.rateLimitMax || parseInt(process.env.MCP_RATE_LIMIT_MAX) || 60,
|
|
24
|
+
rateLimitWindow: options.rateLimitWindow || parseInt(process.env.MCP_RATE_LIMIT_WINDOW) || 60
|
|
25
|
+
});
|
|
26
|
+
this.tools = {
|
|
27
|
+
take_screenshot: {
|
|
28
|
+
name: 'take_screenshot',
|
|
29
|
+
description: 'Take a screenshot of a webpage (requires browser-automation, screenshot-capture skills)',
|
|
30
|
+
inputSchema: {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {
|
|
33
|
+
url: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'URL to capture'
|
|
36
|
+
},
|
|
37
|
+
filename: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Screenshot filename (optional)'
|
|
40
|
+
},
|
|
41
|
+
fullPage: {
|
|
42
|
+
type: 'boolean',
|
|
43
|
+
default: false,
|
|
44
|
+
description: 'Capture full page'
|
|
45
|
+
},
|
|
46
|
+
waitTime: {
|
|
47
|
+
type: 'number',
|
|
48
|
+
default: 3000,
|
|
49
|
+
description: 'Wait time before screenshot (ms)'
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
required: [
|
|
53
|
+
'url'
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
skillRequirements: [
|
|
57
|
+
'browser-automation',
|
|
58
|
+
'screenshot-capture'
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
search_google: {
|
|
62
|
+
name: 'search_google',
|
|
63
|
+
description: 'Search Google and return results (requires browser-automation, web-search skills)',
|
|
64
|
+
inputSchema: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
properties: {
|
|
67
|
+
query: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
description: 'Search query'
|
|
70
|
+
},
|
|
71
|
+
screenshot: {
|
|
72
|
+
type: 'boolean',
|
|
73
|
+
default: true,
|
|
74
|
+
description: 'Take screenshot of results'
|
|
75
|
+
},
|
|
76
|
+
resultCount: {
|
|
77
|
+
type: 'number',
|
|
78
|
+
default: 5,
|
|
79
|
+
description: 'Number of results to return'
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
required: [
|
|
83
|
+
'query'
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
skillRequirements: [
|
|
87
|
+
'browser-automation',
|
|
88
|
+
'web-search'
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
navigate_and_interact: {
|
|
92
|
+
name: 'navigate_and_interact',
|
|
93
|
+
description: 'Navigate to a webpage and interact with elements (requires browser-automation, web-interaction skills)',
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
properties: {
|
|
97
|
+
url: {
|
|
98
|
+
type: 'string',
|
|
99
|
+
description: 'URL to navigate to'
|
|
100
|
+
},
|
|
101
|
+
actions: {
|
|
102
|
+
type: 'array',
|
|
103
|
+
description: 'Array of actions to perform',
|
|
104
|
+
items: {
|
|
105
|
+
type: 'object',
|
|
106
|
+
properties: {
|
|
107
|
+
type: {
|
|
108
|
+
type: 'string',
|
|
109
|
+
enum: [
|
|
110
|
+
'click',
|
|
111
|
+
'fill',
|
|
112
|
+
'press',
|
|
113
|
+
'wait'
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
selector: {
|
|
117
|
+
type: 'string',
|
|
118
|
+
description: 'CSS selector'
|
|
119
|
+
},
|
|
120
|
+
value: {
|
|
121
|
+
type: 'string',
|
|
122
|
+
description: 'Value for fill actions'
|
|
123
|
+
},
|
|
124
|
+
key: {
|
|
125
|
+
type: 'string',
|
|
126
|
+
description: 'Key for press actions'
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
screenshot: {
|
|
132
|
+
type: 'boolean',
|
|
133
|
+
default: false
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
required: [
|
|
137
|
+
'url'
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
skillRequirements: [
|
|
141
|
+
'browser-automation',
|
|
142
|
+
'web-interaction'
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
this.stats = {
|
|
147
|
+
totalRequests: 0,
|
|
148
|
+
authorizedRequests: 0,
|
|
149
|
+
rejectedRequests: 0,
|
|
150
|
+
toolUsage: {},
|
|
151
|
+
lastActivity: null
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
async initialize() {
|
|
155
|
+
try {
|
|
156
|
+
// Initialize authentication
|
|
157
|
+
await this.auth.initialize();
|
|
158
|
+
console.error('[MCP-Server] Authentication middleware initialized');
|
|
159
|
+
// Initialize Playwright browser
|
|
160
|
+
await this.initBrowser();
|
|
161
|
+
console.error('[MCP-Server] Playwright browser initialized');
|
|
162
|
+
console.error('[MCP-Server] Authenticated Playwright MCP Server ready');
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error('[MCP-Server] Failed to initialize:', error);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async initBrowser() {
|
|
169
|
+
if (!this.browser) {
|
|
170
|
+
this.browser = await chromium.launch({
|
|
171
|
+
headless: true,
|
|
172
|
+
args: [
|
|
173
|
+
'--no-sandbox',
|
|
174
|
+
'--disable-setuid-sandbox',
|
|
175
|
+
'--disable-dev-shm-usage',
|
|
176
|
+
'--disable-gpu'
|
|
177
|
+
]
|
|
178
|
+
});
|
|
179
|
+
this.page = await this.browser.newPage();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async takeScreenshot(args, agentContext) {
|
|
183
|
+
await this.initBrowser();
|
|
184
|
+
console.error(`[MCP-Server] Taking screenshot for ${agentContext.agentType}`);
|
|
185
|
+
await this.page.goto(args.url, {
|
|
186
|
+
waitUntil: 'networkidle',
|
|
187
|
+
timeout: 15000
|
|
188
|
+
});
|
|
189
|
+
if (args.waitTime > 0) {
|
|
190
|
+
await this.page.waitForTimeout(args.waitTime);
|
|
191
|
+
}
|
|
192
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
193
|
+
const filename = args.filename || `screenshot-${agentContext.agentType}-${timestamp}.png`;
|
|
194
|
+
const filepath = `/app/screenshots/${filename}`;
|
|
195
|
+
await this.page.screenshot({
|
|
196
|
+
path: filepath,
|
|
197
|
+
fullPage: args.fullPage || false
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
success: true,
|
|
201
|
+
filename: filename,
|
|
202
|
+
filepath: filepath,
|
|
203
|
+
url: args.url,
|
|
204
|
+
title: await this.page.title(),
|
|
205
|
+
size: `${this.page.viewportSize()?.width || 1280}x${this.page.viewportSize()?.height || 720}`,
|
|
206
|
+
capturedBy: agentContext.agentType,
|
|
207
|
+
timestamp: new Date().toISOString()
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
async searchGoogle(args, agentContext) {
|
|
211
|
+
await this.initBrowser();
|
|
212
|
+
console.error(`[MCP-Server] Google search for ${agentContext.agentType}: "${args.query}"`);
|
|
213
|
+
await this.page.goto('https://www.google.com', {
|
|
214
|
+
waitUntil: 'networkidle',
|
|
215
|
+
timeout: 15000
|
|
216
|
+
});
|
|
217
|
+
// Handle cookies popup if present
|
|
218
|
+
try {
|
|
219
|
+
await this.page.waitForSelector('button[aria-label*="Accept"], button[aria-label*="agree"]', {
|
|
220
|
+
timeout: 3000
|
|
221
|
+
});
|
|
222
|
+
await this.page.click('button[aria-label*="Accept"], button[aria-label*="agree"]');
|
|
223
|
+
await this.page.waitForTimeout(1000);
|
|
224
|
+
} catch (e) {
|
|
225
|
+
// No cookie popup, continue
|
|
226
|
+
}
|
|
227
|
+
// Perform search
|
|
228
|
+
const searchBox = await this.page.waitForSelector('textarea[name="q"], input[name="q"]', {
|
|
229
|
+
timeout: 10000
|
|
230
|
+
});
|
|
231
|
+
await searchBox.fill(args.query);
|
|
232
|
+
await searchBox.press('Enter');
|
|
233
|
+
// Wait for results
|
|
234
|
+
await this.page.waitForSelector('[role="main"], #search', {
|
|
235
|
+
timeout: 15000
|
|
236
|
+
});
|
|
237
|
+
// Extract results
|
|
238
|
+
const results = await this.page.$$eval('div[data-hveid] h3', (elements)=>elements.slice(0, args.resultCount || 5).map((el)=>el.textContent.trim()));
|
|
239
|
+
let screenshotInfo = null;
|
|
240
|
+
if (args.screenshot) {
|
|
241
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
242
|
+
const filename = `google-search-${args.query.toLowerCase().replace(/\s+/g, '-')}-${timestamp}.png`;
|
|
243
|
+
await this.page.screenshot({
|
|
244
|
+
path: `/app/screenshots/${filename}`
|
|
245
|
+
});
|
|
246
|
+
screenshotInfo = {
|
|
247
|
+
filename,
|
|
248
|
+
path: `/app/screenshots/${filename}`,
|
|
249
|
+
url: this.page.url()
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
success: true,
|
|
254
|
+
query: args.query,
|
|
255
|
+
results: results,
|
|
256
|
+
resultCount: results.length,
|
|
257
|
+
screenshot: screenshotInfo,
|
|
258
|
+
url: this.page.url(),
|
|
259
|
+
title: await this.page.title(),
|
|
260
|
+
searchedBy: agentContext.agentType,
|
|
261
|
+
timestamp: new Date().toISOString()
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
async navigateAndInteract(args, agentContext) {
|
|
265
|
+
await this.initBrowser();
|
|
266
|
+
console.error(`[MCP-Server] Page interaction for ${agentContext.agentType}: ${args.url}`);
|
|
267
|
+
await this.page.goto(args.url, {
|
|
268
|
+
waitUntil: 'networkidle',
|
|
269
|
+
timeout: 15000
|
|
270
|
+
});
|
|
271
|
+
const results = [];
|
|
272
|
+
for (const action of args.actions || []){
|
|
273
|
+
try {
|
|
274
|
+
switch(action.type){
|
|
275
|
+
case 'click':
|
|
276
|
+
await this.page.waitForSelector(action.selector, {
|
|
277
|
+
timeout: 5000
|
|
278
|
+
});
|
|
279
|
+
await this.page.click(action.selector);
|
|
280
|
+
results.push({
|
|
281
|
+
action: 'click',
|
|
282
|
+
selector: action.selector,
|
|
283
|
+
success: true
|
|
284
|
+
});
|
|
285
|
+
break;
|
|
286
|
+
case 'fill':
|
|
287
|
+
await this.page.waitForSelector(action.selector, {
|
|
288
|
+
timeout: 5000
|
|
289
|
+
});
|
|
290
|
+
await this.page.fill(action.selector, action.value);
|
|
291
|
+
results.push({
|
|
292
|
+
action: 'fill',
|
|
293
|
+
selector: action.selector,
|
|
294
|
+
value: action.value,
|
|
295
|
+
success: true
|
|
296
|
+
});
|
|
297
|
+
break;
|
|
298
|
+
case 'press':
|
|
299
|
+
await this.page.press(action.selector || 'body', action.key);
|
|
300
|
+
results.push({
|
|
301
|
+
action: 'press',
|
|
302
|
+
key: action.key,
|
|
303
|
+
success: true
|
|
304
|
+
});
|
|
305
|
+
break;
|
|
306
|
+
case 'wait':
|
|
307
|
+
await this.page.waitForTimeout(parseInt(action.value) || 1000);
|
|
308
|
+
results.push({
|
|
309
|
+
action: 'wait',
|
|
310
|
+
duration: action.value,
|
|
311
|
+
success: true
|
|
312
|
+
});
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
} catch (error) {
|
|
316
|
+
results.push({
|
|
317
|
+
action: action.type,
|
|
318
|
+
selector: action.selector,
|
|
319
|
+
success: false,
|
|
320
|
+
error: error.message
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
let screenshotInfo = null;
|
|
325
|
+
if (args.screenshot) {
|
|
326
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
327
|
+
const filename = `interaction-${agentContext.agentType}-${timestamp}.png`;
|
|
328
|
+
await this.page.screenshot({
|
|
329
|
+
path: `/app/screenshots/${filename}`
|
|
330
|
+
});
|
|
331
|
+
screenshotInfo = {
|
|
332
|
+
filename,
|
|
333
|
+
path: `/app/screenshots/${filename}`
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
return {
|
|
337
|
+
success: true,
|
|
338
|
+
url: args.url,
|
|
339
|
+
actions: results,
|
|
340
|
+
screenshot: screenshotInfo,
|
|
341
|
+
title: await this.page.title(),
|
|
342
|
+
interactedBy: agentContext.agentType,
|
|
343
|
+
timestamp: new Date().toISOString()
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
async handleMessage(message) {
|
|
347
|
+
try {
|
|
348
|
+
this.stats.totalRequests++;
|
|
349
|
+
this.stats.lastActivity = Date.now();
|
|
350
|
+
// Initialize request context
|
|
351
|
+
const request = {
|
|
352
|
+
headers: {
|
|
353
|
+
'x-agent-token': message.params?.context?.agentToken,
|
|
354
|
+
'x-agent-type': message.params?.context?.agentType
|
|
355
|
+
},
|
|
356
|
+
body: message
|
|
357
|
+
};
|
|
358
|
+
const response = {
|
|
359
|
+
writeHead: ()=>{},
|
|
360
|
+
end: (data)=>{
|
|
361
|
+
// For JSON-RPC, we'll just return the data directly
|
|
362
|
+
this.responseData = JSON.parse(data);
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
// Authenticate request
|
|
366
|
+
let authenticationPassed = false;
|
|
367
|
+
await this.auth.authenticateRequest(request, response, ()=>{
|
|
368
|
+
authenticationPassed = true;
|
|
369
|
+
});
|
|
370
|
+
if (!authenticationPassed) {
|
|
371
|
+
this.stats.rejectedRequests++;
|
|
372
|
+
return this.responseData || {
|
|
373
|
+
jsonrpc: '2.0',
|
|
374
|
+
id: message.id,
|
|
375
|
+
error: {
|
|
376
|
+
code: -32001,
|
|
377
|
+
message: 'Authentication failed'
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
this.stats.authorizedRequests++;
|
|
382
|
+
// Authentication passed, process request
|
|
383
|
+
if (message.method === 'initialize') {
|
|
384
|
+
return {
|
|
385
|
+
jsonrpc: '2.0',
|
|
386
|
+
id: message.id,
|
|
387
|
+
result: {
|
|
388
|
+
protocolVersion: '2024-11-05',
|
|
389
|
+
capabilities: {
|
|
390
|
+
tools: {}
|
|
391
|
+
},
|
|
392
|
+
serverInfo: {
|
|
393
|
+
name: 'playwright-mcp-server-authenticated',
|
|
394
|
+
version: '1.0.0',
|
|
395
|
+
authentication: 'enabled'
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
} else if (message.method === 'tools/list') {
|
|
400
|
+
return {
|
|
401
|
+
jsonrpc: '2.0',
|
|
402
|
+
id: message.id,
|
|
403
|
+
result: {
|
|
404
|
+
tools: Object.values(this.tools)
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
} else if (message.method === 'tools/call') {
|
|
408
|
+
const toolName = message.params.name;
|
|
409
|
+
const args = message.params.arguments || {};
|
|
410
|
+
const agentContext = request.agentContext || {
|
|
411
|
+
agentType: 'unknown',
|
|
412
|
+
authenticated: false
|
|
413
|
+
};
|
|
414
|
+
// Update tool usage stats
|
|
415
|
+
this.stats.toolUsage[toolName] = (this.stats.toolUsage[toolName] || 0) + 1;
|
|
416
|
+
let result;
|
|
417
|
+
if (toolName === 'take_screenshot') {
|
|
418
|
+
result = await this.takeScreenshot(args, agentContext);
|
|
419
|
+
} else if (toolName === 'search_google') {
|
|
420
|
+
result = await this.searchGoogle(args, agentContext);
|
|
421
|
+
} else if (toolName === 'navigate_and_interact') {
|
|
422
|
+
result = await this.navigateAndInteract(args, agentContext);
|
|
423
|
+
} else {
|
|
424
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
425
|
+
}
|
|
426
|
+
console.error(`[MCP-Server] Tool ${toolName} executed by ${agentContext.agentType}`);
|
|
427
|
+
return {
|
|
428
|
+
jsonrpc: '2.0',
|
|
429
|
+
id: message.id,
|
|
430
|
+
result: {
|
|
431
|
+
content: [
|
|
432
|
+
{
|
|
433
|
+
type: 'text',
|
|
434
|
+
text: JSON.stringify(result, null, 2)
|
|
435
|
+
}
|
|
436
|
+
]
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
} catch (error) {
|
|
441
|
+
console.error('[MCP-Server] Error handling message:', error);
|
|
442
|
+
return {
|
|
443
|
+
jsonrpc: '2.0',
|
|
444
|
+
id: message.id || null,
|
|
445
|
+
error: {
|
|
446
|
+
code: -32000,
|
|
447
|
+
message: error.message
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
async start() {
|
|
453
|
+
await this.initialize();
|
|
454
|
+
this.rl.on('line', async (line)=>{
|
|
455
|
+
try {
|
|
456
|
+
const message = JSON.parse(line);
|
|
457
|
+
const response = await this.handleMessage(message);
|
|
458
|
+
console.log(JSON.stringify(response));
|
|
459
|
+
} catch (error) {
|
|
460
|
+
console.log(JSON.stringify({
|
|
461
|
+
jsonrpc: '2.0',
|
|
462
|
+
id: null,
|
|
463
|
+
error: {
|
|
464
|
+
code: -32700,
|
|
465
|
+
message: `Parse error: ${error.message}`
|
|
466
|
+
}
|
|
467
|
+
}));
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
// Cleanup on exit
|
|
471
|
+
process.on('SIGINT', async ()=>{
|
|
472
|
+
console.error('[MCP-Server] Shutting down authenticated Playwright MCP Server...');
|
|
473
|
+
await this.shutdown();
|
|
474
|
+
process.exit(0);
|
|
475
|
+
});
|
|
476
|
+
// Log statistics periodically
|
|
477
|
+
setInterval(()=>{
|
|
478
|
+
console.error(`[MCP-Server] Stats: ${this.stats.totalRequests} total, ${this.stats.authorizedRequests} authorized, ${this.stats.rejectedRequests} rejected`);
|
|
479
|
+
console.error(`[MCP-Server] Tool usage:`, JSON.stringify(this.stats.toolUsage));
|
|
480
|
+
}, 60000); // Every minute
|
|
481
|
+
}
|
|
482
|
+
async getStats() {
|
|
483
|
+
const authStats = await this.auth.getStats();
|
|
484
|
+
return {
|
|
485
|
+
server: {
|
|
486
|
+
name: 'playwright-mcp-server-authenticated',
|
|
487
|
+
uptime: process.uptime(),
|
|
488
|
+
...this.stats
|
|
489
|
+
},
|
|
490
|
+
authentication: authStats
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
async shutdown() {
|
|
494
|
+
try {
|
|
495
|
+
if (this.browser) await this.browser.close();
|
|
496
|
+
if (this.rl) this.rl.close();
|
|
497
|
+
if (this.auth) await this.auth.shutdown();
|
|
498
|
+
console.error('[MCP-Server] Shutdown complete');
|
|
499
|
+
} catch (error) {
|
|
500
|
+
console.error('[MCP-Server] Error during shutdown:', error);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
// Start the server
|
|
505
|
+
const server = new AuthenticatedPlaywrightMCPServer({
|
|
506
|
+
redisUrl: process.env.MCP_REDIS_URL,
|
|
507
|
+
authRequired: process.env.MCP_AUTH_REQUIRED !== 'false',
|
|
508
|
+
rateLimitMax: parseInt(process.env.MCP_RATE_LIMIT_MAX) || 60
|
|
509
|
+
});
|
|
510
|
+
server.start().catch((error)=>{
|
|
511
|
+
console.error('[MCP-Server] Failed to start authenticated Playwright MCP Server:', error);
|
|
512
|
+
process.exit(1);
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
//# sourceMappingURL=playwright-mcp-server-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/playwright-mcp-server-auth.js"],"sourcesContent":["#!/usr/bin/env node\r\n\r\n/**\r\n * Enhanced Playwright MCP Server with Authentication\r\n * Includes token-based authentication and authorization\r\n */\r\n\r\nconst { chromium } = require('playwright');\r\nconst readline = require('readline');\r\nconst MCPAuthMiddleware = require('./auth-middleware.js');\r\n\r\nclass AuthenticatedPlaywrightMCPServer {\r\n constructor(options = {}) {\r\n this.browser = null;\r\n this.page = null;\r\n this.rl = readline.createInterface({\r\n input: process.stdin,\r\n output: process.stdout,\r\n terminal: false\r\n });\r\n\r\n // Initialize authentication middleware\r\n this.auth = new MCPAuthMiddleware({\r\n redisUrl: options.redisUrl || process.env.MCP_REDIS_URL || 'redis://localhost:6379',\r\n authRequired: options.authRequired !== false && process.env.MCP_AUTH_REQUIRED !== 'false',\r\n agentConfigPath: options.agentConfigPath || process.env.MCP_AGENT_CONFIG || './config/agent-whitelist.json',\r\n skillConfigPath: options.skillConfigPath || process.env.MCP_SKILL_CONFIG || './config/skill-requirements.json',\r\n rateLimitMax: options.rateLimitMax || parseInt(process.env.MCP_RATE_LIMIT_MAX) || 60,\r\n rateLimitWindow: options.rateLimitWindow || parseInt(process.env.MCP_RATE_LIMIT_WINDOW) || 60\r\n });\r\n\r\n this.tools = {\r\n take_screenshot: {\r\n name: 'take_screenshot',\r\n description: 'Take a screenshot of a webpage (requires browser-automation, screenshot-capture skills)',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n url: { type: 'string', description: 'URL to capture' },\r\n filename: { type: 'string', description: 'Screenshot filename (optional)' },\r\n fullPage: { type: 'boolean', default: false, description: 'Capture full page' },\r\n waitTime: { type: 'number', default: 3000, description: 'Wait time before screenshot (ms)' }\r\n },\r\n required: ['url']\r\n },\r\n skillRequirements: ['browser-automation', 'screenshot-capture']\r\n },\r\n search_google: {\r\n name: 'search_google',\r\n description: 'Search Google and return results (requires browser-automation, web-search skills)',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n query: { type: 'string', description: 'Search query' },\r\n screenshot: { type: 'boolean', default: true, description: 'Take screenshot of results' },\r\n resultCount: { type: 'number', default: 5, description: 'Number of results to return' }\r\n },\r\n required: ['query']\r\n },\r\n skillRequirements: ['browser-automation', 'web-search']\r\n },\r\n navigate_and_interact: {\r\n name: 'navigate_and_interact',\r\n description: 'Navigate to a webpage and interact with elements (requires browser-automation, web-interaction skills)',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n url: { type: 'string', description: 'URL to navigate to' },\r\n actions: {\r\n type: 'array',\r\n description: 'Array of actions to perform',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n type: { type: 'string', enum: ['click', 'fill', 'press', 'wait'] },\r\n selector: { type: 'string', description: 'CSS selector' },\r\n value: { type: 'string', description: 'Value for fill actions' },\r\n key: { type: 'string', description: 'Key for press actions' }\r\n }\r\n }\r\n },\r\n screenshot: { type: 'boolean', default: false }\r\n },\r\n required: ['url']\r\n },\r\n skillRequirements: ['browser-automation', 'web-interaction']\r\n }\r\n };\r\n\r\n this.stats = {\r\n totalRequests: 0,\r\n authorizedRequests: 0,\r\n rejectedRequests: 0,\r\n toolUsage: {},\r\n lastActivity: null\r\n };\r\n }\r\n\r\n async initialize() {\r\n try {\r\n // Initialize authentication\r\n await this.auth.initialize();\r\n console.error('[MCP-Server] Authentication middleware initialized');\r\n\r\n // Initialize Playwright browser\r\n await this.initBrowser();\r\n console.error('[MCP-Server] Playwright browser initialized');\r\n\r\n console.error('[MCP-Server] Authenticated Playwright MCP Server ready');\r\n } catch (error) {\r\n console.error('[MCP-Server] Failed to initialize:', error);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n async initBrowser() {\r\n if (!this.browser) {\r\n this.browser = await chromium.launch({\r\n headless: true,\r\n args: [\r\n '--no-sandbox',\r\n '--disable-setuid-sandbox',\r\n '--disable-dev-shm-usage',\r\n '--disable-gpu'\r\n ]\r\n });\r\n this.page = await this.browser.newPage();\r\n }\r\n }\r\n\r\n async takeScreenshot(args, agentContext) {\r\n await this.initBrowser();\r\n\r\n console.error(`[MCP-Server] Taking screenshot for ${agentContext.agentType}`);\r\n\r\n await this.page.goto(args.url, {\r\n waitUntil: 'networkidle',\r\n timeout: 15000\r\n });\r\n\r\n if (args.waitTime > 0) {\r\n await this.page.waitForTimeout(args.waitTime);\r\n }\r\n\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\r\n const filename = args.filename || `screenshot-${agentContext.agentType}-${timestamp}.png`;\r\n const filepath = `/app/screenshots/${filename}`;\r\n\r\n await this.page.screenshot({\r\n path: filepath,\r\n fullPage: args.fullPage || false\r\n });\r\n\r\n return {\r\n success: true,\r\n filename: filename,\r\n filepath: filepath,\r\n url: args.url,\r\n title: await this.page.title(),\r\n size: `${this.page.viewportSize()?.width || 1280}x${this.page.viewportSize()?.height || 720}`,\r\n capturedBy: agentContext.agentType,\r\n timestamp: new Date().toISOString()\r\n };\r\n }\r\n\r\n async searchGoogle(args, agentContext) {\r\n await this.initBrowser();\r\n\r\n console.error(`[MCP-Server] Google search for ${agentContext.agentType}: \"${args.query}\"`);\r\n\r\n await this.page.goto('https://www.google.com', {\r\n waitUntil: 'networkidle',\r\n timeout: 15000\r\n });\r\n\r\n // Handle cookies popup if present\r\n try {\r\n await this.page.waitForSelector('button[aria-label*=\"Accept\"], button[aria-label*=\"agree\"]', { timeout: 3000 });\r\n await this.page.click('button[aria-label*=\"Accept\"], button[aria-label*=\"agree\"]');\r\n await this.page.waitForTimeout(1000);\r\n } catch (e) {\r\n // No cookie popup, continue\r\n }\r\n\r\n // Perform search\r\n const searchBox = await this.page.waitForSelector('textarea[name=\"q\"], input[name=\"q\"]', { timeout: 10000 });\r\n await searchBox.fill(args.query);\r\n await searchBox.press('Enter');\r\n\r\n // Wait for results\r\n await this.page.waitForSelector('[role=\"main\"], #search', { timeout: 15000 });\r\n\r\n // Extract results\r\n const results = await this.page.$$eval('div[data-hveid] h3', elements =>\r\n elements.slice(0, args.resultCount || 5).map(el => el.textContent.trim())\r\n );\r\n\r\n let screenshotInfo = null;\r\n if (args.screenshot) {\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\r\n const filename = `google-search-${args.query.toLowerCase().replace(/\\s+/g, '-')}-${timestamp}.png`;\r\n await this.page.screenshot({ path: `/app/screenshots/${filename}` });\r\n screenshotInfo = {\r\n filename,\r\n path: `/app/screenshots/${filename}`,\r\n url: this.page.url()\r\n };\r\n }\r\n\r\n return {\r\n success: true,\r\n query: args.query,\r\n results: results,\r\n resultCount: results.length,\r\n screenshot: screenshotInfo,\r\n url: this.page.url(),\r\n title: await this.page.title(),\r\n searchedBy: agentContext.agentType,\r\n timestamp: new Date().toISOString()\r\n };\r\n }\r\n\r\n async navigateAndInteract(args, agentContext) {\r\n await this.initBrowser();\r\n\r\n console.error(`[MCP-Server] Page interaction for ${agentContext.agentType}: ${args.url}`);\r\n\r\n await this.page.goto(args.url, {\r\n waitUntil: 'networkidle',\r\n timeout: 15000\r\n });\r\n\r\n const results = [];\r\n\r\n for (const action of args.actions || []) {\r\n try {\r\n switch (action.type) {\r\n case 'click':\r\n await this.page.waitForSelector(action.selector, { timeout: 5000 });\r\n await this.page.click(action.selector);\r\n results.push({ action: 'click', selector: action.selector, success: true });\r\n break;\r\n\r\n case 'fill':\r\n await this.page.waitForSelector(action.selector, { timeout: 5000 });\r\n await this.page.fill(action.selector, action.value);\r\n results.push({ action: 'fill', selector: action.selector, value: action.value, success: true });\r\n break;\r\n\r\n case 'press':\r\n await this.page.press(action.selector || 'body', action.key);\r\n results.push({ action: 'press', key: action.key, success: true });\r\n break;\r\n\r\n case 'wait':\r\n await this.page.waitForTimeout(parseInt(action.value) || 1000);\r\n results.push({ action: 'wait', duration: action.value, success: true });\r\n break;\r\n }\r\n } catch (error) {\r\n results.push({\r\n action: action.type,\r\n selector: action.selector,\r\n success: false,\r\n error: error.message\r\n });\r\n }\r\n }\r\n\r\n let screenshotInfo = null;\r\n if (args.screenshot) {\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\r\n const filename = `interaction-${agentContext.agentType}-${timestamp}.png`;\r\n await this.page.screenshot({ path: `/app/screenshots/${filename}` });\r\n screenshotInfo = {\r\n filename,\r\n path: `/app/screenshots/${filename}`\r\n };\r\n }\r\n\r\n return {\r\n success: true,\r\n url: args.url,\r\n actions: results,\r\n screenshot: screenshotInfo,\r\n title: await this.page.title(),\r\n interactedBy: agentContext.agentType,\r\n timestamp: new Date().toISOString()\r\n };\r\n }\r\n\r\n async handleMessage(message) {\r\n try {\r\n this.stats.totalRequests++;\r\n this.stats.lastActivity = Date.now();\r\n\r\n // Initialize request context\r\n const request = {\r\n headers: {\r\n 'x-agent-token': message.params?.context?.agentToken,\r\n 'x-agent-type': message.params?.context?.agentType\r\n },\r\n body: message\r\n };\r\n\r\n const response = {\r\n writeHead: () => {},\r\n end: (data) => {\r\n // For JSON-RPC, we'll just return the data directly\r\n this.responseData = JSON.parse(data);\r\n }\r\n };\r\n\r\n // Authenticate request\r\n let authenticationPassed = false;\r\n await this.auth.authenticateRequest(request, response, () => {\r\n authenticationPassed = true;\r\n });\r\n\r\n if (!authenticationPassed) {\r\n this.stats.rejectedRequests++;\r\n return this.responseData || {\r\n jsonrpc: '2.0',\r\n id: message.id,\r\n error: {\r\n code: -32001,\r\n message: 'Authentication failed'\r\n }\r\n };\r\n }\r\n\r\n this.stats.authorizedRequests++;\r\n\r\n // Authentication passed, process request\r\n if (message.method === 'initialize') {\r\n return {\r\n jsonrpc: '2.0',\r\n id: message.id,\r\n result: {\r\n protocolVersion: '2024-11-05',\r\n capabilities: {\r\n tools: {}\r\n },\r\n serverInfo: {\r\n name: 'playwright-mcp-server-authenticated',\r\n version: '1.0.0',\r\n authentication: 'enabled'\r\n }\r\n }\r\n };\r\n } else if (message.method === 'tools/list') {\r\n return {\r\n jsonrpc: '2.0',\r\n id: message.id,\r\n result: { tools: Object.values(this.tools) }\r\n };\r\n } else if (message.method === 'tools/call') {\r\n const toolName = message.params.name;\r\n const args = message.params.arguments || {};\r\n const agentContext = request.agentContext || {\r\n agentType: 'unknown',\r\n authenticated: false\r\n };\r\n\r\n // Update tool usage stats\r\n this.stats.toolUsage[toolName] = (this.stats.toolUsage[toolName] || 0) + 1;\r\n\r\n let result;\r\n if (toolName === 'take_screenshot') {\r\n result = await this.takeScreenshot(args, agentContext);\r\n } else if (toolName === 'search_google') {\r\n result = await this.searchGoogle(args, agentContext);\r\n } else if (toolName === 'navigate_and_interact') {\r\n result = await this.navigateAndInteract(args, agentContext);\r\n } else {\r\n throw new Error(`Unknown tool: ${toolName}`);\r\n }\r\n\r\n console.error(`[MCP-Server] Tool ${toolName} executed by ${agentContext.agentType}`);\r\n\r\n return {\r\n jsonrpc: '2.0',\r\n id: message.id,\r\n result: {\r\n content: [{\r\n type: 'text',\r\n text: JSON.stringify(result, null, 2)\r\n }]\r\n }\r\n };\r\n }\r\n } catch (error) {\r\n console.error('[MCP-Server] Error handling message:', error);\r\n return {\r\n jsonrpc: '2.0',\r\n id: message.id || null,\r\n error: {\r\n code: -32000,\r\n message: error.message\r\n }\r\n };\r\n }\r\n }\r\n\r\n async start() {\r\n await this.initialize();\r\n\r\n this.rl.on('line', async (line) => {\r\n try {\r\n const message = JSON.parse(line);\r\n const response = await this.handleMessage(message);\r\n console.log(JSON.stringify(response));\r\n } catch (error) {\r\n console.log(JSON.stringify({\r\n jsonrpc: '2.0',\r\n id: null,\r\n error: {\r\n code: -32700,\r\n message: `Parse error: ${error.message}`\r\n }\r\n }));\r\n }\r\n });\r\n\r\n // Cleanup on exit\r\n process.on('SIGINT', async () => {\r\n console.error('[MCP-Server] Shutting down authenticated Playwright MCP Server...');\r\n await this.shutdown();\r\n process.exit(0);\r\n });\r\n\r\n // Log statistics periodically\r\n setInterval(() => {\r\n console.error(`[MCP-Server] Stats: ${this.stats.totalRequests} total, ${this.stats.authorizedRequests} authorized, ${this.stats.rejectedRequests} rejected`);\r\n console.error(`[MCP-Server] Tool usage:`, JSON.stringify(this.stats.toolUsage));\r\n }, 60000); // Every minute\r\n }\r\n\r\n async getStats() {\r\n const authStats = await this.auth.getStats();\r\n return {\r\n server: {\r\n name: 'playwright-mcp-server-authenticated',\r\n uptime: process.uptime(),\r\n ...this.stats\r\n },\r\n authentication: authStats\r\n };\r\n }\r\n\r\n async shutdown() {\r\n try {\r\n if (this.browser) await this.browser.close();\r\n if (this.rl) this.rl.close();\r\n if (this.auth) await this.auth.shutdown();\r\n console.error('[MCP-Server] Shutdown complete');\r\n } catch (error) {\r\n console.error('[MCP-Server] Error during shutdown:', error);\r\n }\r\n }\r\n}\r\n\r\n// Start the server\r\nconst server = new AuthenticatedPlaywrightMCPServer({\r\n redisUrl: process.env.MCP_REDIS_URL,\r\n authRequired: process.env.MCP_AUTH_REQUIRED !== 'false',\r\n rateLimitMax: parseInt(process.env.MCP_RATE_LIMIT_MAX) || 60\r\n});\r\n\r\nserver.start().catch(error => {\r\n console.error('[MCP-Server] Failed to start authenticated Playwright MCP Server:', error);\r\n process.exit(1);\r\n});"],"names":["chromium","require","readline","MCPAuthMiddleware","AuthenticatedPlaywrightMCPServer","options","browser","page","rl","createInterface","input","process","stdin","output","stdout","terminal","auth","redisUrl","env","MCP_REDIS_URL","authRequired","MCP_AUTH_REQUIRED","agentConfigPath","MCP_AGENT_CONFIG","skillConfigPath","MCP_SKILL_CONFIG","rateLimitMax","parseInt","MCP_RATE_LIMIT_MAX","rateLimitWindow","MCP_RATE_LIMIT_WINDOW","tools","take_screenshot","name","description","inputSchema","type","properties","url","filename","fullPage","default","waitTime","required","skillRequirements","search_google","query","screenshot","resultCount","navigate_and_interact","actions","items","enum","selector","value","key","stats","totalRequests","authorizedRequests","rejectedRequests","toolUsage","lastActivity","initialize","console","error","initBrowser","exit","launch","headless","args","newPage","takeScreenshot","agentContext","agentType","goto","waitUntil","timeout","waitForTimeout","timestamp","Date","toISOString","replace","filepath","path","success","title","size","viewportSize","width","height","capturedBy","searchGoogle","waitForSelector","click","e","searchBox","fill","press","results","$$eval","elements","slice","map","el","textContent","trim","screenshotInfo","toLowerCase","length","searchedBy","navigateAndInteract","action","push","duration","message","interactedBy","handleMessage","now","request","headers","params","context","agentToken","body","response","writeHead","end","data","responseData","JSON","parse","authenticationPassed","authenticateRequest","jsonrpc","id","code","method","result","protocolVersion","capabilities","serverInfo","version","authentication","Object","values","toolName","arguments","authenticated","Error","content","text","stringify","start","on","line","log","shutdown","setInterval","getStats","authStats","server","uptime","close","catch"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow-novice",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.16",
|
|
4
4
|
"description": "AI agent orchestration framework with namespace-isolated skills, agents, and CFN Loop validation. Safe installation with ~0.01% collision risk.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|