@ejazullah/browser-mcp 0.0.57 → 0.0.58

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 (61) hide show
  1. package/README.md +2 -0
  2. package/lib/auth.js +82 -1
  3. package/lib/browserContextFactory.js +205 -1
  4. package/lib/browserServerBackend.js +125 -1
  5. package/lib/config.js +266 -1
  6. package/lib/context.js +232 -1
  7. package/lib/databaseLogger.js +264 -1
  8. package/lib/extension/cdpRelay.js +346 -1
  9. package/lib/extension/extensionContextFactory.js +56 -1
  10. package/lib/extension/main.js +26 -1
  11. package/lib/fileUtils.js +32 -1
  12. package/lib/httpServer.js +39 -1
  13. package/lib/index.js +39 -1
  14. package/lib/javascript.js +49 -1
  15. package/lib/log.js +21 -1
  16. package/lib/loop/loop.js +69 -1
  17. package/lib/loop/loopClaude.js +152 -1
  18. package/lib/loop/loopOpenAI.js +143 -1
  19. package/lib/loop/main.js +60 -1
  20. package/lib/loopTools/context.js +66 -1
  21. package/lib/loopTools/main.js +49 -1
  22. package/lib/loopTools/perform.js +32 -1
  23. package/lib/loopTools/snapshot.js +29 -1
  24. package/lib/loopTools/tool.js +18 -1
  25. package/lib/manualPromise.js +111 -1
  26. package/lib/mcp/inProcessTransport.js +72 -1
  27. package/lib/mcp/server.js +93 -1
  28. package/lib/mcp/transport.js +223 -1
  29. package/lib/mongoDBLogger.js +252 -1
  30. package/lib/package.js +20 -1
  31. package/lib/program.js +113 -1
  32. package/lib/response.js +172 -1
  33. package/lib/sessionLog.js +156 -1
  34. package/lib/tab.js +266 -1
  35. package/lib/tools/cdp.js +169 -1
  36. package/lib/tools/common.js +55 -1
  37. package/lib/tools/console.js +33 -1
  38. package/lib/tools/dialogs.js +47 -1
  39. package/lib/tools/evaluate.js +53 -1
  40. package/lib/tools/extraction.js +217 -1
  41. package/lib/tools/files.js +44 -1
  42. package/lib/tools/forms.js +180 -1
  43. package/lib/tools/getext.js +99 -1
  44. package/lib/tools/install.js +53 -1
  45. package/lib/tools/interactions.js +191 -1
  46. package/lib/tools/keyboard.js +86 -1
  47. package/lib/tools/mouse.js +99 -1
  48. package/lib/tools/navigate.js +70 -1
  49. package/lib/tools/network.js +41 -1
  50. package/lib/tools/pdf.js +40 -1
  51. package/lib/tools/screenshot.js +75 -1
  52. package/lib/tools/selectors.js +233 -1
  53. package/lib/tools/snapshot.js +169 -1
  54. package/lib/tools/states.js +147 -1
  55. package/lib/tools/tabs.js +87 -1
  56. package/lib/tools/tool.js +33 -1
  57. package/lib/tools/utils.js +74 -1
  58. package/lib/tools/wait.js +56 -1
  59. package/lib/tools.js +64 -1
  60. package/lib/utils.js +26 -1
  61. package/package.json +2 -2
package/lib/mcp/server.js CHANGED
@@ -1 +1,93 @@
1
- (function(_0x2b0c96,_0x43df36){const _0x1b60f2=_0x2a8c,_0x43d6ac=_0x2b0c96();while(!![]){try{const _0x830372=-parseInt(_0x1b60f2(0x1c4))/0x1+-parseInt(_0x1b60f2(0x1c0))/0x2*(-parseInt(_0x1b60f2(0x1af))/0x3)+-parseInt(_0x1b60f2(0x1d7))/0x4+parseInt(_0x1b60f2(0x1d2))/0x5*(parseInt(_0x1b60f2(0x1ad))/0x6)+parseInt(_0x1b60f2(0x1da))/0x7+-parseInt(_0x1b60f2(0x1c7))/0x8+parseInt(_0x1b60f2(0x1ac))/0x9;if(_0x830372===_0x43df36)break;else _0x43d6ac['push'](_0x43d6ac['shift']());}catch(_0x424eaa){_0x43d6ac['push'](_0x43d6ac['shift']());}}}(_0x5579,0x7e754));const _0x413020=(function(){let _0x95450a=!![];return function(_0x1fa393,_0x193269){const _0x43ad0c=_0x95450a?function(){const _0x8de2b9=_0x2a8c;if(_0x193269){const _0x597440=_0x193269[_0x8de2b9(0x1b0)](_0x1fa393,arguments);return _0x193269=null,_0x597440;}}:function(){};return _0x95450a=![],_0x43ad0c;};}()),_0x3cfd31=_0x413020(this,function(){const _0x34f7d4=_0x2a8c,_0x4680f0={};_0x4680f0[_0x34f7d4(0x1a9)]=_0x34f7d4(0x1df);const _0x293fa2=_0x4680f0;return _0x3cfd31[_0x34f7d4(0x1c1)]()['search'](_0x293fa2[_0x34f7d4(0x1a9)])[_0x34f7d4(0x1c1)]()[_0x34f7d4(0x1dc)](_0x3cfd31)[_0x34f7d4(0x1c8)](_0x293fa2[_0x34f7d4(0x1a9)]);});_0x3cfd31();function _0x5579(){const _0x592ac0=['y2fSBfrVB2W','zMLUza','kcGOlISPkYKRksSK','CMfJzq','BhLfBu0','AM9PBG','qvDnwwq','AgjrqKO','C2v0uMvXDwvZDeHHBMrSzxi','ntu1mJKXmhv0t0Lzsq','ndHkwhnWqwm','Aw5WDxrty2HLBwe','m1rsBLHUBa','yxbWBhK','rxjYB3i6ifrVB2WGiG','C2vYDMvYq2XVC2vK','CgfYyw1Z','qxLRq2e','CgLUzYb0Aw1LB3v0','CMvHze9UBhK','yxjNDw1LBNrZ','Dgv4Da','Dgjtt3O','Dg9VBhm','zgvZDhj1y3rPDMu','zuL5DNu','sK50qK4','BMfTzq','DMvYC2LVBG','mZK3nZGWDMXoD21u','Dg9tDhjPBMC','DgL0Bgu','Aw5PDgLHBgL6zwq','mta3mdyYCwL3CePA','ugv5tKy','iYmJifjLC3vSDaO','ndu4mdmZnNjNBhPwqW','C2vHCMnO','y29UBMvJDa','y2f0y2G','tujdyMm','zgvZy3jPChrPB24','CgfYC2u','wfjgq1i','CgLUzW','DgHLBG','txfTC1O','mtqXmJmWDMXSr0HQ','A29JBeG','y2fWywjPBgL0AwvZ','iIbUB3qGzM91BMq','DhLWzq','mtG0odG0CenrzKvk','seDcse4','Aw5PDgLHBgL6zq','mtqXmZy0m1H3DKfiuW','y2XVC2u','y29UC3rYDwn0B3i'];_0x5579=function(){return _0x592ac0;};return _0x5579();}import{Server}from'@modelcontextprotocol/sdk/server/index.js';import{CallToolRequestSchema,ListToolsRequestSchema}from'@modelcontextprotocol/sdk/types.js';import{zodToJsonSchema}from'zod-to-json-schema';import{ManualPromise}from'../manualPromise.js';import{logUnhandledError}from'../log.js';export async function connect(_0x414569,_0x419f31,_0xa4b1f8){const _0x1330c9=_0x2a8c,_0x4707e8={'lyEmM':function(_0x58c1bd){return _0x58c1bd();},'hbQBJ':function(_0x2ad85e,_0x53efc3,_0x5d8adb){return _0x2ad85e(_0x53efc3,_0x5d8adb);}},_0x2f6cdb=_0x4707e8[_0x1330c9(0x1e1)](_0x414569),_0x1f3310=_0x4707e8[_0x1330c9(0x1aa)](createServer,_0x2f6cdb,_0xa4b1f8);await _0x1f3310[_0x1330c9(0x1c9)](_0x419f31);}export function createServer(_0x56136b,_0x53ed2b){const _0x32ae6c=_0x2a8c,_0x13deac={'JNtBN':function(_0x6747d5,_0x21805c){return _0x6747d5&&_0x21805c;},'HGBHN':function(_0x26e2b9,_0x462a32){return _0x26e2b9(_0x462a32);},'MBCbc':function(_0x3e03a0,_0x28cd8c){return _0x3e03a0(_0x28cd8c);},'MqmsZ':function(_0x46eb3a,_0x676d40){return _0x46eb3a(_0x676d40);},'PeyNF':function(_0x39c3a8,_0x56d869){return _0x39c3a8(_0x56d869);},'XRFCR':function(_0x79d2e8,_0x1f77bd,_0x5d682d,_0x383e85){return _0x79d2e8(_0x1f77bd,_0x5d682d,_0x383e85);},'koclH':_0x32ae6c(0x1c3),'eIyvu':function(_0x1f8b25,_0x43def7,_0x1a7c1f,_0x259617){return _0x1f8b25(_0x43def7,_0x1a7c1f,_0x259617);},'tbSOz':_0x32ae6c(0x1db)},_0x224dda=new ManualPromise(),_0x3dd6b6={};_0x3dd6b6[_0x32ae6c(0x1be)]=_0x56136b[_0x32ae6c(0x1be)],_0x3dd6b6[_0x32ae6c(0x1bf)]=_0x56136b[_0x32ae6c(0x1bf)];const _0x1db152={};_0x1db152[_0x32ae6c(0x1ba)]={};const _0x14db74={};_0x14db74[_0x32ae6c(0x1d4)]=_0x1db152;const _0x5ac5f1=new Server(_0x3dd6b6,_0x14db74),_0x120169=_0x56136b[_0x32ae6c(0x1ba)]();_0x5ac5f1[_0x32ae6c(0x1ab)](ListToolsRequestSchema,async()=>{const _0x3d32a6=_0x32ae6c;return{'tools':_0x120169['map'](_0x2f2be7=>({'name':_0x2f2be7[_0x3d32a6(0x1be)],'description':_0x2f2be7[_0x3d32a6(0x1cc)],'inputSchema':zodToJsonSchema(_0x2f2be7[_0x3d32a6(0x1ae)]),'annotations':{'title':_0x2f2be7[_0x3d32a6(0x1c2)],'readOnlyHint':_0x2f2be7[_0x3d32a6(0x1d6)]===_0x3d32a6(0x1b6),'destructiveHint':_0x2f2be7[_0x3d32a6(0x1d6)]===_0x3d32a6(0x1bb),'openWorldHint':!![]}}))};});let _0x4eaace=![];return _0x5ac5f1[_0x32ae6c(0x1ab)](CallToolRequestSchema,async _0x2676a7=>{const _0xbd6247=_0x32ae6c;await _0x224dda;_0x13deac[_0xbd6247(0x1bd)](_0x53ed2b,!_0x4eaace)&&(_0x4eaace=!![],_0x13deac[_0xbd6247(0x1d8)](startHeartbeat,_0x5ac5f1));const _0x8db7b4=(..._0x53206f)=>({'content':[{'type':_0xbd6247(0x1b8),'text':_0xbd6247(0x1c6)+_0x53206f[_0xbd6247(0x1e2)]('\x0a')}],'isError':!![]}),_0x2a0647=_0x120169[_0xbd6247(0x1de)](_0x36402b=>_0x36402b[_0xbd6247(0x1be)]===_0x2676a7[_0xbd6247(0x1b3)][_0xbd6247(0x1be)]);if(!_0x2a0647)return _0x13deac[_0xbd6247(0x1cb)](_0x8db7b4,_0xbd6247(0x1b1)+_0x2676a7[_0xbd6247(0x1b3)][_0xbd6247(0x1be)]+_0xbd6247(0x1d5));try{return await _0x56136b[_0xbd6247(0x1dd)](_0x2a0647,_0x2a0647[_0xbd6247(0x1ae)][_0xbd6247(0x1cd)](_0x2676a7[_0xbd6247(0x1b3)][_0xbd6247(0x1b7)]||{}));}catch(_0x13e39c){return _0x13deac[_0xbd6247(0x1d1)](_0x8db7b4,_0x13deac[_0xbd6247(0x1c5)](String,_0x13e39c));}}),_0x13deac[_0x32ae6c(0x1ce)](addServerListener,_0x5ac5f1,_0x13deac[_0x32ae6c(0x1d3)],()=>{const _0x5e427c=_0x32ae6c;_0x56136b[_0x5e427c(0x1d9)]?.(_0x5ac5f1)[_0x5e427c(0x1d0)](()=>_0x224dda['resolve']())[_0x5e427c(0x1ca)](logUnhandledError);}),_0x13deac[_0x32ae6c(0x1bc)](addServerListener,_0x5ac5f1,_0x13deac[_0x32ae6c(0x1b9)],()=>_0x56136b[_0x32ae6c(0x1b2)]?.()),_0x5ac5f1;}function _0x2a8c(_0x39e400,_0x2d78ec){_0x39e400=_0x39e400-0x1a9;const _0xa1f074=_0x5579();let _0x3cfd31=_0xa1f074[_0x39e400];if(_0x2a8c['HoHKvu']===undefined){var _0x413020=function(_0x120673){const _0x9d1c7d='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2b4f79='',_0xd76742='',_0x37c7fc=_0x2b4f79+_0x413020;for(let _0x42f03b=0x0,_0x2b586c,_0x516569,_0x20fce7=0x0;_0x516569=_0x120673['charAt'](_0x20fce7++);~_0x516569&&(_0x2b586c=_0x42f03b%0x4?_0x2b586c*0x40+_0x516569:_0x516569,_0x42f03b++%0x4)?_0x2b4f79+=_0x37c7fc['charCodeAt'](_0x20fce7+0xa)-0xa!==0x0?String['fromCharCode'](0xff&_0x2b586c>>(-0x2*_0x42f03b&0x6)):_0x42f03b:0x0){_0x516569=_0x9d1c7d['indexOf'](_0x516569);}for(let _0x5da767=0x0,_0x1c3d3d=_0x2b4f79['length'];_0x5da767<_0x1c3d3d;_0x5da767++){_0xd76742+='%'+('00'+_0x2b4f79['charCodeAt'](_0x5da767)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xd76742);};_0x2a8c['jPEzQJ']=_0x413020,_0x2a8c['HSqaLa']={},_0x2a8c['HoHKvu']=!![];}const _0x557939=_0xa1f074[0x0],_0x2a8c1a=_0x39e400+_0x557939,_0x3d90bb=_0x2a8c['HSqaLa'][_0x2a8c1a];if(!_0x3d90bb){const _0x1239fd=function(_0xaba08a){this['DiLUBu']=_0xaba08a,this['SxfbAS']=[0x1,0x0,0x0],this['aPSTsz']=function(){return'newState';},this['uSVTVk']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['Vognmz']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x1239fd['prototype']['QNfORZ']=function(){const _0x1f99b0=new RegExp(this['uSVTVk']+this['Vognmz']),_0x6d1ed9=_0x1f99b0['test'](this['aPSTsz']['toString']())?--this['SxfbAS'][0x1]:--this['SxfbAS'][0x0];return this['vcEgoc'](_0x6d1ed9);},_0x1239fd['prototype']['vcEgoc']=function(_0x5e8d0b){if(!Boolean(~_0x5e8d0b))return _0x5e8d0b;return this['ORNErW'](this['DiLUBu']);},_0x1239fd['prototype']['ORNErW']=function(_0x360825){for(let _0x38611c=0x0,_0x11c047=this['SxfbAS']['length'];_0x38611c<_0x11c047;_0x38611c++){this['SxfbAS']['push'](Math['round'](Math['random']())),_0x11c047=this['SxfbAS']['length'];}return _0x360825(this['SxfbAS'][0x0]);},new _0x1239fd(_0x2a8c)['QNfORZ'](),_0x3cfd31=_0x2a8c['jPEzQJ'](_0x3cfd31),_0x2a8c['HSqaLa'][_0x2a8c1a]=_0x3cfd31;}else _0x3cfd31=_0x3d90bb;return _0x3cfd31;}const startHeartbeat=_0x4ea034=>{const _0x53e8d9={'wdQGD':function(_0x186f84,_0x353d40,_0x1ec006){return _0x186f84(_0x353d40,_0x1ec006);}},_0x21dcfc=()=>{const _0x205155=_0x2a8c;Promise[_0x205155(0x1e0)]([_0x4ea034[_0x205155(0x1cf)](),new Promise((_0x5cf27d,_0x1a8392)=>setTimeout(()=>_0x1a8392(new Error(_0x205155(0x1b5))),0x1388))])[_0x205155(0x1d0)](()=>{_0x53e8d9['wdQGD'](setTimeout,_0x21dcfc,0xbb8);})['catch'](()=>{const _0x579f2e=_0x205155;void _0x4ea034[_0x579f2e(0x1db)]();});};_0x21dcfc();};function addServerListener(_0x173dcf,_0x321133,_0x11a676){const _0x535821={'AykCa':function(_0x1039ea){return _0x1039ea?.();}},_0x492d7b=_0x173dcf['on'+_0x321133];_0x173dcf['on'+_0x321133]=()=>{const _0x11bf5a=_0x2a8c;_0x535821[_0x11bf5a(0x1b4)](_0x492d7b),_0x11a676();};}
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
17
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
18
+ import { zodToJsonSchema } from 'zod-to-json-schema';
19
+ import { ManualPromise } from '../manualPromise.js';
20
+ import { logUnhandledError } from '../log.js';
21
+ export async function connect(serverBackendFactory, transport, runHeartbeat) {
22
+ const backend = serverBackendFactory();
23
+ const server = createServer(backend, runHeartbeat);
24
+ await server.connect(transport);
25
+ }
26
+ export function createServer(backend, runHeartbeat) {
27
+ const initializedPromise = new ManualPromise();
28
+ const server = new Server({ name: backend.name, version: backend.version }, {
29
+ capabilities: {
30
+ tools: {},
31
+ }
32
+ });
33
+ const tools = backend.tools();
34
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
35
+ return { tools: tools.map(tool => ({
36
+ name: tool.name,
37
+ description: tool.description,
38
+ inputSchema: zodToJsonSchema(tool.inputSchema),
39
+ annotations: {
40
+ title: tool.title,
41
+ readOnlyHint: tool.type === 'readOnly',
42
+ destructiveHint: tool.type === 'destructive',
43
+ openWorldHint: true,
44
+ },
45
+ })) };
46
+ });
47
+ let heartbeatRunning = false;
48
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
49
+ await initializedPromise;
50
+ if (runHeartbeat && !heartbeatRunning) {
51
+ heartbeatRunning = true;
52
+ startHeartbeat(server);
53
+ }
54
+ const errorResult = (...messages) => ({
55
+ content: [{ type: 'text', text: '### Result\n' + messages.join('\n') }],
56
+ isError: true,
57
+ });
58
+ const tool = tools.find(tool => tool.name === request.params.name);
59
+ if (!tool)
60
+ return errorResult(`Error: Tool "${request.params.name}" not found`);
61
+ try {
62
+ return await backend.callTool(tool, tool.inputSchema.parse(request.params.arguments || {}));
63
+ }
64
+ catch (error) {
65
+ return errorResult(String(error));
66
+ }
67
+ });
68
+ addServerListener(server, 'initialized', () => {
69
+ backend.initialize?.(server).then(() => initializedPromise.resolve()).catch(logUnhandledError);
70
+ });
71
+ addServerListener(server, 'close', () => backend.serverClosed?.());
72
+ return server;
73
+ }
74
+ const startHeartbeat = (server) => {
75
+ const beat = () => {
76
+ Promise.race([
77
+ server.ping(),
78
+ new Promise((_, reject) => setTimeout(() => reject(new Error('ping timeout')), 5000)),
79
+ ]).then(() => {
80
+ setTimeout(beat, 3000);
81
+ }).catch(() => {
82
+ void server.close();
83
+ });
84
+ };
85
+ beat();
86
+ };
87
+ function addServerListener(server, event, listener) {
88
+ const oldListener = server[`on${event}`];
89
+ server[`on${event}`] = () => {
90
+ oldListener?.();
91
+ listener();
92
+ };
93
+ }
@@ -1 +1,223 @@
1
- const _0x11aebd=_0x2e0b;(function(_0x303313,_0xbaa3ed){const _0x31e0f7=_0x2e0b,_0x5064c5=_0x303313();while(!![]){try{const _0x89b8b0=parseInt(_0x31e0f7(0x110))/0x1+-parseInt(_0x31e0f7(0x15a))/0x2+-parseInt(_0x31e0f7(0x16e))/0x3+parseInt(_0x31e0f7(0x10f))/0x4*(-parseInt(_0x31e0f7(0x12a))/0x5)+parseInt(_0x31e0f7(0x122))/0x6+-parseInt(_0x31e0f7(0x172))/0x7+-parseInt(_0x31e0f7(0x15c))/0x8*(-parseInt(_0x31e0f7(0x171))/0x9);if(_0x89b8b0===_0xbaa3ed)break;else _0x5064c5['push'](_0x5064c5['shift']());}catch(_0x14dc29){_0x5064c5['push'](_0x5064c5['shift']());}}}(_0x754f,0x44553));const _0x500883=(function(){let _0x38c021=!![];return function(_0x12966e,_0x54c5d7){const _0xaf74b5=_0x38c021?function(){const _0x429809=_0x2e0b;if(_0x54c5d7){const _0xcb0b5a=_0x54c5d7[_0x429809(0x11d)](_0x12966e,arguments);return _0x54c5d7=null,_0xcb0b5a;}}:function(){};return _0x38c021=![],_0xaf74b5;};}()),_0x306622=_0x500883(this,function(){const _0x274483=_0x2e0b,_0x212502={};_0x212502[_0x274483(0x177)]=_0x274483(0x138);const _0x29fa3e=_0x212502;return _0x306622[_0x274483(0x120)]()[_0x274483(0x121)](_0x274483(0x138))[_0x274483(0x120)]()[_0x274483(0x176)](_0x306622)['search'](_0x29fa3e[_0x274483(0x177)]);});_0x306622();import _0x2a0046 from'crypto';import _0x420e7a from'debug';import _0x539fc8 from'cors';import{readFileSync}from'fs';import{fileURLToPath}from'url';function _0x2e0b(_0x5787b0,_0x13778b){_0x5787b0=_0x5787b0-0x10c;const _0x33a5b8=_0x754f();let _0x306622=_0x33a5b8[_0x5787b0];if(_0x2e0b['eWWdja']===undefined){var _0x500883=function(_0x5831c3){const _0x32a8ef='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3fe359='',_0x464bf6='',_0x29df17=_0x3fe359+_0x500883;for(let _0x5cddf3=0x0,_0x28647a,_0x72d6e0,_0x160459=0x0;_0x72d6e0=_0x5831c3['charAt'](_0x160459++);~_0x72d6e0&&(_0x28647a=_0x5cddf3%0x4?_0x28647a*0x40+_0x72d6e0:_0x72d6e0,_0x5cddf3++%0x4)?_0x3fe359+=_0x29df17['charCodeAt'](_0x160459+0xa)-0xa!==0x0?String['fromCharCode'](0xff&_0x28647a>>(-0x2*_0x5cddf3&0x6)):_0x5cddf3:0x0){_0x72d6e0=_0x32a8ef['indexOf'](_0x72d6e0);}for(let _0x4a5e48=0x0,_0x4e25bf=_0x3fe359['length'];_0x4a5e48<_0x4e25bf;_0x4a5e48++){_0x464bf6+='%'+('00'+_0x3fe359['charCodeAt'](_0x4a5e48)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x464bf6);};_0x2e0b['cVIgRV']=_0x500883,_0x2e0b['RYKNaj']={},_0x2e0b['eWWdja']=!![];}const _0x754f62=_0x33a5b8[0x0],_0x2e0b20=_0x5787b0+_0x754f62,_0x204352=_0x2e0b['RYKNaj'][_0x2e0b20];if(!_0x204352){const _0x414721=function(_0x340fb2){this['KwMghf']=_0x340fb2,this['TouFLN']=[0x1,0x0,0x0],this['cTuLZI']=function(){return'newState';},this['vzixrm']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['DbSGWN']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x414721['prototype']['jQNsuO']=function(){const _0x4bb26c=new RegExp(this['vzixrm']+this['DbSGWN']),_0x282a47=_0x4bb26c['test'](this['cTuLZI']['toString']())?--this['TouFLN'][0x1]:--this['TouFLN'][0x0];return this['HXPrIV'](_0x282a47);},_0x414721['prototype']['HXPrIV']=function(_0x5b74f3){if(!Boolean(~_0x5b74f3))return _0x5b74f3;return this['rjhIgs'](this['KwMghf']);},_0x414721['prototype']['rjhIgs']=function(_0x7fac4a){for(let _0x55516b=0x0,_0x2172fc=this['TouFLN']['length'];_0x55516b<_0x2172fc;_0x55516b++){this['TouFLN']['push'](Math['round'](Math['random']())),_0x2172fc=this['TouFLN']['length'];}return _0x7fac4a(this['TouFLN'][0x0]);},new _0x414721(_0x2e0b)['jQNsuO'](),_0x306622=_0x2e0b['cVIgRV'](_0x306622),_0x2e0b['RYKNaj'][_0x2e0b20]=_0x306622;}else _0x306622=_0x204352;return _0x306622;}import{dirname,join}from'path';import{SSEServerTransport}from'@modelcontextprotocol/sdk/server/sse.js';function _0x754f(){const _0x2abd2e=['mJG5nJiWnMXvtLzUsG','q29UDgvUDc1uExbL','wwPTAK4','zgvSzxrLigH0DhaGC2vZC2LVBJOG','r2rqtgG','icHHDxrOigvUywjSzwqP','zgvSzxrLifntrsbZzxnZAw9UoIa','Bwv0Ag9K','nta2nJuWsKrWALrp','twv0Ag9Kig5VDcbHBgXVD2vK','l29HDxrOl3rVA2vUicaGicaGicaGic0Gr2v0igfJy2vZCYb0B2TLBG','l29Wzw5HCgKUANnVBG','CMfUzg9Tvvvjra','s1jjDNu','yxbWBgLJyxrPB24VANnVBG','qwnJzxnZlunVBNrYB2WTqwXSB3CTt3jPz2LU','BNffqKK','BhHeEK8','rKzuueu','C3rHCNrZv2L0Aa','l29HDxrOl2f1DgHVCML6zsaGicaGicaTief1DgHVCML6yxrPB24Gy29KzsbMBg93','Cg9YDa','kcGOlISPkYKRksSK','C2v0sgvHzgvY','DxrMoa','r1zbBMe','yxv0AgvUDgLJyxrLuMvXDwvZDa','Egjvqvi','CMvXDwvZDa','zxjYB3i','rM9YigXLz2fJEsbtu0uGDhjHBNnWB3j0ihn1ChbVCNqSihLVDsbJyw4GDxnLihrOzsaVC3nLigvUzhbVAw50igLUC3rLywqU','DgXZs2m','AgfUzgXLuMvXDwvZDa','EfbhELG','EKLNzhm','B2LnB3m','BKzvzxu','AgvHzgvYCW','ChC6BwnWoNrLC3q','l21JCa','B25JBg9Zzq','veXqs0O','ELPWtgu','v3zqzNy','r0vu','zw5HyMXLza','zgvSzxrL','AgfUzgXLug9ZDe1LC3nHz2u','BKT1qMq','BK5pD28','A1btsfq','wLffEfy','y2XVC2u','t1busu9ouW','C2vHCMnOugfYyw1Z','t3bLBKfqssbZCgvJAwzPy2f0Aw9Uig5VDcbMB3vUza','ntq1oduWwhnlrfnT','lY53zwXSlwTUB3DUl29HDxrOlwf1DgHVCML6yxrPB24TC2vYDMvYic0Gt0f1DgGGBwv0ywrHDge','ndy3ntCZnMvoBwjQuq','y3jLyxrLigH0DhaGC2vZC2LVBJOG','zw5K','qxv0Ag9YAxPHDgLVBG','Bxverey','l3nZzq','DxjS','DezSrxm','tgLZDgvUAw5Nig9Uia','z2v0','C2v0','swvzDe0','icbhrvqGia','l29HDxrOl3rVA2vUlwLUzM8GicaGicaTieLUDhjVC3bLy3qGDg9Rzw4','ue9tva','zMHWAum','y3jLyxrLifntrsbZzxnZAw9UoIa','Cgf0Ag5HBwu','mta2mJu5neHlrezdAq','ywrKCMvZCW','EWOGicjVCgvUyxbPiJOGiJmUmc4ZiIWkicaIAw5MBYi6ihSkicaGicj0AxrSzsi6icjnq1aGugXHExDYAwDODcbcCM93C2vYief1Dg9TyxrPB24GqvbjiIWkicaGicjKzxnJCMLWDgLVBIi6icjfBMHHBMnLzcbqBgf5D3jPz2H0ifrVB2XZigzVCIbnB2rLBcbdB250zxH0ifbYB3rVy29SicHnq1aPihDPDgGGq0rqifn1ChbVCNqUifbYB3zPzgvZigjYB3DZzxiGyxv0B21HDgLVBIbJyxbHyMLSAxrPzxmGAw5JBhvKAw5Nig5HDMLNyxrPB24SigLUDgvYywn0Aw9UlcbLEhrYywn0Aw9UlcbHBMqGDgvZDgLUzY4IlaOGicaGiNzLCNnPB24IoIaImc4WlJm2iIWkicaGicjJB250ywn0iJOGEWOGicaGicaIBMfTzsi6icjfAMf6ifvSBgfOiIWkicaGicaGiMvTywLSiJOGiMvQyxP1BgXHAebLEgfTCgXLlMnVBsiScIaGicaGicj1CMWIoIaIAhr0Chm6lY9NAxrODwiUy29Tl2vQyxP1BgXHAc9Ty3aTCgXHExDYAwDODcikicaGih0ScIaGicaIBgLJzw5Zzsi6ihSkicaGicaGiM5HBwuIoIaIqxbHy2HLltiUmciScIaGicaGicj1CMWIoIaIAhr0Chm6lY93D3CUyxbHy2HLlM9YzY9SAwnLBNnLCY9msunftLnfltiUmcikicaGih0kicb9laOGicjZzxj2zxjZiJOGwWOGicaGEWOGicaGicaIDxjSiJOGiMH0DhbZoI8VBwnWlMrVAw5NzxjWlMnVBsiScIaGicaGicjKzxnJCMLWDgLVBIi6icjqCM9KDwn0Aw9Uie1ducbqBgf5D3jPz2H0ifnLCNzLCIikicaGih0ScIaGicb7cIaGicaGicj1CMWIoIaIAhr0CdOVl2XVy2fSAg9ZDdO4otmXiIWkicaGicaGiMrLC2nYAxb0Aw9UiJOGiKXVy2fSierLDMvSB3bTzw50ifnLCNzLCIikicaGih0kicbDlaOGicjPBMzViJOGEWOGicaGiMrLC2nYAxb0Aw9UiJOGiLrOAxmGqvbjihbYB3zPzgvZigjYB3DZzxiGyxv0B21HDgLVBIb0B29SCYb0AhjVDwDOie1ducaOtw9KzwWGq29UDgv4DcbqCM90B2nVBcKUiefSBcbLBMrWB2LUDhmGywnJzxb0ifbpu1qGCMvXDwvZDhmGD2L0Acbku09oihbHEwXVywrZigfUzcbYzxr1CM4GC3rYDwn0DxjLzcbYzxnWB25ZzxmUiGOGih0kFq','ouzpENPAAW','nJyWnJuZDwX6yuTr','u2vZC2LVBIbUB3qGzM91BMq','C2vZC2LVBKLK','C3rHDhvZq29Kzq','y29UC3rYDwn0B3i','tLbks24','BMniD3a','q0roEMu','AKHmwhK','oevksffuAa','mtm2odG1Eg50rujR','BwnWlxnLC3nPB24TAwq','txfgCvO','Ahr0CdOVl2XVy2fSAg9ZDa','vvvzD3i','BwfzyLO','C3rYAw5NAwz5','seDTB1u','y29UBMvJDa','qxnTEhK','uxjWsKq','icbqt1nuia','twLZC2LUzYbZzxnZAw9Uswq','yxbWBhK','EuLPzfy','wc1bueKTs2v5','Dg9tDhjPBMC','C2vHCMnO'];_0x754f=function(){return _0x2abd2e;};return _0x754f();}import{StreamableHTTPServerTransport}from'@modelcontextprotocol/sdk/server/streamableHttp.js';import{StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import{httpAddressToString,startHttpServer}from'../httpServer.js';import*as _0x220bd0 from'./server.js';import{AuthManager,defaultAuthConfig}from'../auth.js';export async function start(_0x89e3e9,_0x50a825,_0x2f4b11){const _0x5b2eae=_0x2e0b,_0x3ccfc8={'GYIeD':function(_0x27771f,_0x88bc7e){return _0x27771f!==_0x88bc7e;},'maYbZ':function(_0xbcc472){return _0xbcc472();},'WvPfv':function(_0x20cead,_0x420e75){return _0x20cead(_0x420e75);}};if(_0x3ccfc8['GYIeD'](_0x50a825[_0x5b2eae(0x137)],undefined)){const _0x5a47f5=await startHttpServer(_0x50a825),_0x1d9402=new AuthManager(_0x2f4b11??_0x3ccfc8[_0x5b2eae(0x115)](defaultAuthConfig));startHttpTransport(_0x5a47f5,_0x89e3e9,_0x1d9402);}else await _0x3ccfc8[_0x5b2eae(0x14d)](startStdioTransport,_0x89e3e9);}async function startStdioTransport(_0x5a7623){const _0x242e4a=_0x2e0b;await _0x220bd0[_0x242e4a(0x118)](_0x5a7623,new StdioServerTransport(),![]);}const testDebug=_0x420e7a(_0x11aebd(0x148)),__filename=fileURLToPath(import.meta.url),__dirname=dirname(__filename),embeddedOpenApiSpec=_0x11aebd(0x170);async function handleOpenAPI(_0x42bafc,_0x53ac58){const _0x9ecc2b=_0x11aebd,_0x17f0d9={'muDDF':function(_0xafaf4c,_0x2ba1d0){return _0xafaf4c!==_0x2ba1d0;},'FFTPE':_0x9ecc2b(0x14e),'QrpJD':function(_0x42b033,_0x1ee22e,_0x48f668){return _0x42b033(_0x1ee22e,_0x48f668);},'nNOwo':'../../openapi.json','nqEBI':_0x9ecc2b(0x13a),'GdPLh':_0x9ecc2b(0x131)};if(_0x17f0d9[_0x9ecc2b(0x160)](_0x42bafc[_0x9ecc2b(0x129)],_0x17f0d9[_0x9ecc2b(0x134)])){_0x53ac58[_0x9ecc2b(0x175)]=0x195,_0x53ac58[_0x9ecc2b(0x15e)](_0x9ecc2b(0x12b));return;}try{const _0x5beaae=_0x17f0d9[_0x9ecc2b(0x11a)](join,__dirname,_0x17f0d9[_0x9ecc2b(0x153)]);let _0x23121a;try{_0x23121a=_0x17f0d9[_0x9ecc2b(0x11a)](readFileSync,_0x5beaae,_0x17f0d9[_0x9ecc2b(0x132)]);}catch{_0x23121a=embeddedOpenApiSpec;}_0x53ac58[_0x9ecc2b(0x139)](_0x9ecc2b(0x123),_0x9ecc2b(0x130)),_0x53ac58[_0x9ecc2b(0x139)](_0x17f0d9[_0x9ecc2b(0x126)],'*'),_0x53ac58[_0x9ecc2b(0x175)]=0xc8,_0x53ac58[_0x9ecc2b(0x15e)](_0x23121a);}catch(_0x2fe062){_0x53ac58['statusCode']=0x1f4,_0x53ac58['end'](_0x9ecc2b(0x159));}}async function handleSSE(_0x136715,_0x3686f9,_0x241d72,_0x310fe2,_0x48c036){const _0x1af603=_0x11aebd,_0xea4a1b={'oiMos':function(_0x2e433c,_0x4ab268){return _0x2e433c(_0x4ab268);},'yIidV':function(_0x1116b4,_0x98d26a){return _0x1116b4===_0x98d26a;},'IeYtM':'POST','jHLXy':'sessionId','ZQExV':_0x1af603(0x11c),'nKuBd':_0x1af603(0x173),'TLPKJ':_0x1af603(0x14e),'tFlEs':_0x1af603(0x161),'lxDzO':_0x1af603(0x156),'fhpiC':_0x1af603(0x12b)};if(_0xea4a1b[_0x1af603(0x11e)](_0x3686f9[_0x1af603(0x129)],_0xea4a1b[_0x1af603(0x167)])){const _0x724c13=_0x310fe2[_0x1af603(0x158)][_0x1af603(0x165)](_0xea4a1b[_0x1af603(0x10e)]);if(!_0x724c13)return _0x241d72[_0x1af603(0x175)]=0x190,_0x241d72[_0x1af603(0x15e)](_0xea4a1b[_0x1af603(0x155)]);const _0x38ac50=_0x48c036[_0x1af603(0x165)](_0x724c13);if(!_0x38ac50)return _0x241d72[_0x1af603(0x175)]=0x194,_0x241d72[_0x1af603(0x15e)](_0xea4a1b[_0x1af603(0x152)]);return await _0x38ac50[_0x1af603(0x151)](_0x3686f9,_0x241d72);}else{if(_0xea4a1b[_0x1af603(0x11e)](_0x3686f9[_0x1af603(0x129)],_0xea4a1b[_0x1af603(0x14b)])){const _0x1cd4c2=new SSEServerTransport(_0xea4a1b[_0x1af603(0x163)],_0x241d72);_0x48c036[_0x1af603(0x166)](_0x1cd4c2[_0x1af603(0x174)],_0x1cd4c2),testDebug(_0x1af603(0x16c)+_0x1cd4c2[_0x1af603(0x174)]),await _0x220bd0[_0x1af603(0x118)](_0x136715,_0x1cd4c2,![]),_0x241d72['on'](_0xea4a1b[_0x1af603(0x133)],()=>{const _0x2bde14=_0x1af603;_0xea4a1b[_0x2bde14(0x145)](testDebug,_0x2bde14(0x128)+_0x1cd4c2[_0x2bde14(0x174)]),_0x48c036[_0x2bde14(0x150)](_0x1cd4c2[_0x2bde14(0x174)]);});return;}}_0x241d72[_0x1af603(0x175)]=0x195,_0x241d72[_0x1af603(0x15e)](_0xea4a1b[_0x1af603(0x16b)]);}async function handleStreamable(_0x193121,_0x12e86d,_0x4fa74,_0x2828d3){const _0x36e53d=_0x11aebd,_0x268f53={'pFdFJ':function(_0x381019,_0x3ba389){return _0x381019(_0x3ba389);},'xbUAR':_0x36e53d(0x111),'ncHwp':'Session\x20not\x20found','CHByh':_0x36e53d(0x16a),'nFUeu':'Invalid\x20request'},_0x35195b=_0x12e86d[_0x36e53d(0x147)][_0x268f53[_0x36e53d(0x13d)]];if(_0x35195b){const _0x5dfc37=_0x2828d3[_0x36e53d(0x165)](_0x35195b);if(!_0x5dfc37){_0x4fa74[_0x36e53d(0x175)]=0x194,_0x4fa74[_0x36e53d(0x15e)](_0x268f53[_0x36e53d(0x10c)]);return;}return await _0x5dfc37[_0x36e53d(0x142)](_0x12e86d,_0x4fa74);}if(_0x12e86d[_0x36e53d(0x129)]===_0x268f53['CHByh']){const _0x4f0281=new StreamableHTTPServerTransport({'sessionIdGenerator':()=>_0x2a0046[_0x36e53d(0x12e)](),'onsessioninitialized':async _0x27faae=>{const _0x1dc20d=_0x36e53d;_0x268f53['pFdFJ'](testDebug,_0x1dc20d(0x15d)+_0x4f0281[_0x1dc20d(0x174)]),await _0x220bd0[_0x1dc20d(0x118)](_0x193121,_0x4f0281,!![]),_0x2828d3['set'](_0x27faae,_0x4f0281);}});_0x4f0281[_0x36e53d(0x14a)]=()=>{const _0xff713d=_0x36e53d;if(!_0x4f0281[_0xff713d(0x174)])return;_0x2828d3[_0xff713d(0x150)](_0x4f0281[_0xff713d(0x174)]),testDebug(_0xff713d(0x125)+_0x4f0281['sessionId']);},await _0x4f0281[_0x36e53d(0x142)](_0x12e86d,_0x4fa74);return;}_0x4fa74[_0x36e53d(0x175)]=0x190,_0x4fa74[_0x36e53d(0x15e)](_0x268f53[_0x36e53d(0x146)]);}function startHttpTransport(_0x2ccd35,_0x1136d1,_0x3ec57b){const _0x38fe74=_0x11aebd,_0x1f745b={'Asmxy':_0x38fe74(0x12d),'YjmjN':function(_0x14617b,_0x2d4860,_0x51b1db){return _0x14617b(_0x2d4860,_0x51b1db);},'kPSHT':_0x38fe74(0x161),'KRIvu':function(_0x40a834,_0x28511d,_0x1be0c8,_0x4683c3,_0x5528f5,_0x2b26a9){return _0x40a834(_0x28511d,_0x1be0c8,_0x4683c3,_0x5528f5,_0x2b26a9);},'zZpLe':function(_0x202b32,_0x201dad,_0x185020,_0x2914d9){return _0x202b32(_0x201dad,_0x185020,_0x2914d9);},'MqFqZ':function(_0x15bcdf,_0x1675af){return _0x15bcdf(_0x1675af);},'xPGzX':_0x38fe74(0x14e),'GVAna':_0x38fe74(0x157),'tlsKc':_0x38fe74(0x123),'jTUrB':_0x38fe74(0x15f),'CDNze':_0x38fe74(0x111),'HGmoU':_0x38fe74(0x13e),'zIgds':'Put\x20this\x20in\x20your\x20client\x20config:','dViOG':_0x38fe74(0x140),'UUYwr':'Auth\x20endpoints:'},_0x397374=new Map(),_0x158ebd=new Map(),_0x402433=_0x1f745b[_0x38fe74(0x112)](_0x539fc8,{'origin':!![],'methods':[_0x1f745b[_0x38fe74(0x143)],_0x38fe74(0x16a),_0x1f745b[_0x38fe74(0x13b)]],'allowedHeaders':[_0x1f745b[_0x38fe74(0x141)],_0x1f745b['jTUrB'],_0x1f745b[_0x38fe74(0x10d)],_0x38fe74(0x11f)],'credentials':!![],'preflightContinue':![],'optionsSuccessStatus':0xcc});_0x2ccd35['on'](_0x1f745b[_0x38fe74(0x117)],async(_0x301ddc,_0x1ca2f7)=>{const _0x15e4ee=_0x38fe74;_0x1f745b[_0x15e4ee(0x14c)](_0x402433,_0x301ddc,_0x1ca2f7,async()=>{const _0x130613=_0x15e4ee,_0x1322e5=new URL(_0x130613(0x113)+_0x301ddc[_0x130613(0x162)]);if(_0x1322e5[_0x130613(0x16d)]===_0x1f745b[_0x130613(0x119)]){await _0x1f745b[_0x130613(0x124)](handleOpenAPI,_0x301ddc,_0x1ca2f7);return;}if(await _0x3ec57b[_0x130613(0x13c)](_0x301ddc,_0x1ca2f7))return;if(_0x1322e5['pathname'][_0x130613(0x135)](_0x1f745b[_0x130613(0x154)]))await _0x1f745b[_0x130613(0x12f)](handleSSE,_0x1136d1,_0x301ddc,_0x1ca2f7,_0x1322e5,_0x397374);else await handleStreamable(_0x1136d1,_0x301ddc,_0x1ca2f7,_0x158ebd);});});const _0x2e9995=httpAddressToString(_0x2ccd35[_0x38fe74(0x16f)]()),_0x5678cd=_0x3ec57b[_0x38fe74(0x14f)]?_0x38fe74(0x127):'',_0x57801d=[_0x38fe74(0x164)+_0x2e9995+_0x5678cd,_0x1f745b[_0x38fe74(0x144)],JSON[_0x38fe74(0x116)]({'mcpServers':{'playwright':{'url':_0x2e9995+_0x38fe74(0x149)}}},undefined,0x2),_0x1f745b['dViOG'],..._0x3ec57b[_0x38fe74(0x14f)]?['',_0x1f745b[_0x38fe74(0x114)],_0x38fe74(0x11b)+_0x2e9995+_0x38fe74(0x12c),_0x38fe74(0x168)+_0x2e9995+_0x38fe74(0x136),'\x20\x20GET\x20\x20'+_0x2e9995+_0x38fe74(0x169),_0x38fe74(0x168)+_0x2e9995+_0x38fe74(0x15b)]:[]]['join']('\x0a');console[_0x38fe74(0x13f)](_0x57801d);}
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import crypto from 'crypto';
17
+ import debug from 'debug';
18
+ import cors from 'cors';
19
+ import { readFileSync } from 'fs';
20
+ import { fileURLToPath } from 'url';
21
+ import { dirname, join } from 'path';
22
+ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
23
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
24
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
25
+ import { httpAddressToString, startHttpServer } from '../httpServer.js';
26
+ import * as mcpServer from './server.js';
27
+ import { AuthManager, defaultAuthConfig } from '../auth.js';
28
+ export async function start(serverBackendFactory, options, authConfig) {
29
+ if (options.port !== undefined) {
30
+ const httpServer = await startHttpServer(options);
31
+ const auth = new AuthManager(authConfig ?? defaultAuthConfig());
32
+ startHttpTransport(httpServer, serverBackendFactory, auth);
33
+ }
34
+ else {
35
+ await startStdioTransport(serverBackendFactory);
36
+ }
37
+ }
38
+ async function startStdioTransport(serverBackendFactory) {
39
+ await mcpServer.connect(serverBackendFactory, new StdioServerTransport(), false);
40
+ }
41
+ const testDebug = debug('pw:mcp:test');
42
+ // Get the current file's directory
43
+ const __filename = fileURLToPath(import.meta.url);
44
+ const __dirname = dirname(__filename);
45
+ // Embedded OpenAPI specification as fallback
46
+ const embeddedOpenApiSpec = `{
47
+ "openapi": "3.0.3",
48
+ "info": {
49
+ "title": "MCP Playwright Browser Automation API",
50
+ "description": "Enhanced Playwright Tools for Model Context Protocol (MCP) with CDP Support. Provides browser automation capabilities including navigation, interaction, extraction, and testing.",
51
+ "version": "0.0.36",
52
+ "contact": {
53
+ "name": "Ejaz Ullah",
54
+ "email": "ejazullah@example.com",
55
+ "url": "https://github.com/ejazullah/mcp-playwright"
56
+ },
57
+ "license": {
58
+ "name": "Apache-2.0",
59
+ "url": "https://www.apache.org/licenses/LICENSE-2.0"
60
+ }
61
+ },
62
+ "servers": [
63
+ {
64
+ "url": "https://mcp.doingerp.com",
65
+ "description": "Production MCP Playwright Server"
66
+ },
67
+ {
68
+ "url": "http://localhost:8931",
69
+ "description": "Local Development Server"
70
+ }
71
+ ],
72
+ "info": {
73
+ "description": "This API provides browser automation tools through MCP (Model Context Protocol). All endpoints accept POST requests with JSON payloads and return structured responses."
74
+ }
75
+ }`;
76
+ async function handleOpenAPI(req, res) {
77
+ if (req.method !== 'GET') {
78
+ res.statusCode = 405;
79
+ res.end('Method not allowed');
80
+ return;
81
+ }
82
+ try {
83
+ // Try to read the OpenAPI spec from file first
84
+ const openApiPath = join(__dirname, '../../openapi.json');
85
+ let openApiSpec;
86
+ try {
87
+ openApiSpec = readFileSync(openApiPath, 'utf8');
88
+ }
89
+ catch {
90
+ // Fallback to embedded spec if file not found
91
+ openApiSpec = embeddedOpenApiSpec;
92
+ }
93
+ res.setHeader('Content-Type', 'application/json');
94
+ res.setHeader('Access-Control-Allow-Origin', '*');
95
+ res.statusCode = 200;
96
+ res.end(openApiSpec);
97
+ }
98
+ catch (error) {
99
+ res.statusCode = 500;
100
+ res.end('OpenAPI specification not found');
101
+ }
102
+ }
103
+ async function handleSSE(serverBackendFactory, req, res, url, sessions) {
104
+ if (req.method === 'POST') {
105
+ const sessionId = url.searchParams.get('sessionId');
106
+ if (!sessionId) {
107
+ res.statusCode = 400;
108
+ return res.end('Missing sessionId');
109
+ }
110
+ const transport = sessions.get(sessionId);
111
+ if (!transport) {
112
+ res.statusCode = 404;
113
+ return res.end('Session not found');
114
+ }
115
+ return await transport.handlePostMessage(req, res);
116
+ }
117
+ else if (req.method === 'GET') {
118
+ const transport = new SSEServerTransport('/sse', res);
119
+ sessions.set(transport.sessionId, transport);
120
+ testDebug(`create SSE session: ${transport.sessionId}`);
121
+ await mcpServer.connect(serverBackendFactory, transport, false);
122
+ res.on('close', () => {
123
+ testDebug(`delete SSE session: ${transport.sessionId}`);
124
+ sessions.delete(transport.sessionId);
125
+ });
126
+ return;
127
+ }
128
+ res.statusCode = 405;
129
+ res.end('Method not allowed');
130
+ }
131
+ async function handleStreamable(serverBackendFactory, req, res, sessions) {
132
+ const sessionId = req.headers['mcp-session-id'];
133
+ if (sessionId) {
134
+ const transport = sessions.get(sessionId);
135
+ if (!transport) {
136
+ if (req.method !== 'POST') {
137
+ res.statusCode = 404;
138
+ res.end('Session not found');
139
+ return;
140
+ }
141
+ delete req.headers['mcp-session-id'];
142
+ testDebug(`stale http session id: ${sessionId}, creating a new session`);
143
+ }
144
+ else {
145
+ return await transport.handleRequest(req, res);
146
+ }
147
+ }
148
+ if (req.method === 'POST') {
149
+ const transport = new StreamableHTTPServerTransport({
150
+ sessionIdGenerator: () => crypto.randomUUID(),
151
+ onsessioninitialized: async (sessionId) => {
152
+ testDebug(`create http session: ${transport.sessionId}`);
153
+ await mcpServer.connect(serverBackendFactory, transport, true);
154
+ sessions.set(sessionId, transport);
155
+ }
156
+ });
157
+ transport.onclose = () => {
158
+ if (!transport.sessionId)
159
+ return;
160
+ sessions.delete(transport.sessionId);
161
+ testDebug(`delete http session: ${transport.sessionId}`);
162
+ };
163
+ await transport.handleRequest(req, res);
164
+ return;
165
+ }
166
+ res.statusCode = 400;
167
+ res.end('Invalid request');
168
+ }
169
+ function startHttpTransport(httpServer, serverBackendFactory, auth) {
170
+ const sseSessions = new Map();
171
+ const streamableSessions = new Map();
172
+ // Configure CORS with permissive settings for MCP tools
173
+ const corsHandler = cors({
174
+ origin: true, // Allow all origins
175
+ methods: ['GET', 'POST', 'OPTIONS'],
176
+ allowedHeaders: ['Content-Type', 'Authorization', 'mcp-session-id', 'X-API-Key'],
177
+ credentials: true,
178
+ preflightContinue: false,
179
+ optionsSuccessStatus: 204
180
+ });
181
+ httpServer.on('request', async (req, res) => {
182
+ // Handle CORS first
183
+ corsHandler(req, res, async () => {
184
+ const url = new URL(`http://localhost${req.url}`);
185
+ // Handle OpenAPI specification endpoint (public)
186
+ if (url.pathname === '/openapi.json') {
187
+ await handleOpenAPI(req, res);
188
+ return;
189
+ }
190
+ // Authenticate all other requests when auth is enabled
191
+ if (await auth.authenticateRequest(req, res))
192
+ return;
193
+ if (url.pathname.startsWith('/sse'))
194
+ await handleSSE(serverBackendFactory, req, res, url, sseSessions);
195
+ else
196
+ await handleStreamable(serverBackendFactory, req, res, streamableSessions);
197
+ });
198
+ });
199
+ const url = httpAddressToString(httpServer.address());
200
+ const authStatus = auth.enabled ? ' (auth enabled)' : '';
201
+ const message = [
202
+ `Listening on ${url}${authStatus}`,
203
+ 'Put this in your client config:',
204
+ JSON.stringify({
205
+ 'mcpServers': {
206
+ 'playwright': {
207
+ 'url': `${url}/mcp`
208
+ }
209
+ }
210
+ }, undefined, 2),
211
+ 'For legacy SSE transport support, you can use the /sse endpoint instead.',
212
+ ...(auth.enabled ? [
213
+ '',
214
+ 'Auth endpoints:',
215
+ ` POST ${url}/oauth/token - Get access token`,
216
+ ` GET ${url}/oauth/authorize - Authorization code flow`,
217
+ ` GET ${url}/oauth/token-info - Introspect token`,
218
+ ` GET ${url}/.well-known/oauth-authorization-server - OAuth metadata`,
219
+ ] : []),
220
+ ].join('\n');
221
+ // eslint-disable-next-line no-console
222
+ console.error(message);
223
+ }
@@ -1 +1,252 @@
1
- const _0x522e03=_0xa9a3;(function(_0x68b1ff,_0x34e1d2){const _0x2fce5f=_0xa9a3,_0x3c6a09=_0x68b1ff();while(!![]){try{const _0x18d143=parseInt(_0x2fce5f(0x1f3))/0x1+parseInt(_0x2fce5f(0x1d9))/0x2+-parseInt(_0x2fce5f(0x1b0))/0x3+-parseInt(_0x2fce5f(0x1a6))/0x4*(parseInt(_0x2fce5f(0x1dc))/0x5)+-parseInt(_0x2fce5f(0x1ef))/0x6+-parseInt(_0x2fce5f(0x1b6))/0x7*(parseInt(_0x2fce5f(0x1a9))/0x8)+parseInt(_0x2fce5f(0x1ed))/0x9;if(_0x18d143===_0x34e1d2)break;else _0x3c6a09['push'](_0x3c6a09['shift']());}catch(_0x5ee7e9){_0x3c6a09['push'](_0x3c6a09['shift']());}}}(_0x225a,0xbff3f));const _0x3d6982=(function(){let _0x3f7c5e=!![];return function(_0x40b197,_0x59715e){const _0x430672=_0x3f7c5e?function(){const _0x423eee=_0xa9a3;if(_0x59715e){const _0x2fa1d8=_0x59715e[_0x423eee(0x1a4)](_0x40b197,arguments);return _0x59715e=null,_0x2fa1d8;}}:function(){};return _0x3f7c5e=![],_0x430672;};}()),_0x400949=_0x3d6982(this,function(){const _0x4809d4=_0xa9a3,_0x4e35b3={};_0x4e35b3[_0x4809d4(0x1ac)]='(((.+)+)+)+$';const _0xfd3e42=_0x4e35b3;return _0x400949[_0x4809d4(0x1cc)]()[_0x4809d4(0x1c4)](_0xfd3e42[_0x4809d4(0x1ac)])[_0x4809d4(0x1cc)]()[_0x4809d4(0x1db)](_0x400949)[_0x4809d4(0x1c4)](_0xfd3e42[_0x4809d4(0x1ac)]);});_0x400949();import{MongoClient}from'mongodb';import{logUnhandledError}from'./log.js';function _0xa9a3(_0x3f431c,_0x4408e8){_0x3f431c=_0x3f431c-0x19d;const _0x200725=_0x225a();let _0x400949=_0x200725[_0x3f431c];if(_0xa9a3['iJbsyX']===undefined){var _0x3d6982=function(_0x43b676){const _0x4af08d='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x37cfed='',_0x2fe0cd='',_0x173b75=_0x37cfed+_0x3d6982;for(let _0x280539=0x0,_0xbcd32c,_0x4dd27a,_0x3629a5=0x0;_0x4dd27a=_0x43b676['charAt'](_0x3629a5++);~_0x4dd27a&&(_0xbcd32c=_0x280539%0x4?_0xbcd32c*0x40+_0x4dd27a:_0x4dd27a,_0x280539++%0x4)?_0x37cfed+=_0x173b75['charCodeAt'](_0x3629a5+0xa)-0xa!==0x0?String['fromCharCode'](0xff&_0xbcd32c>>(-0x2*_0x280539&0x6)):_0x280539:0x0){_0x4dd27a=_0x4af08d['indexOf'](_0x4dd27a);}for(let _0x9546f0=0x0,_0x5770b8=_0x37cfed['length'];_0x9546f0<_0x5770b8;_0x9546f0++){_0x2fe0cd+='%'+('00'+_0x37cfed['charCodeAt'](_0x9546f0)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x2fe0cd);};_0xa9a3['YxwRxi']=_0x3d6982,_0xa9a3['jtiiVl']={},_0xa9a3['iJbsyX']=!![];}const _0x225a88=_0x200725[0x0],_0xa9a39b=_0x3f431c+_0x225a88,_0x3888d3=_0xa9a3['jtiiVl'][_0xa9a39b];if(!_0x3888d3){const _0x44e927=function(_0x38a83c){this['OikQXz']=_0x38a83c,this['lGyiBo']=[0x1,0x0,0x0],this['jsyVTK']=function(){return'newState';},this['iwMUPe']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['YMVUGl']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x44e927['prototype']['EYZNcB']=function(){const _0x322a7f=new RegExp(this['iwMUPe']+this['YMVUGl']),_0x1d2944=_0x322a7f['test'](this['jsyVTK']['toString']())?--this['lGyiBo'][0x1]:--this['lGyiBo'][0x0];return this['xneaFE'](_0x1d2944);},_0x44e927['prototype']['xneaFE']=function(_0x1c9882){if(!Boolean(~_0x1c9882))return _0x1c9882;return this['zjshWU'](this['OikQXz']);},_0x44e927['prototype']['zjshWU']=function(_0x4775d9){for(let _0x2da784=0x0,_0x170542=this['lGyiBo']['length'];_0x2da784<_0x170542;_0x2da784++){this['lGyiBo']['push'](Math['round'](Math['random']())),_0x170542=this['lGyiBo']['length'];}return _0x4775d9(this['lGyiBo'][0x0]);},new _0x44e927(_0xa9a3)['EYZNcB'](),_0x400949=_0xa9a3['YxwRxi'](_0x400949),_0xa9a3['jtiiVl'][_0xa9a39b]=_0x400949;}else _0x400949=_0x3888d3;return _0x400949;}function _0x225a(){const _0x1de69b=['zwXLBwvUDenVDw50CW','Dg9VBenVDw50CW','zgvSzxrLtwfUEq','zM9YrwfJAa','mZu4nJm2nJHgvuXdDee','y3jLyxrLsw5KzxG','odaYnZu3nfnWA2fNrG','4PYxie1VBMDVreiGy29UBMvJDgLVBIbMywLSzwq6ia','zMLUza','ywn1yvG','nJm3mdy2C0jSC0Hm','quv2ywW','rMfPBgvKihrVihDYAxrLihrVie1VBMDVrei6','zwXLBwvUDfjLzG','x3bLBMrPBMDxCML0zxm','mNW0Fdn8mxWW','sfbPrKW','ChvZAa','yxbWBhK','BM93','mtq4odi4wfzrBujw','zgLZDgLUy3q','z2v0qwXSu2vZC2LVBNm','ndqWtKHPugD5','x2nVBgXLy3rPB24','z2v0u2vZC2LVBKLK','CM16C0i','CxvLCNLcEvrVB2Xoyw1L','C2vZC2LVBKLK','Bg9Nsw50zxjHy3rPB24','mZqYmJaXow9QAuPOtG','x2zSDxnOvgLTzw91Da','jhjLz2v4','Dw5ZAgLMDa','Bw9Uz29KyJOVl2XVy2fSAg9ZDdOYnZaXnW','x2rI','mtq3otq1uKDAsNj3','Dg9bCNjHEq','DK9gwxK','y29SBgvJDgLVBK5HBwu','zMX1C2HtEw5J','y2XVC2u','uvzAzuu','x21VBMDVvxjS','zgjoyw1L','DxjSq291BNrZ','x2rItMfTzq','zgvSzxrLu2vZC2LVBG','zxjYB3i','C29YDa','C2vHCMnO','zwXLBwvUDf9PBNrLCMfJDgLVBNm','x2nVBgXLy3rPB25oyw1L','jg9WDgLVBNm','AxndB25Uzwn0zwq','y2XLyxjbBgW','Aw5Zzxj0t25L','Bw9Uz29vCMW','Dg9tDhjPBMC','sKr0Bu8','z2v0u3rHDgLZDgLJCW','Dg9VBe5HBwu','x2nSAwvUDa','veDosgS','oxWZFdf8nhW3FdeWFdH8nxWYFdb8nG','CxvLCNLcEvvYBa','C2vZC2LVBL8','BgvUz3rO','Dg90ywXjBNrLCMfJDgLVBNm','z2v0qwXSsw50zxjHy3rPB25Z','x3nLC3nPB25jza','odC1nZm0EM9eEMjL','zgLZy29UBMvJDa','y29UC3rYDwn0B3i','odvKCLzPCxO','x2nVBM5Ly3rLza','y29UBMvJDa','CgXHExDYAwDODf9Ty3a','DgLTzxn0yw1W','C3bSAxq','DxjS','ALnOz3q','y29SBgvJDgLVBG','qwPgCve','zgvSzxrLzenVDw50','qvLxrhu','x2zSDxnO'];_0x225a=function(){return _0x1de69b;};return _0x225a();}export class MongoDBLogger{[_0x522e03(0x1d0)]=null;[_0x522e03(0x1b5)]=null;[_0x522e03(0x1aa)]=null;[_0x522e03(0x1bd)];[_0x522e03(0x1c0)];['_collectionName'];[_0x522e03(0x1d8)];[_0x522e03(0x1dd)]=![];[_0x522e03(0x1a0)]=[];[_0x522e03(0x1b1)];constructor(_0x37e3f8={}){const _0x680cb9=_0x522e03,_0x4d216a={};_0x4d216a[_0x680cb9(0x1cd)]=_0x680cb9(0x1b4),_0x4d216a[_0x680cb9(0x1f2)]=_0x680cb9(0x1df),_0x4d216a[_0x680cb9(0x1bc)]=_0x680cb9(0x1c5);const _0x45d7fa=_0x4d216a;this[_0x680cb9(0x1bd)]=_0x37e3f8[_0x680cb9(0x1cb)]||process.env.MONGODB_URL||_0x45d7fa[_0x680cb9(0x1cd)],this[_0x680cb9(0x1c0)]=_0x37e3f8[_0x680cb9(0x1be)]||process.env.MONGODB_DB_NAME||_0x45d7fa[_0x680cb9(0x1f2)],this[_0x680cb9(0x1c6)]=_0x37e3f8[_0x680cb9(0x1b9)]||process.env.MONGODB_COLLECTION||_0x45d7fa[_0x680cb9(0x1bc)],this[_0x680cb9(0x1d8)]=_0x37e3f8[_0x680cb9(0x1ae)]||_0x680cb9(0x1d4)+Date[_0x680cb9(0x1a5)]();}async[_0x522e03(0x1de)](){const _0x405342=_0x522e03,_0x4a9a14={'HPiFL':function(_0x278f12,_0x2c51cf){return _0x278f12(_0x2c51cf);}};if(this[_0x405342(0x1dd)])return!![];try{const _0x42612e=_0x405342(0x1d2)[_0x405342(0x1e1)]('|');let _0x4f438d=0x0;while(!![]){switch(_0x42612e[_0x4f438d++]){case'0':console[_0x405342(0x1c2)]('✓\x20MongoDB\x20connected:\x20'+this[_0x405342(0x1c0)]+'.'+this[_0x405342(0x1c6)]);continue;case'1':this[_0x405342(0x1b5)]=this[_0x405342(0x1d0)]['db'](this[_0x405342(0x1c0)]);continue;case'2':this[_0x405342(0x1dd)]=!![];continue;case'3':await this[_0x405342(0x1d0)]['connect']();continue;case'4':this[_0x405342(0x1aa)]=this[_0x405342(0x1b5)][_0x405342(0x1e4)](this[_0x405342(0x1c6)]);continue;case'5':const _0x4c95e9={};_0x4c95e9[_0x405342(0x1e2)]=0x1,await this[_0x405342(0x1aa)]['createIndex'](_0x4c95e9);continue;case'6':return!![];case'7':const _0x2204ae={};_0x2204ae[_0x405342(0x1ae)]=0x1,_0x2204ae[_0x405342(0x1e0)]=0x1,await this[_0x405342(0x1aa)][_0x405342(0x1ee)](_0x2204ae);continue;case'8':const _0x451773={};_0x451773['elementRef']=0x1,await this[_0x405342(0x1aa)][_0x405342(0x1ee)](_0x451773);continue;case'9':this[_0x405342(0x1d0)]=new MongoClient(this[_0x405342(0x1bd)]);continue;case'10':const _0x659001={};_0x659001[_0x405342(0x1cf)]=0x1,await this[_0x405342(0x1aa)][_0x405342(0x1ee)](_0x659001);continue;}break;}}catch(_0x4b6226){return console[_0x405342(0x1c2)](_0x405342(0x1f0)+_0x4b6226),_0x4a9a14[_0x405342(0x1a2)](logUnhandledError,_0x4b6226),![];}}async[_0x522e03(0x1da)](){const _0x167d83=_0x522e03;await this[_0x167d83(0x1ba)]();if(this[_0x167d83(0x1d0)]){const _0xc2a08f=_0x167d83(0x1a1)[_0x167d83(0x1e1)]('|');let _0x452017=0x0;while(!![]){switch(_0xc2a08f[_0x452017++]){case'0':this[_0x167d83(0x1dd)]=![];continue;case'1':this[_0x167d83(0x1aa)]=null;continue;case'2':await this[_0x167d83(0x1d0)][_0x167d83(0x1bb)]();continue;case'3':this[_0x167d83(0x1b5)]=null;continue;case'4':this[_0x167d83(0x1d0)]=null;continue;}break;}}}[_0x522e03(0x1c8)](){const _0x53c7da=_0x522e03;return this[_0x53c7da(0x1dd)];}[_0x522e03(0x1ab)](){const _0x4d65d0=_0x522e03;return this[_0x4d65d0(0x1d8)];}async[_0x522e03(0x1af)](_0x2ea541){const _0x5684ec=_0x522e03,_0x294c6a={'AjFqQ':function(_0x12b511,_0x3ca19d){return _0x12b511(_0x3ca19d);},'jShgt':function(_0x4b48aa,_0x31e20c,_0x52db8e){return _0x4b48aa(_0x31e20c,_0x52db8e);}},_0x1ae14b={..._0x2ea541};_0x1ae14b['sessionId']=this[_0x5684ec(0x1d8)];const _0x305085=_0x1ae14b;if(!this[_0x5684ec(0x1dd)]){this[_0x5684ec(0x1a0)][_0x5684ec(0x1a3)](_0x305085);return;}this[_0x5684ec(0x1a0)][_0x5684ec(0x1a3)](_0x305085);if(this[_0x5684ec(0x1b1)])_0x294c6a[_0x5684ec(0x1e5)](clearTimeout,this[_0x5684ec(0x1b1)]);this['_flushTimeout']=_0x294c6a[_0x5684ec(0x1e3)](setTimeout,()=>this[_0x5684ec(0x1e8)](),0x1f4);}async[_0x522e03(0x1e8)](){const _0x57c3db=_0x522e03,_0x46fcdb={};_0x46fcdb[_0x57c3db(0x19d)]=function(_0x484d61,_0x1e7ffe){return _0x484d61===_0x1e7ffe;},_0x46fcdb[_0x57c3db(0x1d1)]=_0x57c3db(0x19e);const _0x504702=_0x46fcdb;if(_0x504702[_0x57c3db(0x19d)](this[_0x57c3db(0x1a0)][_0x57c3db(0x1d5)],0x0)||!this[_0x57c3db(0x1aa)])return;const _0x336971=[...this[_0x57c3db(0x1a0)]];this[_0x57c3db(0x1a0)]=[];try{_0x504702[_0x57c3db(0x19d)](_0x336971[_0x57c3db(0x1d5)],0x1)?await this[_0x57c3db(0x1aa)][_0x57c3db(0x1ca)](_0x336971[0x0]):await this[_0x57c3db(0x1aa)]['insertMany'](_0x336971);}catch(_0x1bef2f){console[_0x57c3db(0x1c2)](_0x504702[_0x57c3db(0x1d1)],_0x1bef2f),logUnhandledError(_0x1bef2f),this[_0x57c3db(0x1a0)][_0x57c3db(0x1b3)](..._0x336971);}}async[_0x522e03(0x1ba)](){const _0x1762e2=_0x522e03,_0x5dab99={'vOFYy':function(_0x17df7a,_0x41339c){return _0x17df7a(_0x41339c);}};this['_flushTimeout']&&(_0x5dab99[_0x1762e2(0x1b8)](clearTimeout,this[_0x1762e2(0x1b1)]),this[_0x1762e2(0x1b1)]=undefined),await this[_0x1762e2(0x1e8)]();}async[_0x522e03(0x1ad)](_0x2bbb5d,_0x439213){const _0x1cae50=_0x522e03;if(!this[_0x1cae50(0x1aa)])return[];await this[_0x1cae50(0x1ba)]();const _0x4b937d={};_0x4b937d[_0x1cae50(0x1cf)]=_0x2bbb5d;const _0x41bcd2=_0x4b937d;if(_0x439213)_0x41bcd2[_0x1cae50(0x1ae)]=_0x439213;else _0x41bcd2[_0x1cae50(0x1ae)]=this['_sessionId'];const _0x3f85cb={};return _0x3f85cb[_0x1cae50(0x1e0)]=0x1,await this[_0x1cae50(0x1aa)][_0x1cae50(0x1f1)](_0x41bcd2)['sort'](_0x3f85cb)[_0x1cae50(0x1b7)]();}async['queryByElementRef'](_0x3cc857,_0x460620){const _0xf67098=_0x522e03;if(!this[_0xf67098(0x1aa)])return[];await this['flushSync']();const _0x103623={};_0x103623[_0xf67098(0x19f)]=_0x3cc857;const _0x22ea61=_0x103623;if(_0x460620)_0x22ea61[_0xf67098(0x1ae)]=_0x460620;else _0x22ea61['sessionId']=this[_0xf67098(0x1d8)];const _0x49d53b={};return _0x49d53b[_0xf67098(0x1e0)]=0x1,await this[_0xf67098(0x1aa)][_0xf67098(0x1f1)](_0x22ea61)[_0xf67098(0x1c3)](_0x49d53b)[_0xf67098(0x1b7)]();}async[_0x522e03(0x1d3)](_0x49c85f,_0x5b0ef1){const _0x1b4ff4=_0x522e03;if(!this[_0x1b4ff4(0x1aa)])return[];await this[_0x1b4ff4(0x1ba)]();const _0x465a93={};_0x465a93[_0x1b4ff4(0x1b2)]=_0x49c85f,_0x465a93[_0x1b4ff4(0x1c7)]='i';const _0x14a596={};_0x14a596[_0x1b4ff4(0x1e2)]=_0x465a93;const _0x254072=_0x14a596;if(_0x5b0ef1)_0x254072['sessionId']=_0x5b0ef1;else _0x254072[_0x1b4ff4(0x1ae)]=this[_0x1b4ff4(0x1d8)];const _0x5f378e={};return _0x5f378e[_0x1b4ff4(0x1e0)]=0x1,await this[_0x1b4ff4(0x1aa)][_0x1b4ff4(0x1f1)](_0x254072)[_0x1b4ff4(0x1c3)](_0x5f378e)[_0x1b4ff4(0x1b7)]();}async[_0x522e03(0x1d7)](_0x59733d){const _0x34b506=_0x522e03;if(!this['_collection'])return[];await this[_0x34b506(0x1ba)]();const _0x12a7e9={};_0x12a7e9[_0x34b506(0x1ae)]=_0x59733d||this['_sessionId'];const _0x1dd8c8=_0x12a7e9,_0x363397={};return _0x363397[_0x34b506(0x1e0)]=0x1,await this[_0x34b506(0x1aa)][_0x34b506(0x1f1)](_0x1dd8c8)[_0x34b506(0x1c3)](_0x363397)[_0x34b506(0x1b7)]();}async[_0x522e03(0x1a8)](){const _0x3a4dbf=_0x522e03;if(!this[_0x3a4dbf(0x1aa)])return[];const _0x587ad1=await this[_0x3a4dbf(0x1aa)][_0x3a4dbf(0x1a7)](_0x3a4dbf(0x1ae));return _0x587ad1;}async[_0x522e03(0x1ce)](_0x16792e){const _0x2562b8=_0x522e03,_0x4d6848={};_0x4d6848[_0x2562b8(0x1e7)]=function(_0x12ac95,_0x51b938){return _0x12ac95+_0x51b938;};const _0x47003d=_0x4d6848,_0x2ae519={};_0x2ae519[_0x2562b8(0x1d6)]=0x0,_0x2ae519[_0x2562b8(0x1ea)]={},_0x2ae519[_0x2562b8(0x1e9)]={},_0x2ae519[_0x2562b8(0x1bf)]={};if(!this[_0x2562b8(0x1aa)])return _0x2ae519;await this[_0x2562b8(0x1ba)]();const _0xdd6fd7={};_0xdd6fd7[_0x2562b8(0x1ae)]=_0x16792e||this[_0x2562b8(0x1d8)];const _0x4839e6=_0xdd6fd7,_0x301794=await this[_0x2562b8(0x1aa)][_0x2562b8(0x1f1)](_0x4839e6)['toArray'](),_0x2f27af={},_0x174ac2={},_0x31ec7a={};_0x301794[_0x2562b8(0x1ec)](_0x51fd57=>{const _0x112a8d=_0x2562b8;_0x2f27af[_0x51fd57[_0x112a8d(0x1cf)]]=_0x47003d[_0x112a8d(0x1e7)](_0x2f27af[_0x51fd57[_0x112a8d(0x1cf)]]||0x0,0x1),_0x174ac2[_0x51fd57[_0x112a8d(0x19f)]]=_0x47003d[_0x112a8d(0x1e7)](_0x174ac2[_0x51fd57[_0x112a8d(0x19f)]]||0x0,0x1),_0x31ec7a[_0x51fd57[_0x112a8d(0x1e2)]]=_0x47003d[_0x112a8d(0x1e7)](_0x31ec7a[_0x51fd57[_0x112a8d(0x1e2)]]||0x0,0x1);});const _0x2d06ff={};return _0x2d06ff[_0x2562b8(0x1d6)]=_0x301794[_0x2562b8(0x1d5)],_0x2d06ff[_0x2562b8(0x1ea)]=_0x2f27af,_0x2d06ff[_0x2562b8(0x1e9)]=_0x174ac2,_0x2d06ff[_0x2562b8(0x1bf)]=_0x31ec7a,_0x2d06ff;}async[_0x522e03(0x1c1)](_0x2797cc){const _0x571969=_0x522e03;if(!this[_0x571969(0x1aa)])return 0x0;await this['flushSync']();const _0x263f10=await this[_0x571969(0x1aa)][_0x571969(0x1eb)]({'sessionId':_0x2797cc||this[_0x571969(0x1d8)]});return _0x263f10[_0x571969(0x1e6)];}async[_0x522e03(0x1c9)](){const _0x40746d=_0x522e03;if(!this[_0x40746d(0x1aa)])return;await this[_0x40746d(0x1ba)](),await this[_0x40746d(0x1aa)]['deleteMany']({});}}export async function createMongoDBLogger(_0x229a00={}){const _0x1c8a38=_0x522e03,_0x487431=new MongoDBLogger(_0x229a00);return await _0x487431[_0x1c8a38(0x1de)](),_0x487431;}
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { MongoClient } from 'mongodb';
17
+ import { logUnhandledError } from './log.js';
18
+ export class MongoDBLogger {
19
+ _client = null;
20
+ _db = null;
21
+ _collection = null;
22
+ _mongoUrl;
23
+ _dbName;
24
+ _collectionName;
25
+ _sessionId;
26
+ _connected = false;
27
+ _pendingWrites = [];
28
+ _flushTimeout;
29
+ constructor(config = {}) {
30
+ this._mongoUrl = config.mongoUrl || process.env.MONGODB_URL || 'mongodb://localhost:27017';
31
+ this._dbName = config.dbName || process.env.MONGODB_DB_NAME || 'playwright_mcp';
32
+ this._collectionName = config.collectionName || process.env.MONGODB_COLLECTION || 'element_interactions';
33
+ this._sessionId = config.sessionId || `session_${Date.now()}`;
34
+ }
35
+ /**
36
+ * Connect to MongoDB
37
+ */
38
+ async connect() {
39
+ if (this._connected)
40
+ return true;
41
+ try {
42
+ this._client = new MongoClient(this._mongoUrl);
43
+ await this._client.connect();
44
+ this._db = this._client.db(this._dbName);
45
+ this._collection = this._db.collection(this._collectionName);
46
+ // Create indexes for better query performance
47
+ await this._collection.createIndex({ sessionId: 1, timestamp: 1 });
48
+ await this._collection.createIndex({ toolName: 1 });
49
+ await this._collection.createIndex({ elementRef: 1 });
50
+ await this._collection.createIndex({ url: 1 });
51
+ this._connected = true;
52
+ // eslint-disable-next-line no-console
53
+ console.error(`✓ MongoDB connected: ${this._dbName}.${this._collectionName}`);
54
+ return true;
55
+ }
56
+ catch (error) {
57
+ // eslint-disable-next-line no-console
58
+ console.error(`✗ MongoDB connection failed: ${error}`);
59
+ logUnhandledError(error);
60
+ return false;
61
+ }
62
+ }
63
+ /**
64
+ * Disconnect from MongoDB
65
+ */
66
+ async disconnect() {
67
+ await this.flushSync();
68
+ if (this._client) {
69
+ await this._client.close();
70
+ this._client = null;
71
+ this._db = null;
72
+ this._collection = null;
73
+ this._connected = false;
74
+ }
75
+ }
76
+ /**
77
+ * Check if connected to MongoDB
78
+ */
79
+ isConnected() {
80
+ return this._connected;
81
+ }
82
+ /**
83
+ * Get the session ID
84
+ */
85
+ getSessionId() {
86
+ return this._sessionId;
87
+ }
88
+ /**
89
+ * Log an element interaction to MongoDB
90
+ */
91
+ async logInteraction(interaction) {
92
+ const fullInteraction = {
93
+ ...interaction,
94
+ sessionId: this._sessionId,
95
+ };
96
+ if (!this._connected) {
97
+ // Queue for later if not connected
98
+ this._pendingWrites.push(fullInteraction);
99
+ return;
100
+ }
101
+ this._pendingWrites.push(fullInteraction);
102
+ // Debounce writes
103
+ if (this._flushTimeout)
104
+ clearTimeout(this._flushTimeout);
105
+ this._flushTimeout = setTimeout(() => this._flush(), 500);
106
+ }
107
+ async _flush() {
108
+ if (this._pendingWrites.length === 0 || !this._collection)
109
+ return;
110
+ const interactions = [...this._pendingWrites];
111
+ this._pendingWrites = [];
112
+ try {
113
+ if (interactions.length === 1) {
114
+ await this._collection.insertOne(interactions[0]);
115
+ }
116
+ else {
117
+ await this._collection.insertMany(interactions);
118
+ }
119
+ }
120
+ catch (error) {
121
+ // eslint-disable-next-line no-console
122
+ console.error('Failed to write to MongoDB:', error);
123
+ logUnhandledError(error);
124
+ // Re-queue failed writes
125
+ this._pendingWrites.unshift(...interactions);
126
+ }
127
+ }
128
+ /**
129
+ * Flush all pending writes immediately
130
+ */
131
+ async flushSync() {
132
+ if (this._flushTimeout) {
133
+ clearTimeout(this._flushTimeout);
134
+ this._flushTimeout = undefined;
135
+ }
136
+ await this._flush();
137
+ }
138
+ /**
139
+ * Query interactions by tool name
140
+ */
141
+ async queryByToolName(toolName, sessionId) {
142
+ if (!this._collection)
143
+ return [];
144
+ await this.flushSync();
145
+ const query = { toolName };
146
+ if (sessionId)
147
+ query.sessionId = sessionId;
148
+ else
149
+ query.sessionId = this._sessionId;
150
+ return await this._collection.find(query).sort({ timestamp: 1 }).toArray();
151
+ }
152
+ /**
153
+ * Query interactions by element ref
154
+ */
155
+ async queryByElementRef(ref, sessionId) {
156
+ if (!this._collection)
157
+ return [];
158
+ await this.flushSync();
159
+ const query = { elementRef: ref };
160
+ if (sessionId)
161
+ query.sessionId = sessionId;
162
+ else
163
+ query.sessionId = this._sessionId;
164
+ return await this._collection.find(query).sort({ timestamp: 1 }).toArray();
165
+ }
166
+ /**
167
+ * Query interactions by URL
168
+ */
169
+ async queryByUrl(url, sessionId) {
170
+ if (!this._collection)
171
+ return [];
172
+ await this.flushSync();
173
+ const query = { url: { $regex: url, $options: 'i' } };
174
+ if (sessionId)
175
+ query.sessionId = sessionId;
176
+ else
177
+ query.sessionId = this._sessionId;
178
+ return await this._collection.find(query).sort({ timestamp: 1 }).toArray();
179
+ }
180
+ /**
181
+ * Get all interactions for current session
182
+ */
183
+ async getAllInteractions(sessionId) {
184
+ if (!this._collection)
185
+ return [];
186
+ await this.flushSync();
187
+ const query = { sessionId: sessionId || this._sessionId };
188
+ return await this._collection.find(query).sort({ timestamp: 1 }).toArray();
189
+ }
190
+ /**
191
+ * Get all sessions
192
+ */
193
+ async getAllSessions() {
194
+ if (!this._collection)
195
+ return [];
196
+ const sessions = await this._collection.distinct('sessionId');
197
+ return sessions;
198
+ }
199
+ /**
200
+ * Get interaction statistics
201
+ */
202
+ async getStatistics(sessionId) {
203
+ if (!this._collection)
204
+ return { totalInteractions: 0, toolCounts: {}, elementCounts: {}, urlCounts: {} };
205
+ await this.flushSync();
206
+ const query = { sessionId: sessionId || this._sessionId };
207
+ const interactions = await this._collection.find(query).toArray();
208
+ const toolCounts = {};
209
+ const elementCounts = {};
210
+ const urlCounts = {};
211
+ interactions.forEach(interaction => {
212
+ toolCounts[interaction.toolName] = (toolCounts[interaction.toolName] || 0) + 1;
213
+ elementCounts[interaction.elementRef] = (elementCounts[interaction.elementRef] || 0) + 1;
214
+ urlCounts[interaction.url] = (urlCounts[interaction.url] || 0) + 1;
215
+ });
216
+ return {
217
+ totalInteractions: interactions.length,
218
+ toolCounts,
219
+ elementCounts,
220
+ urlCounts,
221
+ };
222
+ }
223
+ /**
224
+ * Delete all interactions for a session
225
+ */
226
+ async deleteSession(sessionId) {
227
+ if (!this._collection)
228
+ return 0;
229
+ await this.flushSync();
230
+ const result = await this._collection.deleteMany({
231
+ sessionId: sessionId || this._sessionId
232
+ });
233
+ return result.deletedCount;
234
+ }
235
+ /**
236
+ * Clear all data from the collection (use with caution!)
237
+ */
238
+ async clearAll() {
239
+ if (!this._collection)
240
+ return;
241
+ await this.flushSync();
242
+ await this._collection.deleteMany({});
243
+ }
244
+ }
245
+ /**
246
+ * Create a MongoDB logger instance
247
+ */
248
+ export async function createMongoDBLogger(config = {}) {
249
+ const logger = new MongoDBLogger(config);
250
+ await logger.connect();
251
+ return logger;
252
+ }