algorembrant commited on
Commit
668d995
·
verified ·
1 Parent(s): 706ee34

Upload 44 files

Browse files
.env.example ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MCP Browser Server Configuration
2
+
3
+ # Browser settings
4
+ BROWSER_TYPE=msedge
5
+ # Use existing Edge profile (leave empty for fresh profile)
6
+ # Find your profile path: edge://version -> Profile Path
7
+ EDGE_USER_DATA_DIR=
8
+ EDGE_PROFILE=Default
9
+
10
+ # Timeouts (milliseconds)
11
+ NAVIGATION_TIMEOUT=30000
12
+ ACTION_TIMEOUT=10000
13
+
14
+ # Messenger settings
15
+ MESSENGER_URL=https://www.messenger.com
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ messenger_login_check.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Sensitive information
2
+ .env
3
+ .env.*
4
+ *.key
5
+ *.pem
6
+ credentials.json
7
+ secrets.json
8
+
9
+ # Node.js
10
+ node_modules/
11
+ npm-debug.log*
12
+ yarn-debug.log*
13
+ yarn-error.log*
14
+ .npm/
15
+
16
+ # TypeScript
17
+ dist/
18
+ lib/
19
+ *.tsbuildinfo
20
+
21
+ # OS/IDEs
22
+ .vscode/
23
+ .idea/
24
+ .DS_Store
25
+ Thumbs.db
26
+
27
+ # Existing
28
+ .warning/
29
+
30
+ .env
LICENSE ADDED
@@ -0,0 +1,674 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+ Preamble
9
+
10
+ The GNU General Public License is a free, copyleft license for
11
+ software and other kinds of works.
12
+
13
+ The licenses for most software and other practical works are designed
14
+ to take away your freedom to share and change the works. By contrast,
15
+ the GNU General Public License is intended to guarantee your freedom to
16
+ share and change all versions of a program--to make sure it remains free
17
+ software for all its users. We, the Free Software Foundation, use the
18
+ GNU General Public License for most of our software; it applies also to
19
+ any other work released this way by its authors. You can apply it to
20
+ your programs, too.
21
+
22
+ When we speak of free software, we are referring to freedom, not
23
+ price. Our General Public Licenses are designed to make sure that you
24
+ have the freedom to distribute copies of free software (and charge for
25
+ them if you wish), that you receive source code or can get it if you
26
+ want it, that you can change the software or use pieces of it in new
27
+ free programs, and that you know you can do these things.
28
+
29
+ To protect your rights, we need to prevent others from denying you
30
+ these rights or asking you to surrender the rights. Therefore, you have
31
+ certain responsibilities if you distribute copies of the software, or if
32
+ you modify it: responsibilities to respect the freedom of others.
33
+
34
+ For example, if you distribute copies of such a program, whether
35
+ gratis or for a fee, you must pass on to the recipients the same
36
+ freedoms that you received. You must make sure that they, too, receive
37
+ or can get the source code. And you must show them these terms so they
38
+ know their rights.
39
+
40
+ Developers that use the GNU GPL protect your rights with two steps:
41
+ (1) assert copyright on the software, and (2) offer you this License
42
+ giving you legal permission to copy, distribute and/or modify it.
43
+
44
+ For the developers' and authors' protection, the GPL clearly explains
45
+ that there is no warranty for this free software. For both users' and
46
+ authors' sake, the GPL requires that modified versions be marked as
47
+ changed, so that their problems will not be attributed erroneously to
48
+ authors of previous versions.
49
+
50
+ Some devices are designed to deny users access to install or run
51
+ modified versions of the software inside them, although the manufacturer
52
+ can do so. This is fundamentally incompatible with the aim of
53
+ protecting users' freedom to change the software. The systematic
54
+ pattern of such abuse occurs in the area of products for individuals to
55
+ use, which is precisely where it is most unacceptable. Therefore, we
56
+ have designed this version of the GPL to prohibit the practice for those
57
+ products. If such problems arise substantially in other domains, we
58
+ stand ready to extend this provision to those domains in future versions
59
+ of the GPL, as needed to protect the freedom of users.
60
+
61
+ Finally, every program is threatened constantly by software patents.
62
+ States should not allow patents to restrict development and use of
63
+ software on general-purpose computers, but in those that do, we wish to
64
+ avoid the special danger that patents applied to a free program could
65
+ make it effectively proprietary. To prevent this, the GPL assures that
66
+ patents cannot be used to render the program non-free.
67
+
68
+ The precise terms and conditions for copying, distribution and
69
+ modification follow.
70
+
71
+ TERMS AND CONDITIONS
72
+
73
+ 0. Definitions.
74
+
75
+ "This License" refers to version 3 of the GNU General Public License.
76
+
77
+ "Copyright" also means copyright-like laws that apply to other kinds of
78
+ works, such as semiconductor masks.
79
+
80
+ "The Program" refers to any copyrightable work licensed under this
81
+ License. Each licensee is addressed as "you". "Licensees" and
82
+ "recipients" may be individuals or organizations.
83
+
84
+ To "modify" a work means to copy from or adapt all or part of the work
85
+ in a fashion requiring copyright permission, other than the making of an
86
+ exact copy. The resulting work is called a "modified version" of the
87
+ earlier work or a work "based on" the earlier work.
88
+
89
+ A "covered work" means either the unmodified Program or a work based
90
+ on the Program.
91
+
92
+ To "propagate" a work means to do anything with it that, without
93
+ permission, would make you directly or secondarily liable for
94
+ infringement under applicable copyright law, except executing it on a
95
+ computer or modifying a private copy. Propagation includes copying,
96
+ distribution (with or without modification), making available to the
97
+ public, and in some countries other activities as well.
98
+
99
+ To "convey" a work means any kind of propagation that enables other
100
+ parties to make or receive copies. Mere interaction with a user through
101
+ a computer network, with no transfer of a copy, is not conveying.
102
+
103
+ An interactive user interface displays "Appropriate Legal Notices"
104
+ to the extent that it includes a convenient and prominently visible
105
+ feature that (1) displays an appropriate copyright notice, and (2)
106
+ tells the user that there is no warranty for the work (except to the
107
+ extent that warranties are provided), that licensees may convey the
108
+ work under this License, and how to view a copy of this License. If
109
+ the interface presents a list of user commands or options, such as a
110
+ menu, a prominent item in the list meets this criterion.
111
+
112
+ 1. Source Code.
113
+
114
+ The "source code" for a work means the preferred form of the work
115
+ for making modifications to it. "Object code" means any non-source
116
+ form of a work.
117
+
118
+ A "Standard Interface" means an interface that either is an official
119
+ standard defined by a recognized standards body, or, in the case of
120
+ interfaces specified for a particular programming language, one that
121
+ is widely used among developers working in that language.
122
+
123
+ The "System Libraries" of an executable work include anything, other
124
+ than the work as a whole, that (a) is included in the normal form of
125
+ packaging a Major Component, but which is not part of that Major
126
+ Component, and (b) serves only to enable use of the work with that
127
+ Major Component, or to implement a Standard Interface for which an
128
+ implementation is available to the public in source code form. A
129
+ "Major Component", in this context, means a major essential component
130
+ (kernel, window system, and so on) of the specific operating system
131
+ (if any) on which the executable work runs, or a compiler used to
132
+ produce the work, or an object code interpreter used to run it.
133
+
134
+ The "Corresponding Source" for a work in object code form means all
135
+ the source code needed to generate, install, and (for an executable
136
+ work) run the object code and to modify the work, including scripts to
137
+ control those activities. However, it does not include the work's
138
+ System Libraries, or general-purpose tools or generally available free
139
+ programs which are used unmodified in performing those activities but
140
+ which are not part of the work. For example, Corresponding Source
141
+ includes interface definition files associated with source files for
142
+ the work, and the source code for shared libraries and dynamically
143
+ linked subprograms that the work is specifically designed to require,
144
+ such as by intimate data communication or control flow between those
145
+ subprograms and other parts of the work.
146
+
147
+ The Corresponding Source need not include anything that users
148
+ can regenerate automatically from other parts of the Corresponding
149
+ Source.
150
+
151
+ The Corresponding Source for a work in source code form is that
152
+ same work.
153
+
154
+ 2. Basic Permissions.
155
+
156
+ All rights granted under this License are granted for the term of
157
+ copyright on the Program, and are irrevocable provided the stated
158
+ conditions are met. This License explicitly affirms your unlimited
159
+ permission to run the unmodified Program. The output from running a
160
+ covered work is covered by this License only if the output, given its
161
+ content, constitutes a covered work. This License acknowledges your
162
+ rights of fair use or other equivalent, as provided by copyright law.
163
+
164
+ You may make, run and propagate covered works that you do not
165
+ convey, without conditions so long as your license otherwise remains
166
+ in force. You may convey covered works to others for the sole purpose
167
+ of having them make modifications exclusively for you, or provide you
168
+ with facilities for running those works, provided that you comply with
169
+ the terms of this License in conveying all material for which you do
170
+ not control copyright. Those thus making or running the covered works
171
+ for you must do so exclusively on your behalf, under your direction
172
+ and control, on terms that prohibit them from making any copies of
173
+ your copyrighted material outside their relationship with you.
174
+
175
+ Conveying under any other circumstances is permitted solely under
176
+ the conditions stated below. Sublicensing is not allowed; section 10
177
+ makes it unnecessary.
178
+
179
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
+
181
+ No covered work shall be deemed part of an effective technological
182
+ measure under any applicable law fulfilling obligations under article
183
+ 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184
+ similar laws prohibiting or restricting circumvention of such
185
+ measures.
186
+
187
+ When you convey a covered work, you waive any legal power to forbid
188
+ circumvention of technological measures to the extent such circumvention
189
+ is effected by exercising rights under this License with respect to
190
+ the covered work, and you disclaim any intention to limit operation or
191
+ modification of the work as a means of enforcing, against the work's
192
+ users, your or third parties' legal rights to forbid circumvention of
193
+ technological measures.
194
+
195
+ 4. Conveying Verbatim Copies.
196
+
197
+ You may convey verbatim copies of the Program's source code as you
198
+ receive it, in any medium, provided that you conspicuously and
199
+ appropriately publish on each copy an appropriate copyright notice;
200
+ keep intact all notices stating that this License and any
201
+ non-permissive terms added in accord with section 7 apply to the code;
202
+ keep intact all notices of the absence of any warranty; and give all
203
+ recipients a copy of this License along with the Program.
204
+
205
+ You may charge any price or no price for each copy that you convey,
206
+ and you may offer support or warranty protection for a fee.
207
+
208
+ 5. Conveying Modified Source Versions.
209
+
210
+ You may convey a work based on the Program, or the modifications to
211
+ produce it from the Program, in the form of source code under the
212
+ terms of section 4, provided that you also meet all of these conditions:
213
+
214
+ a) The work must carry prominent notices stating that you modified
215
+ it, and giving a relevant date.
216
+
217
+ b) The work must carry prominent notices stating that it is
218
+ released under this License and any conditions added under section
219
+ 7. This requirement modifies the requirement in section 4 to
220
+ "keep intact all notices".
221
+
222
+ c) You must license the entire work, as a whole, under this
223
+ License to anyone who comes into possession of a copy. This
224
+ License will therefore apply, along with any applicable section 7
225
+ additional terms, to the whole of the work, and all its parts,
226
+ regardless of how they are packaged. This License gives no
227
+ permission to license the work in any other way, but it does not
228
+ invalidate such permission if you have separately received it.
229
+
230
+ d) If the work has interactive user interfaces, each must display
231
+ Appropriate Legal Notices; however, if the Program has interactive
232
+ interfaces that do not display Appropriate Legal Notices, your
233
+ work need not make them do so.
234
+
235
+ A compilation of a covered work with other separate and independent
236
+ works, which are not by their nature extensions of the covered work,
237
+ and which are not combined with it such as to form a larger program,
238
+ in or on a volume of a storage or distribution medium, is called an
239
+ "aggregate" if the compilation and its resulting copyright are not
240
+ used to limit the access or legal rights of the compilation's users
241
+ beyond what the individual works permit. Inclusion of a covered work
242
+ in an aggregate does not cause this License to apply to the other
243
+ parts of the aggregate.
244
+
245
+ 6. Conveying Non-Source Forms.
246
+
247
+ You may convey a covered work in object code form under the terms
248
+ of sections 4 and 5, provided that you also convey the
249
+ machine-readable Corresponding Source under the terms of this License,
250
+ in one of these ways:
251
+
252
+ a) Convey the object code in, or embodied in, a physical product
253
+ (including a physical distribution medium), accompanied by the
254
+ Corresponding Source fixed on a durable physical medium
255
+ customarily used for software interchange.
256
+
257
+ b) Convey the object code in, or embodied in, a physical product
258
+ (including a physical distribution medium), accompanied by a
259
+ written offer, valid for at least three years and valid for as
260
+ long as you offer spare parts or customer support for that product
261
+ model, to give anyone who possesses the object code either (1) a
262
+ copy of the Corresponding Source for all the software in the
263
+ product that is covered by this License, on a durable physical
264
+ medium customarily used for software interchange, for a price no
265
+ more than your reasonable cost of physically performing this
266
+ conveying of source, or (2) access to copy the
267
+ Corresponding Source from a network server at no charge.
268
+
269
+ c) Convey individual copies of the object code with a copy of the
270
+ written offer to provide the Corresponding Source. This
271
+ alternative is allowed only occasionally and noncommercially, and
272
+ only if you received the object code with such an offer, in accord
273
+ with subsection 6b.
274
+
275
+ d) Convey the object code by offering access from a designated
276
+ place (gratis or for a charge), and offer equivalent access to the
277
+ Corresponding Source in the same way through the same place at no
278
+ further charge. You need not require recipients to copy the
279
+ Corresponding Source along with the object code. If the place to
280
+ copy the object code is a network server, the Corresponding Source
281
+ may be on a different server (operated by you or a third party)
282
+ that supports equivalent copying facilities, provided you maintain
283
+ clear directions next to the object code saying where to find the
284
+ Corresponding Source. Regardless of what server hosts the
285
+ Corresponding Source, you remain obligated to ensure that it is
286
+ available for as long as needed to satisfy these requirements.
287
+
288
+ e) Convey the object code using peer-to-peer transmission, provided
289
+ you inform other peers where the object code and Corresponding
290
+ Source of the work are being offered to the general public at no
291
+ charge under subsection 6d.
292
+
293
+ A separable portion of the object code, whose source code is excluded
294
+ from the Corresponding Source as a System Library, need not be
295
+ included in conveying the object code work.
296
+
297
+ A "User Product" is either (1) a "consumer product", which means any
298
+ tangible personal property which is normally used for personal, family,
299
+ or household purposes, or (2) anything designed or sold for incorporation
300
+ into a dwelling. In determining whether a product is a consumer product,
301
+ doubtful cases shall be resolved in favor of coverage. For a particular
302
+ product received by a particular user, "normally used" refers to a
303
+ typical or common use of that class of product, regardless of the status
304
+ of the particular user or of the way in which the particular user
305
+ actually uses, or expects or is expected to use, the product. A product
306
+ is a consumer product regardless of whether the product has substantial
307
+ commercial, industrial or non-consumer uses, unless such uses represent
308
+ the only significant mode of use of the product.
309
+
310
+ "Installation Information" for a User Product means any methods,
311
+ procedures, authorization keys, or other information required to install
312
+ and execute modified versions of a covered work in that User Product from
313
+ a modified version of its Corresponding Source. The information must
314
+ suffice to ensure that the continued functioning of the modified object
315
+ code is in no case prevented or interfered with solely because
316
+ modification has been made.
317
+
318
+ If you convey an object code work under this section in, or with, or
319
+ specifically for use in, a User Product, and the conveying occurs as
320
+ part of a transaction in which the right of possession and use of the
321
+ User Product is transferred to the recipient in perpetuity or for a
322
+ fixed term (regardless of how the transaction is characterized), the
323
+ Corresponding Source conveyed under this section must be accompanied
324
+ by the Installation Information. But this requirement does not apply
325
+ if neither you nor any third party retains the ability to install
326
+ modified object code on the User Product (for example, the work has
327
+ been installed in ROM).
328
+
329
+ The requirement to provide Installation Information does not include a
330
+ requirement to continue to provide support service, warranty, or updates
331
+ for a work that has been modified or installed by the recipient, or for
332
+ the User Product in which it has been modified or installed. Access to a
333
+ network may be denied when the modification itself materially and
334
+ adversely affects the operation of the network or violates the rules and
335
+ protocols for communication across the network.
336
+
337
+ Corresponding Source conveyed, and Installation Information provided,
338
+ in accord with this section must be in a format that is publicly
339
+ documented (and with an implementation available to the public in
340
+ source code form), and must require no special password or key for
341
+ unpacking, reading or copying.
342
+
343
+ 7. Additional Terms.
344
+
345
+ "Additional permissions" are terms that supplement the terms of this
346
+ License by making exceptions from one or more of its conditions.
347
+ Additional permissions that are applicable to the entire Program shall
348
+ be treated as though they were included in this License, to the extent
349
+ that they are valid under applicable law. If additional permissions
350
+ apply only to part of the Program, that part may be used separately
351
+ under those permissions, but the entire Program remains governed by
352
+ this License without regard to the additional permissions.
353
+
354
+ When you convey a copy of a covered work, you may at your option
355
+ remove any additional permissions from that copy, or from any part of
356
+ it. (Additional permissions may be written to require their own
357
+ removal in certain cases when you modify the work.) You may place
358
+ additional permissions on material, added by you to a covered work,
359
+ for which you have or can give appropriate copyright permission.
360
+
361
+ Notwithstanding any other provision of this License, for material you
362
+ add to a covered work, you may (if authorized by the copyright holders of
363
+ that material) supplement the terms of this License with terms:
364
+
365
+ a) Disclaiming warranty or limiting liability differently from the
366
+ terms of sections 15 and 16 of this License; or
367
+
368
+ b) Requiring preservation of specified reasonable legal notices or
369
+ author attributions in that material or in the Appropriate Legal
370
+ Notices displayed by works containing it; or
371
+
372
+ c) Prohibiting misrepresentation of the origin of that material, or
373
+ requiring that modified versions of such material be marked in
374
+ reasonable ways as different from the original version; or
375
+
376
+ d) Limiting the use for publicity purposes of names of licensors or
377
+ authors of the material; or
378
+
379
+ e) Declining to grant rights under trademark law for use of some
380
+ trade names, trademarks, or service marks; or
381
+
382
+ f) Requiring indemnification of licensors and authors of that
383
+ material by anyone who conveys the material (or modified versions of
384
+ it) with contractual assumptions of liability to the recipient, for
385
+ any liability that these contractual assumptions directly impose on
386
+ those licensors and authors.
387
+
388
+ All other non-permissive additional terms are considered "further
389
+ restrictions" within the meaning of section 10. If the Program as you
390
+ received it, or any part of it, contains a notice stating that it is
391
+ governed by this License along with a term that is a further
392
+ restriction, you may remove that term. If a license document contains
393
+ a further restriction but permits relicensing or conveying under this
394
+ License, you may add to a covered work material governed by the terms
395
+ of that license document, provided that the further restriction does
396
+ not survive such relicensing or conveying.
397
+
398
+ If you add terms to a covered work in accord with this section, you
399
+ must place, in the relevant source files, a statement of the
400
+ additional terms that apply to those files, or a notice indicating
401
+ where to find the applicable terms.
402
+
403
+ Additional terms, permissive or non-permissive, may be stated in the
404
+ form of a separately written license, or stated as exceptions;
405
+ the above requirements apply either way.
406
+
407
+ 8. Termination.
408
+
409
+ You may not propagate or modify a covered work except as expressly
410
+ provided under this License. Any attempt otherwise to propagate or
411
+ modify it is void, and will automatically terminate your rights under
412
+ this License (including any patent licenses granted under the third
413
+ paragraph of section 11).
414
+
415
+ However, if you cease all violation of this License, then your
416
+ license from a particular copyright holder is reinstated (a)
417
+ provisionally, unless and until the copyright holder explicitly and
418
+ finally terminates your license, and (b) permanently, if the copyright
419
+ holder fails to notify you of the violation by some reasonable means
420
+ prior to 60 days after the cessation.
421
+
422
+ Moreover, your license from a particular copyright holder is
423
+ reinstated permanently if the copyright holder notifies you of the
424
+ violation by some reasonable means, this is the first time you have
425
+ received notice of violation of this License (for any work) from that
426
+ copyright holder, and you cure the violation prior to 30 days after
427
+ your receipt of the notice.
428
+
429
+ Termination of your rights under this section does not terminate the
430
+ licenses of parties who have received copies or rights from you under
431
+ this License. If your rights have been terminated and not permanently
432
+ reinstated, you do not qualify to receive new licenses for the same
433
+ material under section 10.
434
+
435
+ 9. Acceptance Not Required for Having Copies.
436
+
437
+ You are not required to accept this License in order to receive or
438
+ run a copy of the Program. Ancillary propagation of a covered work
439
+ occurring solely as a consequence of using peer-to-peer transmission
440
+ to receive a copy likewise does not require acceptance. However,
441
+ nothing other than this License grants you permission to propagate or
442
+ modify any covered work. These actions infringe copyright if you do
443
+ not accept this License. Therefore, by modifying or propagating a
444
+ covered work, you indicate your acceptance of this License to do so.
445
+
446
+ 10. Automatic Licensing of Downstream Recipients.
447
+
448
+ Each time you convey a covered work, the recipient automatically
449
+ receives a license from the original licensors, to run, modify and
450
+ propagate that work, subject to this License. You are not responsible
451
+ for enforcing compliance by third parties with this License.
452
+
453
+ An "entity transaction" is a transaction transferring control of an
454
+ organization, or substantially all assets of one, or subdividing an
455
+ organization, or merging organizations. If propagation of a covered
456
+ work results from an entity transaction, each party to that
457
+ transaction who receives a copy of the work also receives whatever
458
+ licenses to the work the party's predecessor in interest had or could
459
+ give under the previous paragraph, plus a right to possession of the
460
+ Corresponding Source of the work from the predecessor in interest, if
461
+ the predecessor has it or can get it with reasonable efforts.
462
+
463
+ You may not impose any further restrictions on the exercise of the
464
+ rights granted or affirmed under this License. For example, you may
465
+ not impose a license fee, royalty, or other charge for exercise of
466
+ rights granted under this License, and you may not initiate litigation
467
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
468
+ any patent claim is infringed by making, using, selling, offering for
469
+ sale, or importing the Program or any portion of it.
470
+
471
+ 11. Patents.
472
+
473
+ A "contributor" is a copyright holder who authorizes use under this
474
+ License of the Program or a work on which the Program is based. The
475
+ work thus licensed is called the contributor's "contributor version".
476
+
477
+ A contributor's "essential patent claims" are all patent claims
478
+ owned or controlled by the contributor, whether already acquired or
479
+ hereafter acquired, that would be infringed by some manner, permitted
480
+ by this License, of making, using, or selling its contributor version,
481
+ but do not include claims that would be infringed only as a
482
+ consequence of further modification of the contributor version. For
483
+ purposes of this definition, "control" includes the right to grant
484
+ patent sublicenses in a manner consistent with the requirements of
485
+ this License.
486
+
487
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
488
+ patent license under the contributor's essential patent claims, to
489
+ make, use, sell, offer for sale, import and otherwise run, modify and
490
+ propagate the contents of its contributor version.
491
+
492
+ In the following three paragraphs, a "patent license" is any express
493
+ agreement or commitment, however denominated, not to enforce a patent
494
+ (such as an express permission to practice a patent or covenant not to
495
+ sue for patent infringement). To "grant" such a patent license to a
496
+ party means to make such an agreement or commitment not to enforce a
497
+ patent against the party.
498
+
499
+ If you convey a covered work, knowingly relying on a patent license,
500
+ and the Corresponding Source of the work is not available for anyone
501
+ to copy, free of charge and under the terms of this License, through a
502
+ publicly available network server or other readily accessible means,
503
+ then you must either (1) cause the Corresponding Source to be so
504
+ available, or (2) arrange to deprive yourself of the benefit of the
505
+ patent license for this particular work, or (3) arrange, in a manner
506
+ consistent with the requirements of this License, to extend the patent
507
+ license to downstream recipients. "Knowingly relying" means you have
508
+ actual knowledge that, but for the patent license, your conveying the
509
+ covered work in a country, or your recipient's use of the covered work
510
+ in a country, would infringe one or more identifiable patents in that
511
+ country that you have reason to believe are valid.
512
+
513
+ If, pursuant to or in connection with a single transaction or
514
+ arrangement, you convey, or propagate by procuring conveyance of, a
515
+ covered work, and grant a patent license to some of the parties
516
+ receiving the covered work authorizing them to use, propagate, modify
517
+ or convey a specific copy of the covered work, then the patent license
518
+ you grant is automatically extended to all recipients of the covered
519
+ work and works based on it.
520
+
521
+ A patent license is "discriminatory" if it does not include within
522
+ the scope of its coverage, prohibits the exercise of, or is
523
+ conditioned on the non-exercise of one or more of the rights that are
524
+ specifically granted under this License. You may not convey a covered
525
+ work if you are a party to an arrangement with a third party that is
526
+ in the business of distributing software, under which you make payment
527
+ to the third party based on the extent of your activity of conveying
528
+ the work, and under which the third party grants, to any of the
529
+ parties who would receive the covered work from you, a discriminatory
530
+ patent license (a) in connection with copies of the covered work
531
+ conveyed by you (or copies made from those copies), or (b) primarily
532
+ for and in connection with specific products or compilations that
533
+ contain the covered work, unless you entered into that arrangement,
534
+ or that patent license was granted, prior to 28 March 2007.
535
+
536
+ Nothing in this License shall be construed as excluding or limiting
537
+ any implied license or other defenses to infringement that may
538
+ otherwise be available to you under applicable patent law.
539
+
540
+ 12. No Surrender of Others' Freedom.
541
+
542
+ If conditions are imposed on you (whether by court order, agreement or
543
+ otherwise) that contradict the conditions of this License, they do not
544
+ excuse you from the conditions of this License. If you cannot convey a
545
+ covered work so as to satisfy simultaneously your obligations under this
546
+ License and any other pertinent obligations, then as a consequence you may
547
+ not convey it at all. For example, if you agree to terms that obligate you
548
+ to collect a royalty for further conveying from those to whom you convey
549
+ the Program, the only way you could satisfy both those terms and this
550
+ License would be to refrain entirely from conveying the Program.
551
+
552
+ 13. Use with the GNU Affero General Public License.
553
+
554
+ Notwithstanding any other provision of this License, you have
555
+ permission to link or combine any covered work with a work licensed
556
+ under version 3 of the GNU Affero General Public License into a single
557
+ combined work, and to convey the resulting work. The terms of this
558
+ License will continue to apply to the part which is the covered work,
559
+ but the special requirements of the GNU Affero General Public License,
560
+ section 13, concerning interaction through a network will apply to the
561
+ combination as such.
562
+
563
+ 14. Revised Versions of this License.
564
+
565
+ The Free Software Foundation may publish revised and/or new versions of
566
+ the GNU General Public License from time to time. Such new versions will
567
+ be similar in spirit to the present version, but may differ in detail to
568
+ address new problems or concerns.
569
+
570
+ Each version is given a distinguishing version number. If the
571
+ Program specifies that a certain numbered version of the GNU General
572
+ Public License "or any later version" applies to it, you have the
573
+ option of following the terms and conditions either of that numbered
574
+ version or of any later version published by the Free Software
575
+ Foundation. If the Program does not specify a version number of the
576
+ GNU General Public License, you may choose any version ever published
577
+ by the Free Software Foundation.
578
+
579
+ If the Program specifies that a proxy can decide which future
580
+ versions of the GNU General Public License can be used, that proxy's
581
+ public statement of acceptance of a version permanently authorizes you
582
+ to choose that version for the Program.
583
+
584
+ Later license versions may give you additional or different
585
+ permissions. However, no additional obligations are imposed on any
586
+ author or copyright holder as a result of your choosing to follow a
587
+ later version.
588
+
589
+ 15. Disclaimer of Warranty.
590
+
591
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594
+ OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596
+ PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597
+ IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598
+ ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
+
600
+ 16. Limitation of Liability.
601
+
602
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604
+ THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605
+ GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606
+ USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609
+ EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610
+ SUCH DAMAGES.
611
+
612
+ 17. Interpretation of Sections 15 and 16.
613
+
614
+ If the disclaimer of warranty and limitation of liability provided
615
+ above cannot be given local legal effect according to their terms,
616
+ reviewing courts shall apply local law that most closely approximates
617
+ an absolute waiver of all civil liability in connection with the
618
+ Program, unless a warranty or assumption of liability accompanies a
619
+ copy of the Program in return for a fee.
620
+
621
+ END OF TERMS AND CONDITIONS
622
+
623
+ How to Apply These Terms to Your New Programs
624
+
625
+ If you develop a new program, and you want it to be of the greatest
626
+ possible use to the public, the best way to achieve this is to make it
627
+ free software which everyone can redistribute and change under these terms.
628
+
629
+ To do so, attach the following notices to the program. It is safest
630
+ to attach them to the start of each source file to most effectively
631
+ state the exclusion of warranty; and each file should have at least
632
+ the "copyright" line and a pointer to where the full notice is found.
633
+
634
+ <one line to give the program's name and a brief idea of what it does.>
635
+ Copyright (C) <year> <name of author>
636
+
637
+ This program is free software: you can redistribute it and/or modify
638
+ it under the terms of the GNU General Public License as published by
639
+ the Free Software Foundation, either version 3 of the License, or
640
+ (at your option) any later version.
641
+
642
+ This program is distributed in the hope that it will be useful,
643
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
644
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645
+ GNU General Public License for more details.
646
+
647
+ You should have received a copy of the GNU General Public License
648
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
649
+
650
+ Also add information on how to contact you by electronic and paper mail.
651
+
652
+ If the program does terminal interaction, make it output a short
653
+ notice like this when it starts in an interactive mode:
654
+
655
+ <program> Copyright (C) <year> <name of author>
656
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657
+ This is free software, and you are welcome to redistribute it
658
+ under certain conditions; type `show c' for details.
659
+
660
+ The hypothetical commands `show w' and `show c' should show the appropriate
661
+ parts of the General Public License. Of course, your program's commands
662
+ might be different; for a GUI interface, you would use an "about box".
663
+
664
+ You should also get your employer (if you work as a programmer) or school,
665
+ if any, to sign a "copyright disclaimer" for the program, if necessary.
666
+ For more information on this, and how to apply and follow the GNU GPL, see
667
+ <https://www.gnu.org/licenses/>.
668
+
669
+ The GNU General Public License does not permit incorporating your program
670
+ into proprietary programs. If your program is a subroutine library, you
671
+ may consider it more useful to permit linking proprietary applications with
672
+ the library. If this is what you want to do, use the GNU Lesser General
673
+ Public License instead of this License. But first, please read
674
+ <https://www.gnu.org/licenses/why-not-lgpl.html>.
README.md ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MCP Browser Automation Server
2
+
3
+ An MCP (Model Context Protocol) server that enables AI agents to interact with websites through browser automation, with specialized support for Facebook Messenger.
4
+
5
+ ## Features
6
+
7
+ ### Messenger Tools
8
+ - `messenger_list_conversations` - List recent conversations
9
+ - `messenger_search_conversation` - Search for conversations
10
+ - `messenger_send_message` - Send text messages
11
+ - `messenger_read_messages` - Read conversation messages
12
+ - `messenger_send_file` - Send file attachments
13
+ - `messenger_get_info` - Get conversation info
14
+
15
+ ### Web Tools
16
+ - `web_navigate` - Navigate to URLs
17
+ - `web_screenshot` - Capture screenshots
18
+ - `web_click` - Click elements
19
+ - `web_type` - Type into inputs
20
+ - `web_extract_text` - Extract page text
21
+ - `web_execute_js` - Run JavaScript
22
+ - `web_wait_for` - Wait for elements
23
+ - `web_get_url` - Get current URL
24
+ - `web_accessibility_snapshot` - Get accessibility tree
25
+ - `browser_close` - Close browser
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install
31
+ npm run build
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ 1. Copy `.env.example` to `.env`
37
+ 2. (Optional) Set `EDGE_USER_DATA_DIR` to use your existing Edge profile with saved logins
38
+
39
+ To find your Edge profile path:
40
+ 1. Open Edge and go to `edge://version`
41
+ 2. Copy the "Profile Path" value
42
+
43
+ ## Usage
44
+
45
+ ### With Antigravity AI
46
+
47
+ Add to your MCP server configuration:
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "browser": {
53
+ "command": "node",
54
+ "args": ["c:/Users/User/Desktop/VSCode/MCP-Server/dist/index.js"]
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### Testing with MCP Inspector
61
+
62
+ ```bash
63
+ npm run inspector
64
+ ```
65
+
66
+ ## First Time Setup
67
+
68
+ 1. Run the server - Microsoft Edge will open
69
+ 2. Log in to Messenger manually in the browser window
70
+ 3. The server will now be able to interact with your Messenger
71
+
72
+ ## Notes
73
+
74
+ - Browser runs in visible mode for debugging/monitoring
75
+ - Uses Microsoft Edge (Chromium-based) by default
76
+ - Messenger selectors may need updates if Facebook changes their UI
STRUCTURE.md ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Project Structure
2
+
3
+ ```text
4
+ Microsoft-MCP-Server/
5
+ ├── dist/
6
+ │ ├── tools/
7
+ │ │ ├── index.d.ts
8
+ │ │ ├── index.d.ts.map
9
+ │ │ ├── index.js
10
+ │ │ ├── index.js.map
11
+ │ │ ├── messenger.d.ts
12
+ │ │ ├── messenger.d.ts.map
13
+ │ │ ├── messenger.js
14
+ │ │ ├── messenger.js.map
15
+ │ │ ├── web.d.ts
16
+ │ │ ├── web.d.ts.map
17
+ │ │ ├── web.js
18
+ │ │ └── web.js.map
19
+ │ ├── browser.d.ts
20
+ │ ├── browser.d.ts.map
21
+ │ ├── browser.js
22
+ │ ├── browser.js.map
23
+ │ ├── config.d.ts
24
+ │ ├── config.d.ts.map
25
+ │ ├── config.js
26
+ │ ├── config.js.map
27
+ │ ├── index.d.ts
28
+ │ ├── index.d.ts.map
29
+ │ ├── index.js
30
+ │ └── index.js.map
31
+ ├── src/
32
+ │ ├── tools/
33
+ │ │ ├── index.ts
34
+ │ │ ├── messenger.ts
35
+ │ │ └── web.ts
36
+ │ ├── browser.ts
37
+ │ ├── config.ts
38
+ │ └── index.ts
39
+ ├── .env
40
+ ├── .env.example
41
+ ├── .gitignore
42
+ ├── automate.ts
43
+ ├── debug-messenger.ts
44
+ ├── LICENSE
45
+ ├── list-messages.ts
46
+ ├── messenger_login_check.png
47
+ ├── package-lock.json
48
+ ├── package.json
49
+ ├── README.md
50
+ ├── TECHSTACK.md
51
+ ├── test-tabs.ts
52
+ └── tsconfig.json
53
+ ```
TECHSTACK.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Techstack
2
+
3
+ Audit of **Microsoft-MCP-Server** project files (excluding environment and cache):
4
+
5
+ | File Type | Count | Size (KB) |
6
+ | :--- | :--- | :--- |
7
+ | MPEG-TS (.ts) | 16 | 47.3 |
8
+ | Source Map (.map) | 12 | 32.3 |
9
+ | JavaScript (.js) | 6 | 31.0 |
10
+ | (no extension) | 3 | 35.7 |
11
+ | JSON (.json) | 3 | 60.7 |
12
+ | EXAMPLE (.example) | 1 | 0.4 |
13
+ | Markdown (.md) | 1 | 1.9 |
14
+ | PNG Image (.png) | 1 | 189.9 |
15
+ | **Total** | **43** | **399.2** |
automate.ts ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Automation script to navigate to Messenger and GitHub and list tabs
3
+ */
4
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
+ import { join, dirname } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const serverPath = join(__dirname, 'dist', 'index.js');
11
+
12
+ async function automate() {
13
+ const transport = new StdioClientTransport({
14
+ command: 'node',
15
+ args: [serverPath],
16
+ });
17
+
18
+ const client = new Client(
19
+ {
20
+ name: 'automation-client',
21
+ version: '1.0.0',
22
+ },
23
+ {
24
+ capabilities: {},
25
+ }
26
+ );
27
+
28
+ await client.connect(transport);
29
+
30
+ console.log('Navigating to Messenger...');
31
+ await client.callTool({
32
+ name: 'web_navigate',
33
+ arguments: { url: 'https://www.messenger.com' },
34
+ });
35
+
36
+ console.log('Opening GitHub in a new tab...');
37
+ await client.callTool({
38
+ name: 'web_new_tab',
39
+ arguments: { url: 'https://github.com' },
40
+ });
41
+
42
+ console.log('Listing tabs...');
43
+ const result = await client.callTool({
44
+ name: 'web_list_tabs',
45
+ arguments: {},
46
+ });
47
+
48
+ console.log('RESULT:' + result.content[0].text);
49
+
50
+ await transport.close();
51
+ }
52
+
53
+ automate().catch((err) => {
54
+ console.error(err);
55
+ process.exit(1);
56
+ });
debug-messenger.ts ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Script to take a screenshot and list tabs
3
+ */
4
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
+ import { join, dirname } from 'path';
7
+ import { fileURLToPath, URL } from 'url';
8
+ import { writeFileSync } from 'fs';
9
+
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ const serverPath = join(__dirname, 'dist', 'index.js');
12
+
13
+ async function debug() {
14
+ const transport = new StdioClientTransport({
15
+ command: 'node',
16
+ args: [serverPath],
17
+ });
18
+
19
+ const client = new Client(
20
+ {
21
+ name: 'debug-client',
22
+ version: '1.0.0',
23
+ },
24
+ {
25
+ capabilities: {},
26
+ }
27
+ );
28
+
29
+ await client.connect(transport);
30
+
31
+ console.log('Navigating to Messenger...');
32
+ await client.callTool({
33
+ name: 'web_navigate',
34
+ arguments: { url: 'https://www.messenger.com' },
35
+ });
36
+
37
+ console.log('Taking screenshot...');
38
+ const result = await client.callTool({
39
+ name: 'web_screenshot',
40
+ arguments: { fullPage: true },
41
+ });
42
+
43
+ if (result.content && result.content[0].text) {
44
+ const data = JSON.parse(result.content[0].text);
45
+ if (data.base64) {
46
+ const screenshotPath = join(__dirname, 'messenger_login_check.png');
47
+ writeFileSync(screenshotPath, Buffer.from(data.base64, 'base64'));
48
+ console.log('Screenshot saved to:', screenshotPath);
49
+ }
50
+ }
51
+
52
+ await transport.close();
53
+ }
54
+
55
+ debug().catch(console.error);
dist/browser.d.ts ADDED
Binary file (458 Bytes). View file
 
dist/browser.d.ts.map ADDED
Binary file (481 Bytes). View file
 
dist/browser.js ADDED
Binary file (2.76 kB). View file
 
dist/browser.js.map ADDED
Binary file (2.62 kB). View file
 
dist/config.d.ts ADDED
Binary file (490 Bytes). View file
 
dist/config.d.ts.map ADDED
Binary file (192 Bytes). View file
 
dist/config.js ADDED
Binary file (1.36 kB). View file
 
dist/config.js.map ADDED
Binary file (1.5 kB). View file
 
dist/index.d.ts ADDED
Binary file (236 Bytes). View file
 
dist/index.d.ts.map ADDED
Binary file (118 Bytes). View file
 
dist/index.js ADDED
Binary file (10.5 kB). View file
 
dist/index.js.map ADDED
Binary file (7.35 kB). View file
 
dist/tools/index.d.ts ADDED
Binary file (140 Bytes). View file
 
dist/tools/index.d.ts.map ADDED
Binary file (166 Bytes). View file
 
dist/tools/index.js ADDED
Binary file (138 Bytes). View file
 
dist/tools/index.js.map ADDED
Binary file (164 Bytes). View file
 
dist/tools/messenger.d.ts ADDED
Binary file (2.19 kB). View file
 
dist/tools/messenger.d.ts.map ADDED
Binary file (1.33 kB). View file
 
dist/tools/messenger.js ADDED
Binary file (8.75 kB). View file
 
dist/tools/messenger.js.map ADDED
Binary file (8.25 kB). View file
 
dist/tools/web.d.ts ADDED
Binary file (3.65 kB). View file
 
dist/tools/web.d.ts.map ADDED
Binary file (2.41 kB). View file
 
dist/tools/web.js ADDED
Binary file (8.25 kB). View file
 
dist/tools/web.js.map ADDED
Binary file (8.5 kB). View file
 
list-messages.ts ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Robust automation script to list Messenger conversations
3
+ */
4
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
+ import { join, dirname } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const serverPath = join(__dirname, 'dist', 'index.js');
11
+
12
+ async function listMessages() {
13
+ const transport = new StdioClientTransport({
14
+ command: 'node',
15
+ args: [serverPath],
16
+ });
17
+
18
+ const client = new Client(
19
+ {
20
+ name: 'list-messages-client',
21
+ version: '1.0.0',
22
+ },
23
+ {
24
+ capabilities: {},
25
+ }
26
+ );
27
+
28
+ await client.connect(transport);
29
+
30
+ console.log('Navigating to Messenger...');
31
+ const navResult = await client.callTool({
32
+ name: 'web_navigate',
33
+ arguments: { url: 'https://www.messenger.com' },
34
+ });
35
+ console.log('Navigation result:', navResult.content[0].text);
36
+
37
+ // Wait for page to stabilize
38
+ console.log('Waiting for Messenger load...');
39
+ await new Promise(r => setTimeout(r, 5000));
40
+
41
+ console.log('Retrieving Messenger conversations...');
42
+ const result = await client.callTool({
43
+ name: 'messenger_list_conversations',
44
+ arguments: {},
45
+ });
46
+
47
+ console.log('RESULT:' + result.content[0].text);
48
+
49
+ await transport.close();
50
+ }
51
+
52
+ listMessages().catch((err) => {
53
+ console.error(err);
54
+ process.exit(1);
55
+ });
messenger_login_check.png ADDED

Git LFS Details

  • SHA256: 4b26ad11b722b15859e3893c31fc51c9335e8dfafab44b1031610984939eef32
  • Pointer size: 131 Bytes
  • Size of remote file: 194 kB
package-lock.json ADDED
@@ -0,0 +1,1763 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "mcp-browser-server",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "mcp-browser-server",
9
+ "version": "1.0.0",
10
+ "license": "MIT",
11
+ "dependencies": {
12
+ "@modelcontextprotocol/sdk": "^1.0.0",
13
+ "playwright": "^1.48.0",
14
+ "zod": "^3.22.4"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^20.10.0",
18
+ "tsx": "^4.7.0",
19
+ "typescript": "^5.3.0"
20
+ }
21
+ },
22
+ "node_modules/@esbuild/aix-ppc64": {
23
+ "version": "0.27.3",
24
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
25
+ "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
26
+ "cpu": [
27
+ "ppc64"
28
+ ],
29
+ "dev": true,
30
+ "license": "MIT",
31
+ "optional": true,
32
+ "os": [
33
+ "aix"
34
+ ],
35
+ "engines": {
36
+ "node": ">=18"
37
+ }
38
+ },
39
+ "node_modules/@esbuild/android-arm": {
40
+ "version": "0.27.3",
41
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
42
+ "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
43
+ "cpu": [
44
+ "arm"
45
+ ],
46
+ "dev": true,
47
+ "license": "MIT",
48
+ "optional": true,
49
+ "os": [
50
+ "android"
51
+ ],
52
+ "engines": {
53
+ "node": ">=18"
54
+ }
55
+ },
56
+ "node_modules/@esbuild/android-arm64": {
57
+ "version": "0.27.3",
58
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
59
+ "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
60
+ "cpu": [
61
+ "arm64"
62
+ ],
63
+ "dev": true,
64
+ "license": "MIT",
65
+ "optional": true,
66
+ "os": [
67
+ "android"
68
+ ],
69
+ "engines": {
70
+ "node": ">=18"
71
+ }
72
+ },
73
+ "node_modules/@esbuild/android-x64": {
74
+ "version": "0.27.3",
75
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
76
+ "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
77
+ "cpu": [
78
+ "x64"
79
+ ],
80
+ "dev": true,
81
+ "license": "MIT",
82
+ "optional": true,
83
+ "os": [
84
+ "android"
85
+ ],
86
+ "engines": {
87
+ "node": ">=18"
88
+ }
89
+ },
90
+ "node_modules/@esbuild/darwin-arm64": {
91
+ "version": "0.27.3",
92
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
93
+ "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
94
+ "cpu": [
95
+ "arm64"
96
+ ],
97
+ "dev": true,
98
+ "license": "MIT",
99
+ "optional": true,
100
+ "os": [
101
+ "darwin"
102
+ ],
103
+ "engines": {
104
+ "node": ">=18"
105
+ }
106
+ },
107
+ "node_modules/@esbuild/darwin-x64": {
108
+ "version": "0.27.3",
109
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
110
+ "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
111
+ "cpu": [
112
+ "x64"
113
+ ],
114
+ "dev": true,
115
+ "license": "MIT",
116
+ "optional": true,
117
+ "os": [
118
+ "darwin"
119
+ ],
120
+ "engines": {
121
+ "node": ">=18"
122
+ }
123
+ },
124
+ "node_modules/@esbuild/freebsd-arm64": {
125
+ "version": "0.27.3",
126
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
127
+ "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
128
+ "cpu": [
129
+ "arm64"
130
+ ],
131
+ "dev": true,
132
+ "license": "MIT",
133
+ "optional": true,
134
+ "os": [
135
+ "freebsd"
136
+ ],
137
+ "engines": {
138
+ "node": ">=18"
139
+ }
140
+ },
141
+ "node_modules/@esbuild/freebsd-x64": {
142
+ "version": "0.27.3",
143
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
144
+ "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
145
+ "cpu": [
146
+ "x64"
147
+ ],
148
+ "dev": true,
149
+ "license": "MIT",
150
+ "optional": true,
151
+ "os": [
152
+ "freebsd"
153
+ ],
154
+ "engines": {
155
+ "node": ">=18"
156
+ }
157
+ },
158
+ "node_modules/@esbuild/linux-arm": {
159
+ "version": "0.27.3",
160
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
161
+ "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
162
+ "cpu": [
163
+ "arm"
164
+ ],
165
+ "dev": true,
166
+ "license": "MIT",
167
+ "optional": true,
168
+ "os": [
169
+ "linux"
170
+ ],
171
+ "engines": {
172
+ "node": ">=18"
173
+ }
174
+ },
175
+ "node_modules/@esbuild/linux-arm64": {
176
+ "version": "0.27.3",
177
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
178
+ "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
179
+ "cpu": [
180
+ "arm64"
181
+ ],
182
+ "dev": true,
183
+ "license": "MIT",
184
+ "optional": true,
185
+ "os": [
186
+ "linux"
187
+ ],
188
+ "engines": {
189
+ "node": ">=18"
190
+ }
191
+ },
192
+ "node_modules/@esbuild/linux-ia32": {
193
+ "version": "0.27.3",
194
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
195
+ "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
196
+ "cpu": [
197
+ "ia32"
198
+ ],
199
+ "dev": true,
200
+ "license": "MIT",
201
+ "optional": true,
202
+ "os": [
203
+ "linux"
204
+ ],
205
+ "engines": {
206
+ "node": ">=18"
207
+ }
208
+ },
209
+ "node_modules/@esbuild/linux-loong64": {
210
+ "version": "0.27.3",
211
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
212
+ "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
213
+ "cpu": [
214
+ "loong64"
215
+ ],
216
+ "dev": true,
217
+ "license": "MIT",
218
+ "optional": true,
219
+ "os": [
220
+ "linux"
221
+ ],
222
+ "engines": {
223
+ "node": ">=18"
224
+ }
225
+ },
226
+ "node_modules/@esbuild/linux-mips64el": {
227
+ "version": "0.27.3",
228
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
229
+ "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
230
+ "cpu": [
231
+ "mips64el"
232
+ ],
233
+ "dev": true,
234
+ "license": "MIT",
235
+ "optional": true,
236
+ "os": [
237
+ "linux"
238
+ ],
239
+ "engines": {
240
+ "node": ">=18"
241
+ }
242
+ },
243
+ "node_modules/@esbuild/linux-ppc64": {
244
+ "version": "0.27.3",
245
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
246
+ "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
247
+ "cpu": [
248
+ "ppc64"
249
+ ],
250
+ "dev": true,
251
+ "license": "MIT",
252
+ "optional": true,
253
+ "os": [
254
+ "linux"
255
+ ],
256
+ "engines": {
257
+ "node": ">=18"
258
+ }
259
+ },
260
+ "node_modules/@esbuild/linux-riscv64": {
261
+ "version": "0.27.3",
262
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
263
+ "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
264
+ "cpu": [
265
+ "riscv64"
266
+ ],
267
+ "dev": true,
268
+ "license": "MIT",
269
+ "optional": true,
270
+ "os": [
271
+ "linux"
272
+ ],
273
+ "engines": {
274
+ "node": ">=18"
275
+ }
276
+ },
277
+ "node_modules/@esbuild/linux-s390x": {
278
+ "version": "0.27.3",
279
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
280
+ "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
281
+ "cpu": [
282
+ "s390x"
283
+ ],
284
+ "dev": true,
285
+ "license": "MIT",
286
+ "optional": true,
287
+ "os": [
288
+ "linux"
289
+ ],
290
+ "engines": {
291
+ "node": ">=18"
292
+ }
293
+ },
294
+ "node_modules/@esbuild/linux-x64": {
295
+ "version": "0.27.3",
296
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
297
+ "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
298
+ "cpu": [
299
+ "x64"
300
+ ],
301
+ "dev": true,
302
+ "license": "MIT",
303
+ "optional": true,
304
+ "os": [
305
+ "linux"
306
+ ],
307
+ "engines": {
308
+ "node": ">=18"
309
+ }
310
+ },
311
+ "node_modules/@esbuild/netbsd-arm64": {
312
+ "version": "0.27.3",
313
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
314
+ "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
315
+ "cpu": [
316
+ "arm64"
317
+ ],
318
+ "dev": true,
319
+ "license": "MIT",
320
+ "optional": true,
321
+ "os": [
322
+ "netbsd"
323
+ ],
324
+ "engines": {
325
+ "node": ">=18"
326
+ }
327
+ },
328
+ "node_modules/@esbuild/netbsd-x64": {
329
+ "version": "0.27.3",
330
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
331
+ "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
332
+ "cpu": [
333
+ "x64"
334
+ ],
335
+ "dev": true,
336
+ "license": "MIT",
337
+ "optional": true,
338
+ "os": [
339
+ "netbsd"
340
+ ],
341
+ "engines": {
342
+ "node": ">=18"
343
+ }
344
+ },
345
+ "node_modules/@esbuild/openbsd-arm64": {
346
+ "version": "0.27.3",
347
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
348
+ "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
349
+ "cpu": [
350
+ "arm64"
351
+ ],
352
+ "dev": true,
353
+ "license": "MIT",
354
+ "optional": true,
355
+ "os": [
356
+ "openbsd"
357
+ ],
358
+ "engines": {
359
+ "node": ">=18"
360
+ }
361
+ },
362
+ "node_modules/@esbuild/openbsd-x64": {
363
+ "version": "0.27.3",
364
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
365
+ "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
366
+ "cpu": [
367
+ "x64"
368
+ ],
369
+ "dev": true,
370
+ "license": "MIT",
371
+ "optional": true,
372
+ "os": [
373
+ "openbsd"
374
+ ],
375
+ "engines": {
376
+ "node": ">=18"
377
+ }
378
+ },
379
+ "node_modules/@esbuild/openharmony-arm64": {
380
+ "version": "0.27.3",
381
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
382
+ "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
383
+ "cpu": [
384
+ "arm64"
385
+ ],
386
+ "dev": true,
387
+ "license": "MIT",
388
+ "optional": true,
389
+ "os": [
390
+ "openharmony"
391
+ ],
392
+ "engines": {
393
+ "node": ">=18"
394
+ }
395
+ },
396
+ "node_modules/@esbuild/sunos-x64": {
397
+ "version": "0.27.3",
398
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
399
+ "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
400
+ "cpu": [
401
+ "x64"
402
+ ],
403
+ "dev": true,
404
+ "license": "MIT",
405
+ "optional": true,
406
+ "os": [
407
+ "sunos"
408
+ ],
409
+ "engines": {
410
+ "node": ">=18"
411
+ }
412
+ },
413
+ "node_modules/@esbuild/win32-arm64": {
414
+ "version": "0.27.3",
415
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
416
+ "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
417
+ "cpu": [
418
+ "arm64"
419
+ ],
420
+ "dev": true,
421
+ "license": "MIT",
422
+ "optional": true,
423
+ "os": [
424
+ "win32"
425
+ ],
426
+ "engines": {
427
+ "node": ">=18"
428
+ }
429
+ },
430
+ "node_modules/@esbuild/win32-ia32": {
431
+ "version": "0.27.3",
432
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
433
+ "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
434
+ "cpu": [
435
+ "ia32"
436
+ ],
437
+ "dev": true,
438
+ "license": "MIT",
439
+ "optional": true,
440
+ "os": [
441
+ "win32"
442
+ ],
443
+ "engines": {
444
+ "node": ">=18"
445
+ }
446
+ },
447
+ "node_modules/@esbuild/win32-x64": {
448
+ "version": "0.27.3",
449
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
450
+ "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
451
+ "cpu": [
452
+ "x64"
453
+ ],
454
+ "dev": true,
455
+ "license": "MIT",
456
+ "optional": true,
457
+ "os": [
458
+ "win32"
459
+ ],
460
+ "engines": {
461
+ "node": ">=18"
462
+ }
463
+ },
464
+ "node_modules/@hono/node-server": {
465
+ "version": "1.19.9",
466
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz",
467
+ "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==",
468
+ "license": "MIT",
469
+ "engines": {
470
+ "node": ">=18.14.1"
471
+ },
472
+ "peerDependencies": {
473
+ "hono": "^4"
474
+ }
475
+ },
476
+ "node_modules/@modelcontextprotocol/sdk": {
477
+ "version": "1.26.0",
478
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz",
479
+ "integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==",
480
+ "license": "MIT",
481
+ "dependencies": {
482
+ "@hono/node-server": "^1.19.9",
483
+ "ajv": "^8.17.1",
484
+ "ajv-formats": "^3.0.1",
485
+ "content-type": "^1.0.5",
486
+ "cors": "^2.8.5",
487
+ "cross-spawn": "^7.0.5",
488
+ "eventsource": "^3.0.2",
489
+ "eventsource-parser": "^3.0.0",
490
+ "express": "^5.2.1",
491
+ "express-rate-limit": "^8.2.1",
492
+ "hono": "^4.11.4",
493
+ "jose": "^6.1.3",
494
+ "json-schema-typed": "^8.0.2",
495
+ "pkce-challenge": "^5.0.0",
496
+ "raw-body": "^3.0.0",
497
+ "zod": "^3.25 || ^4.0",
498
+ "zod-to-json-schema": "^3.25.1"
499
+ },
500
+ "engines": {
501
+ "node": ">=18"
502
+ },
503
+ "peerDependencies": {
504
+ "@cfworker/json-schema": "^4.1.1",
505
+ "zod": "^3.25 || ^4.0"
506
+ },
507
+ "peerDependenciesMeta": {
508
+ "@cfworker/json-schema": {
509
+ "optional": true
510
+ },
511
+ "zod": {
512
+ "optional": false
513
+ }
514
+ }
515
+ },
516
+ "node_modules/@types/node": {
517
+ "version": "20.19.33",
518
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz",
519
+ "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==",
520
+ "dev": true,
521
+ "license": "MIT",
522
+ "dependencies": {
523
+ "undici-types": "~6.21.0"
524
+ }
525
+ },
526
+ "node_modules/accepts": {
527
+ "version": "2.0.0",
528
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
529
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
530
+ "license": "MIT",
531
+ "dependencies": {
532
+ "mime-types": "^3.0.0",
533
+ "negotiator": "^1.0.0"
534
+ },
535
+ "engines": {
536
+ "node": ">= 0.6"
537
+ }
538
+ },
539
+ "node_modules/ajv": {
540
+ "version": "8.17.1",
541
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
542
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
543
+ "license": "MIT",
544
+ "dependencies": {
545
+ "fast-deep-equal": "^3.1.3",
546
+ "fast-uri": "^3.0.1",
547
+ "json-schema-traverse": "^1.0.0",
548
+ "require-from-string": "^2.0.2"
549
+ },
550
+ "funding": {
551
+ "type": "github",
552
+ "url": "https://github.com/sponsors/epoberezkin"
553
+ }
554
+ },
555
+ "node_modules/ajv-formats": {
556
+ "version": "3.0.1",
557
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
558
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
559
+ "license": "MIT",
560
+ "dependencies": {
561
+ "ajv": "^8.0.0"
562
+ },
563
+ "peerDependencies": {
564
+ "ajv": "^8.0.0"
565
+ },
566
+ "peerDependenciesMeta": {
567
+ "ajv": {
568
+ "optional": true
569
+ }
570
+ }
571
+ },
572
+ "node_modules/body-parser": {
573
+ "version": "2.2.2",
574
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
575
+ "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
576
+ "license": "MIT",
577
+ "dependencies": {
578
+ "bytes": "^3.1.2",
579
+ "content-type": "^1.0.5",
580
+ "debug": "^4.4.3",
581
+ "http-errors": "^2.0.0",
582
+ "iconv-lite": "^0.7.0",
583
+ "on-finished": "^2.4.1",
584
+ "qs": "^6.14.1",
585
+ "raw-body": "^3.0.1",
586
+ "type-is": "^2.0.1"
587
+ },
588
+ "engines": {
589
+ "node": ">=18"
590
+ },
591
+ "funding": {
592
+ "type": "opencollective",
593
+ "url": "https://opencollective.com/express"
594
+ }
595
+ },
596
+ "node_modules/bytes": {
597
+ "version": "3.1.2",
598
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
599
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
600
+ "license": "MIT",
601
+ "engines": {
602
+ "node": ">= 0.8"
603
+ }
604
+ },
605
+ "node_modules/call-bind-apply-helpers": {
606
+ "version": "1.0.2",
607
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
608
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
609
+ "license": "MIT",
610
+ "dependencies": {
611
+ "es-errors": "^1.3.0",
612
+ "function-bind": "^1.1.2"
613
+ },
614
+ "engines": {
615
+ "node": ">= 0.4"
616
+ }
617
+ },
618
+ "node_modules/call-bound": {
619
+ "version": "1.0.4",
620
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
621
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
622
+ "license": "MIT",
623
+ "dependencies": {
624
+ "call-bind-apply-helpers": "^1.0.2",
625
+ "get-intrinsic": "^1.3.0"
626
+ },
627
+ "engines": {
628
+ "node": ">= 0.4"
629
+ },
630
+ "funding": {
631
+ "url": "https://github.com/sponsors/ljharb"
632
+ }
633
+ },
634
+ "node_modules/content-disposition": {
635
+ "version": "1.0.1",
636
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
637
+ "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
638
+ "license": "MIT",
639
+ "engines": {
640
+ "node": ">=18"
641
+ },
642
+ "funding": {
643
+ "type": "opencollective",
644
+ "url": "https://opencollective.com/express"
645
+ }
646
+ },
647
+ "node_modules/content-type": {
648
+ "version": "1.0.5",
649
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
650
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
651
+ "license": "MIT",
652
+ "engines": {
653
+ "node": ">= 0.6"
654
+ }
655
+ },
656
+ "node_modules/cookie": {
657
+ "version": "0.7.2",
658
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
659
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
660
+ "license": "MIT",
661
+ "engines": {
662
+ "node": ">= 0.6"
663
+ }
664
+ },
665
+ "node_modules/cookie-signature": {
666
+ "version": "1.2.2",
667
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
668
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
669
+ "license": "MIT",
670
+ "engines": {
671
+ "node": ">=6.6.0"
672
+ }
673
+ },
674
+ "node_modules/cors": {
675
+ "version": "2.8.6",
676
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
677
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
678
+ "license": "MIT",
679
+ "dependencies": {
680
+ "object-assign": "^4",
681
+ "vary": "^1"
682
+ },
683
+ "engines": {
684
+ "node": ">= 0.10"
685
+ },
686
+ "funding": {
687
+ "type": "opencollective",
688
+ "url": "https://opencollective.com/express"
689
+ }
690
+ },
691
+ "node_modules/cross-spawn": {
692
+ "version": "7.0.6",
693
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
694
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
695
+ "license": "MIT",
696
+ "dependencies": {
697
+ "path-key": "^3.1.0",
698
+ "shebang-command": "^2.0.0",
699
+ "which": "^2.0.1"
700
+ },
701
+ "engines": {
702
+ "node": ">= 8"
703
+ }
704
+ },
705
+ "node_modules/debug": {
706
+ "version": "4.4.3",
707
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
708
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
709
+ "license": "MIT",
710
+ "dependencies": {
711
+ "ms": "^2.1.3"
712
+ },
713
+ "engines": {
714
+ "node": ">=6.0"
715
+ },
716
+ "peerDependenciesMeta": {
717
+ "supports-color": {
718
+ "optional": true
719
+ }
720
+ }
721
+ },
722
+ "node_modules/depd": {
723
+ "version": "2.0.0",
724
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
725
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
726
+ "license": "MIT",
727
+ "engines": {
728
+ "node": ">= 0.8"
729
+ }
730
+ },
731
+ "node_modules/dunder-proto": {
732
+ "version": "1.0.1",
733
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
734
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
735
+ "license": "MIT",
736
+ "dependencies": {
737
+ "call-bind-apply-helpers": "^1.0.1",
738
+ "es-errors": "^1.3.0",
739
+ "gopd": "^1.2.0"
740
+ },
741
+ "engines": {
742
+ "node": ">= 0.4"
743
+ }
744
+ },
745
+ "node_modules/ee-first": {
746
+ "version": "1.1.1",
747
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
748
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
749
+ "license": "MIT"
750
+ },
751
+ "node_modules/encodeurl": {
752
+ "version": "2.0.0",
753
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
754
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
755
+ "license": "MIT",
756
+ "engines": {
757
+ "node": ">= 0.8"
758
+ }
759
+ },
760
+ "node_modules/es-define-property": {
761
+ "version": "1.0.1",
762
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
763
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
764
+ "license": "MIT",
765
+ "engines": {
766
+ "node": ">= 0.4"
767
+ }
768
+ },
769
+ "node_modules/es-errors": {
770
+ "version": "1.3.0",
771
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
772
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
773
+ "license": "MIT",
774
+ "engines": {
775
+ "node": ">= 0.4"
776
+ }
777
+ },
778
+ "node_modules/es-object-atoms": {
779
+ "version": "1.1.1",
780
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
781
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
782
+ "license": "MIT",
783
+ "dependencies": {
784
+ "es-errors": "^1.3.0"
785
+ },
786
+ "engines": {
787
+ "node": ">= 0.4"
788
+ }
789
+ },
790
+ "node_modules/esbuild": {
791
+ "version": "0.27.3",
792
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
793
+ "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
794
+ "dev": true,
795
+ "hasInstallScript": true,
796
+ "license": "MIT",
797
+ "bin": {
798
+ "esbuild": "bin/esbuild"
799
+ },
800
+ "engines": {
801
+ "node": ">=18"
802
+ },
803
+ "optionalDependencies": {
804
+ "@esbuild/aix-ppc64": "0.27.3",
805
+ "@esbuild/android-arm": "0.27.3",
806
+ "@esbuild/android-arm64": "0.27.3",
807
+ "@esbuild/android-x64": "0.27.3",
808
+ "@esbuild/darwin-arm64": "0.27.3",
809
+ "@esbuild/darwin-x64": "0.27.3",
810
+ "@esbuild/freebsd-arm64": "0.27.3",
811
+ "@esbuild/freebsd-x64": "0.27.3",
812
+ "@esbuild/linux-arm": "0.27.3",
813
+ "@esbuild/linux-arm64": "0.27.3",
814
+ "@esbuild/linux-ia32": "0.27.3",
815
+ "@esbuild/linux-loong64": "0.27.3",
816
+ "@esbuild/linux-mips64el": "0.27.3",
817
+ "@esbuild/linux-ppc64": "0.27.3",
818
+ "@esbuild/linux-riscv64": "0.27.3",
819
+ "@esbuild/linux-s390x": "0.27.3",
820
+ "@esbuild/linux-x64": "0.27.3",
821
+ "@esbuild/netbsd-arm64": "0.27.3",
822
+ "@esbuild/netbsd-x64": "0.27.3",
823
+ "@esbuild/openbsd-arm64": "0.27.3",
824
+ "@esbuild/openbsd-x64": "0.27.3",
825
+ "@esbuild/openharmony-arm64": "0.27.3",
826
+ "@esbuild/sunos-x64": "0.27.3",
827
+ "@esbuild/win32-arm64": "0.27.3",
828
+ "@esbuild/win32-ia32": "0.27.3",
829
+ "@esbuild/win32-x64": "0.27.3"
830
+ }
831
+ },
832
+ "node_modules/escape-html": {
833
+ "version": "1.0.3",
834
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
835
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
836
+ "license": "MIT"
837
+ },
838
+ "node_modules/etag": {
839
+ "version": "1.8.1",
840
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
841
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
842
+ "license": "MIT",
843
+ "engines": {
844
+ "node": ">= 0.6"
845
+ }
846
+ },
847
+ "node_modules/eventsource": {
848
+ "version": "3.0.7",
849
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
850
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
851
+ "license": "MIT",
852
+ "dependencies": {
853
+ "eventsource-parser": "^3.0.1"
854
+ },
855
+ "engines": {
856
+ "node": ">=18.0.0"
857
+ }
858
+ },
859
+ "node_modules/eventsource-parser": {
860
+ "version": "3.0.6",
861
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz",
862
+ "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==",
863
+ "license": "MIT",
864
+ "engines": {
865
+ "node": ">=18.0.0"
866
+ }
867
+ },
868
+ "node_modules/express": {
869
+ "version": "5.2.1",
870
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
871
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
872
+ "license": "MIT",
873
+ "dependencies": {
874
+ "accepts": "^2.0.0",
875
+ "body-parser": "^2.2.1",
876
+ "content-disposition": "^1.0.0",
877
+ "content-type": "^1.0.5",
878
+ "cookie": "^0.7.1",
879
+ "cookie-signature": "^1.2.1",
880
+ "debug": "^4.4.0",
881
+ "depd": "^2.0.0",
882
+ "encodeurl": "^2.0.0",
883
+ "escape-html": "^1.0.3",
884
+ "etag": "^1.8.1",
885
+ "finalhandler": "^2.1.0",
886
+ "fresh": "^2.0.0",
887
+ "http-errors": "^2.0.0",
888
+ "merge-descriptors": "^2.0.0",
889
+ "mime-types": "^3.0.0",
890
+ "on-finished": "^2.4.1",
891
+ "once": "^1.4.0",
892
+ "parseurl": "^1.3.3",
893
+ "proxy-addr": "^2.0.7",
894
+ "qs": "^6.14.0",
895
+ "range-parser": "^1.2.1",
896
+ "router": "^2.2.0",
897
+ "send": "^1.1.0",
898
+ "serve-static": "^2.2.0",
899
+ "statuses": "^2.0.1",
900
+ "type-is": "^2.0.1",
901
+ "vary": "^1.1.2"
902
+ },
903
+ "engines": {
904
+ "node": ">= 18"
905
+ },
906
+ "funding": {
907
+ "type": "opencollective",
908
+ "url": "https://opencollective.com/express"
909
+ }
910
+ },
911
+ "node_modules/express-rate-limit": {
912
+ "version": "8.2.1",
913
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz",
914
+ "integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==",
915
+ "license": "MIT",
916
+ "dependencies": {
917
+ "ip-address": "10.0.1"
918
+ },
919
+ "engines": {
920
+ "node": ">= 16"
921
+ },
922
+ "funding": {
923
+ "url": "https://github.com/sponsors/express-rate-limit"
924
+ },
925
+ "peerDependencies": {
926
+ "express": ">= 4.11"
927
+ }
928
+ },
929
+ "node_modules/fast-deep-equal": {
930
+ "version": "3.1.3",
931
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
932
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
933
+ "license": "MIT"
934
+ },
935
+ "node_modules/fast-uri": {
936
+ "version": "3.1.0",
937
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
938
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
939
+ "funding": [
940
+ {
941
+ "type": "github",
942
+ "url": "https://github.com/sponsors/fastify"
943
+ },
944
+ {
945
+ "type": "opencollective",
946
+ "url": "https://opencollective.com/fastify"
947
+ }
948
+ ],
949
+ "license": "BSD-3-Clause"
950
+ },
951
+ "node_modules/finalhandler": {
952
+ "version": "2.1.1",
953
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
954
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
955
+ "license": "MIT",
956
+ "dependencies": {
957
+ "debug": "^4.4.0",
958
+ "encodeurl": "^2.0.0",
959
+ "escape-html": "^1.0.3",
960
+ "on-finished": "^2.4.1",
961
+ "parseurl": "^1.3.3",
962
+ "statuses": "^2.0.1"
963
+ },
964
+ "engines": {
965
+ "node": ">= 18.0.0"
966
+ },
967
+ "funding": {
968
+ "type": "opencollective",
969
+ "url": "https://opencollective.com/express"
970
+ }
971
+ },
972
+ "node_modules/forwarded": {
973
+ "version": "0.2.0",
974
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
975
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
976
+ "license": "MIT",
977
+ "engines": {
978
+ "node": ">= 0.6"
979
+ }
980
+ },
981
+ "node_modules/fresh": {
982
+ "version": "2.0.0",
983
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
984
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
985
+ "license": "MIT",
986
+ "engines": {
987
+ "node": ">= 0.8"
988
+ }
989
+ },
990
+ "node_modules/fsevents": {
991
+ "version": "2.3.2",
992
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
993
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
994
+ "hasInstallScript": true,
995
+ "license": "MIT",
996
+ "optional": true,
997
+ "os": [
998
+ "darwin"
999
+ ],
1000
+ "engines": {
1001
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1002
+ }
1003
+ },
1004
+ "node_modules/function-bind": {
1005
+ "version": "1.1.2",
1006
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
1007
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
1008
+ "license": "MIT",
1009
+ "funding": {
1010
+ "url": "https://github.com/sponsors/ljharb"
1011
+ }
1012
+ },
1013
+ "node_modules/get-intrinsic": {
1014
+ "version": "1.3.0",
1015
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
1016
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
1017
+ "license": "MIT",
1018
+ "dependencies": {
1019
+ "call-bind-apply-helpers": "^1.0.2",
1020
+ "es-define-property": "^1.0.1",
1021
+ "es-errors": "^1.3.0",
1022
+ "es-object-atoms": "^1.1.1",
1023
+ "function-bind": "^1.1.2",
1024
+ "get-proto": "^1.0.1",
1025
+ "gopd": "^1.2.0",
1026
+ "has-symbols": "^1.1.0",
1027
+ "hasown": "^2.0.2",
1028
+ "math-intrinsics": "^1.1.0"
1029
+ },
1030
+ "engines": {
1031
+ "node": ">= 0.4"
1032
+ },
1033
+ "funding": {
1034
+ "url": "https://github.com/sponsors/ljharb"
1035
+ }
1036
+ },
1037
+ "node_modules/get-proto": {
1038
+ "version": "1.0.1",
1039
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
1040
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
1041
+ "license": "MIT",
1042
+ "dependencies": {
1043
+ "dunder-proto": "^1.0.1",
1044
+ "es-object-atoms": "^1.0.0"
1045
+ },
1046
+ "engines": {
1047
+ "node": ">= 0.4"
1048
+ }
1049
+ },
1050
+ "node_modules/get-tsconfig": {
1051
+ "version": "4.13.6",
1052
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
1053
+ "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
1054
+ "dev": true,
1055
+ "license": "MIT",
1056
+ "dependencies": {
1057
+ "resolve-pkg-maps": "^1.0.0"
1058
+ },
1059
+ "funding": {
1060
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
1061
+ }
1062
+ },
1063
+ "node_modules/gopd": {
1064
+ "version": "1.2.0",
1065
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
1066
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
1067
+ "license": "MIT",
1068
+ "engines": {
1069
+ "node": ">= 0.4"
1070
+ },
1071
+ "funding": {
1072
+ "url": "https://github.com/sponsors/ljharb"
1073
+ }
1074
+ },
1075
+ "node_modules/has-symbols": {
1076
+ "version": "1.1.0",
1077
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
1078
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
1079
+ "license": "MIT",
1080
+ "engines": {
1081
+ "node": ">= 0.4"
1082
+ },
1083
+ "funding": {
1084
+ "url": "https://github.com/sponsors/ljharb"
1085
+ }
1086
+ },
1087
+ "node_modules/hasown": {
1088
+ "version": "2.0.2",
1089
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
1090
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
1091
+ "license": "MIT",
1092
+ "dependencies": {
1093
+ "function-bind": "^1.1.2"
1094
+ },
1095
+ "engines": {
1096
+ "node": ">= 0.4"
1097
+ }
1098
+ },
1099
+ "node_modules/hono": {
1100
+ "version": "4.11.9",
1101
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.9.tgz",
1102
+ "integrity": "sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ==",
1103
+ "license": "MIT",
1104
+ "engines": {
1105
+ "node": ">=16.9.0"
1106
+ }
1107
+ },
1108
+ "node_modules/http-errors": {
1109
+ "version": "2.0.1",
1110
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
1111
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
1112
+ "license": "MIT",
1113
+ "dependencies": {
1114
+ "depd": "~2.0.0",
1115
+ "inherits": "~2.0.4",
1116
+ "setprototypeof": "~1.2.0",
1117
+ "statuses": "~2.0.2",
1118
+ "toidentifier": "~1.0.1"
1119
+ },
1120
+ "engines": {
1121
+ "node": ">= 0.8"
1122
+ },
1123
+ "funding": {
1124
+ "type": "opencollective",
1125
+ "url": "https://opencollective.com/express"
1126
+ }
1127
+ },
1128
+ "node_modules/iconv-lite": {
1129
+ "version": "0.7.2",
1130
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
1131
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
1132
+ "license": "MIT",
1133
+ "dependencies": {
1134
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
1135
+ },
1136
+ "engines": {
1137
+ "node": ">=0.10.0"
1138
+ },
1139
+ "funding": {
1140
+ "type": "opencollective",
1141
+ "url": "https://opencollective.com/express"
1142
+ }
1143
+ },
1144
+ "node_modules/inherits": {
1145
+ "version": "2.0.4",
1146
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1147
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1148
+ "license": "ISC"
1149
+ },
1150
+ "node_modules/ip-address": {
1151
+ "version": "10.0.1",
1152
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
1153
+ "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
1154
+ "license": "MIT",
1155
+ "engines": {
1156
+ "node": ">= 12"
1157
+ }
1158
+ },
1159
+ "node_modules/ipaddr.js": {
1160
+ "version": "1.9.1",
1161
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
1162
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
1163
+ "license": "MIT",
1164
+ "engines": {
1165
+ "node": ">= 0.10"
1166
+ }
1167
+ },
1168
+ "node_modules/is-promise": {
1169
+ "version": "4.0.0",
1170
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
1171
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
1172
+ "license": "MIT"
1173
+ },
1174
+ "node_modules/isexe": {
1175
+ "version": "2.0.0",
1176
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1177
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1178
+ "license": "ISC"
1179
+ },
1180
+ "node_modules/jose": {
1181
+ "version": "6.1.3",
1182
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz",
1183
+ "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==",
1184
+ "license": "MIT",
1185
+ "funding": {
1186
+ "url": "https://github.com/sponsors/panva"
1187
+ }
1188
+ },
1189
+ "node_modules/json-schema-traverse": {
1190
+ "version": "1.0.0",
1191
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
1192
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
1193
+ "license": "MIT"
1194
+ },
1195
+ "node_modules/json-schema-typed": {
1196
+ "version": "8.0.2",
1197
+ "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
1198
+ "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
1199
+ "license": "BSD-2-Clause"
1200
+ },
1201
+ "node_modules/math-intrinsics": {
1202
+ "version": "1.1.0",
1203
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
1204
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
1205
+ "license": "MIT",
1206
+ "engines": {
1207
+ "node": ">= 0.4"
1208
+ }
1209
+ },
1210
+ "node_modules/media-typer": {
1211
+ "version": "1.1.0",
1212
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
1213
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
1214
+ "license": "MIT",
1215
+ "engines": {
1216
+ "node": ">= 0.8"
1217
+ }
1218
+ },
1219
+ "node_modules/merge-descriptors": {
1220
+ "version": "2.0.0",
1221
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
1222
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
1223
+ "license": "MIT",
1224
+ "engines": {
1225
+ "node": ">=18"
1226
+ },
1227
+ "funding": {
1228
+ "url": "https://github.com/sponsors/sindresorhus"
1229
+ }
1230
+ },
1231
+ "node_modules/mime-db": {
1232
+ "version": "1.54.0",
1233
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
1234
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
1235
+ "license": "MIT",
1236
+ "engines": {
1237
+ "node": ">= 0.6"
1238
+ }
1239
+ },
1240
+ "node_modules/mime-types": {
1241
+ "version": "3.0.2",
1242
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
1243
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
1244
+ "license": "MIT",
1245
+ "dependencies": {
1246
+ "mime-db": "^1.54.0"
1247
+ },
1248
+ "engines": {
1249
+ "node": ">=18"
1250
+ },
1251
+ "funding": {
1252
+ "type": "opencollective",
1253
+ "url": "https://opencollective.com/express"
1254
+ }
1255
+ },
1256
+ "node_modules/ms": {
1257
+ "version": "2.1.3",
1258
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1259
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1260
+ "license": "MIT"
1261
+ },
1262
+ "node_modules/negotiator": {
1263
+ "version": "1.0.0",
1264
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
1265
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
1266
+ "license": "MIT",
1267
+ "engines": {
1268
+ "node": ">= 0.6"
1269
+ }
1270
+ },
1271
+ "node_modules/object-assign": {
1272
+ "version": "4.1.1",
1273
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1274
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1275
+ "license": "MIT",
1276
+ "engines": {
1277
+ "node": ">=0.10.0"
1278
+ }
1279
+ },
1280
+ "node_modules/object-inspect": {
1281
+ "version": "1.13.4",
1282
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
1283
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
1284
+ "license": "MIT",
1285
+ "engines": {
1286
+ "node": ">= 0.4"
1287
+ },
1288
+ "funding": {
1289
+ "url": "https://github.com/sponsors/ljharb"
1290
+ }
1291
+ },
1292
+ "node_modules/on-finished": {
1293
+ "version": "2.4.1",
1294
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1295
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1296
+ "license": "MIT",
1297
+ "dependencies": {
1298
+ "ee-first": "1.1.1"
1299
+ },
1300
+ "engines": {
1301
+ "node": ">= 0.8"
1302
+ }
1303
+ },
1304
+ "node_modules/once": {
1305
+ "version": "1.4.0",
1306
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1307
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1308
+ "license": "ISC",
1309
+ "dependencies": {
1310
+ "wrappy": "1"
1311
+ }
1312
+ },
1313
+ "node_modules/parseurl": {
1314
+ "version": "1.3.3",
1315
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1316
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1317
+ "license": "MIT",
1318
+ "engines": {
1319
+ "node": ">= 0.8"
1320
+ }
1321
+ },
1322
+ "node_modules/path-key": {
1323
+ "version": "3.1.1",
1324
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1325
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1326
+ "license": "MIT",
1327
+ "engines": {
1328
+ "node": ">=8"
1329
+ }
1330
+ },
1331
+ "node_modules/path-to-regexp": {
1332
+ "version": "8.3.0",
1333
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
1334
+ "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
1335
+ "license": "MIT",
1336
+ "funding": {
1337
+ "type": "opencollective",
1338
+ "url": "https://opencollective.com/express"
1339
+ }
1340
+ },
1341
+ "node_modules/pkce-challenge": {
1342
+ "version": "5.0.1",
1343
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
1344
+ "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
1345
+ "license": "MIT",
1346
+ "engines": {
1347
+ "node": ">=16.20.0"
1348
+ }
1349
+ },
1350
+ "node_modules/playwright": {
1351
+ "version": "1.58.2",
1352
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz",
1353
+ "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==",
1354
+ "license": "Apache-2.0",
1355
+ "dependencies": {
1356
+ "playwright-core": "1.58.2"
1357
+ },
1358
+ "bin": {
1359
+ "playwright": "cli.js"
1360
+ },
1361
+ "engines": {
1362
+ "node": ">=18"
1363
+ },
1364
+ "optionalDependencies": {
1365
+ "fsevents": "2.3.2"
1366
+ }
1367
+ },
1368
+ "node_modules/playwright-core": {
1369
+ "version": "1.58.2",
1370
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz",
1371
+ "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==",
1372
+ "license": "Apache-2.0",
1373
+ "bin": {
1374
+ "playwright-core": "cli.js"
1375
+ },
1376
+ "engines": {
1377
+ "node": ">=18"
1378
+ }
1379
+ },
1380
+ "node_modules/proxy-addr": {
1381
+ "version": "2.0.7",
1382
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1383
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1384
+ "license": "MIT",
1385
+ "dependencies": {
1386
+ "forwarded": "0.2.0",
1387
+ "ipaddr.js": "1.9.1"
1388
+ },
1389
+ "engines": {
1390
+ "node": ">= 0.10"
1391
+ }
1392
+ },
1393
+ "node_modules/qs": {
1394
+ "version": "6.14.1",
1395
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
1396
+ "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
1397
+ "license": "BSD-3-Clause",
1398
+ "dependencies": {
1399
+ "side-channel": "^1.1.0"
1400
+ },
1401
+ "engines": {
1402
+ "node": ">=0.6"
1403
+ },
1404
+ "funding": {
1405
+ "url": "https://github.com/sponsors/ljharb"
1406
+ }
1407
+ },
1408
+ "node_modules/range-parser": {
1409
+ "version": "1.2.1",
1410
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1411
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1412
+ "license": "MIT",
1413
+ "engines": {
1414
+ "node": ">= 0.6"
1415
+ }
1416
+ },
1417
+ "node_modules/raw-body": {
1418
+ "version": "3.0.2",
1419
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
1420
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
1421
+ "license": "MIT",
1422
+ "dependencies": {
1423
+ "bytes": "~3.1.2",
1424
+ "http-errors": "~2.0.1",
1425
+ "iconv-lite": "~0.7.0",
1426
+ "unpipe": "~1.0.0"
1427
+ },
1428
+ "engines": {
1429
+ "node": ">= 0.10"
1430
+ }
1431
+ },
1432
+ "node_modules/require-from-string": {
1433
+ "version": "2.0.2",
1434
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
1435
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
1436
+ "license": "MIT",
1437
+ "engines": {
1438
+ "node": ">=0.10.0"
1439
+ }
1440
+ },
1441
+ "node_modules/resolve-pkg-maps": {
1442
+ "version": "1.0.0",
1443
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
1444
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
1445
+ "dev": true,
1446
+ "license": "MIT",
1447
+ "funding": {
1448
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
1449
+ }
1450
+ },
1451
+ "node_modules/router": {
1452
+ "version": "2.2.0",
1453
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
1454
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
1455
+ "license": "MIT",
1456
+ "dependencies": {
1457
+ "debug": "^4.4.0",
1458
+ "depd": "^2.0.0",
1459
+ "is-promise": "^4.0.0",
1460
+ "parseurl": "^1.3.3",
1461
+ "path-to-regexp": "^8.0.0"
1462
+ },
1463
+ "engines": {
1464
+ "node": ">= 18"
1465
+ }
1466
+ },
1467
+ "node_modules/safer-buffer": {
1468
+ "version": "2.1.2",
1469
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1470
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1471
+ "license": "MIT"
1472
+ },
1473
+ "node_modules/send": {
1474
+ "version": "1.2.1",
1475
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
1476
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
1477
+ "license": "MIT",
1478
+ "dependencies": {
1479
+ "debug": "^4.4.3",
1480
+ "encodeurl": "^2.0.0",
1481
+ "escape-html": "^1.0.3",
1482
+ "etag": "^1.8.1",
1483
+ "fresh": "^2.0.0",
1484
+ "http-errors": "^2.0.1",
1485
+ "mime-types": "^3.0.2",
1486
+ "ms": "^2.1.3",
1487
+ "on-finished": "^2.4.1",
1488
+ "range-parser": "^1.2.1",
1489
+ "statuses": "^2.0.2"
1490
+ },
1491
+ "engines": {
1492
+ "node": ">= 18"
1493
+ },
1494
+ "funding": {
1495
+ "type": "opencollective",
1496
+ "url": "https://opencollective.com/express"
1497
+ }
1498
+ },
1499
+ "node_modules/serve-static": {
1500
+ "version": "2.2.1",
1501
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
1502
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
1503
+ "license": "MIT",
1504
+ "dependencies": {
1505
+ "encodeurl": "^2.0.0",
1506
+ "escape-html": "^1.0.3",
1507
+ "parseurl": "^1.3.3",
1508
+ "send": "^1.2.0"
1509
+ },
1510
+ "engines": {
1511
+ "node": ">= 18"
1512
+ },
1513
+ "funding": {
1514
+ "type": "opencollective",
1515
+ "url": "https://opencollective.com/express"
1516
+ }
1517
+ },
1518
+ "node_modules/setprototypeof": {
1519
+ "version": "1.2.0",
1520
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1521
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
1522
+ "license": "ISC"
1523
+ },
1524
+ "node_modules/shebang-command": {
1525
+ "version": "2.0.0",
1526
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1527
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1528
+ "license": "MIT",
1529
+ "dependencies": {
1530
+ "shebang-regex": "^3.0.0"
1531
+ },
1532
+ "engines": {
1533
+ "node": ">=8"
1534
+ }
1535
+ },
1536
+ "node_modules/shebang-regex": {
1537
+ "version": "3.0.0",
1538
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1539
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1540
+ "license": "MIT",
1541
+ "engines": {
1542
+ "node": ">=8"
1543
+ }
1544
+ },
1545
+ "node_modules/side-channel": {
1546
+ "version": "1.1.0",
1547
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
1548
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
1549
+ "license": "MIT",
1550
+ "dependencies": {
1551
+ "es-errors": "^1.3.0",
1552
+ "object-inspect": "^1.13.3",
1553
+ "side-channel-list": "^1.0.0",
1554
+ "side-channel-map": "^1.0.1",
1555
+ "side-channel-weakmap": "^1.0.2"
1556
+ },
1557
+ "engines": {
1558
+ "node": ">= 0.4"
1559
+ },
1560
+ "funding": {
1561
+ "url": "https://github.com/sponsors/ljharb"
1562
+ }
1563
+ },
1564
+ "node_modules/side-channel-list": {
1565
+ "version": "1.0.0",
1566
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
1567
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
1568
+ "license": "MIT",
1569
+ "dependencies": {
1570
+ "es-errors": "^1.3.0",
1571
+ "object-inspect": "^1.13.3"
1572
+ },
1573
+ "engines": {
1574
+ "node": ">= 0.4"
1575
+ },
1576
+ "funding": {
1577
+ "url": "https://github.com/sponsors/ljharb"
1578
+ }
1579
+ },
1580
+ "node_modules/side-channel-map": {
1581
+ "version": "1.0.1",
1582
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
1583
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
1584
+ "license": "MIT",
1585
+ "dependencies": {
1586
+ "call-bound": "^1.0.2",
1587
+ "es-errors": "^1.3.0",
1588
+ "get-intrinsic": "^1.2.5",
1589
+ "object-inspect": "^1.13.3"
1590
+ },
1591
+ "engines": {
1592
+ "node": ">= 0.4"
1593
+ },
1594
+ "funding": {
1595
+ "url": "https://github.com/sponsors/ljharb"
1596
+ }
1597
+ },
1598
+ "node_modules/side-channel-weakmap": {
1599
+ "version": "1.0.2",
1600
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
1601
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
1602
+ "license": "MIT",
1603
+ "dependencies": {
1604
+ "call-bound": "^1.0.2",
1605
+ "es-errors": "^1.3.0",
1606
+ "get-intrinsic": "^1.2.5",
1607
+ "object-inspect": "^1.13.3",
1608
+ "side-channel-map": "^1.0.1"
1609
+ },
1610
+ "engines": {
1611
+ "node": ">= 0.4"
1612
+ },
1613
+ "funding": {
1614
+ "url": "https://github.com/sponsors/ljharb"
1615
+ }
1616
+ },
1617
+ "node_modules/statuses": {
1618
+ "version": "2.0.2",
1619
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
1620
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
1621
+ "license": "MIT",
1622
+ "engines": {
1623
+ "node": ">= 0.8"
1624
+ }
1625
+ },
1626
+ "node_modules/toidentifier": {
1627
+ "version": "1.0.1",
1628
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1629
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1630
+ "license": "MIT",
1631
+ "engines": {
1632
+ "node": ">=0.6"
1633
+ }
1634
+ },
1635
+ "node_modules/tsx": {
1636
+ "version": "4.21.0",
1637
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
1638
+ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
1639
+ "dev": true,
1640
+ "license": "MIT",
1641
+ "dependencies": {
1642
+ "esbuild": "~0.27.0",
1643
+ "get-tsconfig": "^4.7.5"
1644
+ },
1645
+ "bin": {
1646
+ "tsx": "dist/cli.mjs"
1647
+ },
1648
+ "engines": {
1649
+ "node": ">=18.0.0"
1650
+ },
1651
+ "optionalDependencies": {
1652
+ "fsevents": "~2.3.3"
1653
+ }
1654
+ },
1655
+ "node_modules/tsx/node_modules/fsevents": {
1656
+ "version": "2.3.3",
1657
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1658
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1659
+ "dev": true,
1660
+ "hasInstallScript": true,
1661
+ "license": "MIT",
1662
+ "optional": true,
1663
+ "os": [
1664
+ "darwin"
1665
+ ],
1666
+ "engines": {
1667
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1668
+ }
1669
+ },
1670
+ "node_modules/type-is": {
1671
+ "version": "2.0.1",
1672
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
1673
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
1674
+ "license": "MIT",
1675
+ "dependencies": {
1676
+ "content-type": "^1.0.5",
1677
+ "media-typer": "^1.1.0",
1678
+ "mime-types": "^3.0.0"
1679
+ },
1680
+ "engines": {
1681
+ "node": ">= 0.6"
1682
+ }
1683
+ },
1684
+ "node_modules/typescript": {
1685
+ "version": "5.9.3",
1686
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
1687
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
1688
+ "dev": true,
1689
+ "license": "Apache-2.0",
1690
+ "bin": {
1691
+ "tsc": "bin/tsc",
1692
+ "tsserver": "bin/tsserver"
1693
+ },
1694
+ "engines": {
1695
+ "node": ">=14.17"
1696
+ }
1697
+ },
1698
+ "node_modules/undici-types": {
1699
+ "version": "6.21.0",
1700
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
1701
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
1702
+ "dev": true,
1703
+ "license": "MIT"
1704
+ },
1705
+ "node_modules/unpipe": {
1706
+ "version": "1.0.0",
1707
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1708
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1709
+ "license": "MIT",
1710
+ "engines": {
1711
+ "node": ">= 0.8"
1712
+ }
1713
+ },
1714
+ "node_modules/vary": {
1715
+ "version": "1.1.2",
1716
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1717
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1718
+ "license": "MIT",
1719
+ "engines": {
1720
+ "node": ">= 0.8"
1721
+ }
1722
+ },
1723
+ "node_modules/which": {
1724
+ "version": "2.0.2",
1725
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1726
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1727
+ "license": "ISC",
1728
+ "dependencies": {
1729
+ "isexe": "^2.0.0"
1730
+ },
1731
+ "bin": {
1732
+ "node-which": "bin/node-which"
1733
+ },
1734
+ "engines": {
1735
+ "node": ">= 8"
1736
+ }
1737
+ },
1738
+ "node_modules/wrappy": {
1739
+ "version": "1.0.2",
1740
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1741
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
1742
+ "license": "ISC"
1743
+ },
1744
+ "node_modules/zod": {
1745
+ "version": "3.25.76",
1746
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
1747
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
1748
+ "license": "MIT",
1749
+ "funding": {
1750
+ "url": "https://github.com/sponsors/colinhacks"
1751
+ }
1752
+ },
1753
+ "node_modules/zod-to-json-schema": {
1754
+ "version": "3.25.1",
1755
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz",
1756
+ "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==",
1757
+ "license": "ISC",
1758
+ "peerDependencies": {
1759
+ "zod": "^3.25 || ^4"
1760
+ }
1761
+ }
1762
+ }
1763
+ }
package.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "mcp-browser-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP Server for browser automation with Messenger and web integration",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "start": "node dist/index.js",
10
+ "dev": "tsx src/index.ts",
11
+ "inspector": "npx @modelcontextprotocol/inspector node dist/index.js"
12
+ },
13
+ "dependencies": {
14
+ "@modelcontextprotocol/sdk": "^1.0.0",
15
+ "playwright": "^1.48.0",
16
+ "zod": "^3.22.4"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^20.10.0",
20
+ "tsx": "^4.7.0",
21
+ "typescript": "^5.3.0"
22
+ },
23
+ "keywords": [
24
+ "mcp",
25
+ "browser-automation",
26
+ "messenger",
27
+ "playwright",
28
+ "ai-agent"
29
+ ],
30
+ "license": "MIT"
31
+ }
src/browser.ts ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Browser Manager - Handles Playwright browser lifecycle
3
+ */
4
+
5
+ import { chromium, Browser, BrowserContext, Page } from 'playwright';
6
+ import { config } from './config.js';
7
+
8
+ export class BrowserManager {
9
+ private browser: Browser | null = null;
10
+ private context: BrowserContext | null = null;
11
+ private page: Page | null = null;
12
+
13
+ async initialize(): Promise<void> {
14
+ try {
15
+ // Try to connect to an existing browser first (Remote Debugging)
16
+ this.browser = await chromium.connectOverCDP('http://localhost:9222');
17
+ this.context = this.browser.contexts()[0];
18
+ this.page = this.context.pages()[0] || await this.context.newPage();
19
+ console.error('Connected to existing browser via Remote Debugging!');
20
+ } catch (error) {
21
+ console.error('Could not connect to existing browser, launching new instance...');
22
+ if (config.browser.userDataDir) {
23
+ // launchPersistentContext launches a browser and context in one go
24
+ this.context = await chromium.launchPersistentContext(
25
+ config.browser.userDataDir,
26
+ {
27
+ channel: config.browser.type === 'msedge' ? 'msedge' : undefined,
28
+ headless: config.browser.headless,
29
+ args: [
30
+ `--profile-directory=${config.browser.profile}`,
31
+ ],
32
+ }
33
+ );
34
+ this.page = this.context.pages()[0] || await this.context.newPage();
35
+ } else {
36
+ this.browser = await chromium.launch({
37
+ channel: config.browser.type === 'msedge' ? 'msedge' : undefined,
38
+ headless: config.browser.headless,
39
+ });
40
+ this.context = await this.browser.newContext();
41
+ this.page = await this.context.newPage();
42
+ }
43
+ }
44
+
45
+ // Set default timeouts
46
+ if (this.page) {
47
+ this.page.setDefaultTimeout(config.timeouts.action);
48
+ this.page.setDefaultNavigationTimeout(config.timeouts.navigation);
49
+ }
50
+ }
51
+
52
+ async getPage(): Promise<Page> {
53
+ if (!this.page) {
54
+ await this.initialize();
55
+ }
56
+ return this.page!;
57
+ }
58
+
59
+ async close(): Promise<void> {
60
+ if (this.context) {
61
+ await this.context.close();
62
+ }
63
+ if (this.browser) {
64
+ await this.browser.close();
65
+ }
66
+ this.browser = null;
67
+ this.context = null;
68
+ this.page = null;
69
+ }
70
+
71
+ async setActivePage(page: Page): Promise<void> {
72
+ this.page = page;
73
+ this.page.setDefaultTimeout(config.timeouts.action);
74
+ this.page.setDefaultNavigationTimeout(config.timeouts.navigation);
75
+ }
76
+
77
+ isInitialized(): boolean {
78
+ return this.page !== null;
79
+ }
80
+ }
81
+
82
+ // Singleton instance
83
+ export const browserManager = new BrowserManager();
src/config.ts ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Configuration for MCP Browser Server
3
+ */
4
+
5
+ import { readFileSync, existsSync } from 'fs';
6
+ import { join, dirname } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+
11
+ // Load .env file if it exists
12
+ function loadEnv(): Record<string, string> {
13
+ const envPath = join(__dirname, '..', '.env');
14
+ const env: Record<string, string> = {};
15
+
16
+ if (existsSync(envPath)) {
17
+ const content = readFileSync(envPath, 'utf-8');
18
+ for (const line of content.split('\n')) {
19
+ const trimmed = line.trim();
20
+ if (trimmed && !trimmed.startsWith('#')) {
21
+ const [key, ...valueParts] = trimmed.split('=');
22
+ if (key) {
23
+ env[key.trim()] = valueParts.join('=').trim();
24
+ }
25
+ }
26
+ }
27
+ }
28
+
29
+ return env;
30
+ }
31
+
32
+ const env = loadEnv();
33
+
34
+ export const config = {
35
+ browser: {
36
+ type: (env.BROWSER_TYPE || 'msedge') as 'msedge' | 'chromium' | 'firefox',
37
+ userDataDir: env.EDGE_USER_DATA_DIR || undefined,
38
+ profile: env.EDGE_PROFILE || 'Default',
39
+ headless: false, // Keep visible for debugging
40
+ },
41
+ timeouts: {
42
+ navigation: parseInt(env.NAVIGATION_TIMEOUT || '30000', 10),
43
+ action: parseInt(env.ACTION_TIMEOUT || '10000', 10),
44
+ },
45
+ messenger: {
46
+ url: env.MESSENGER_URL || 'https://www.messenger.com',
47
+ },
48
+ } as const;
src/index.ts ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * MCP Browser Automation Server
5
+ *
6
+ * Provides browser automation capabilities for AI agents to interact with
7
+ * websites like Messenger through Microsoft Edge.
8
+ */
9
+
10
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
11
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
12
+ import {
13
+ CallToolRequestSchema,
14
+ ListToolsRequestSchema,
15
+ ErrorCode,
16
+ McpError,
17
+ } from '@modelcontextprotocol/sdk/types.js';
18
+
19
+ import { browserManager } from './browser.js';
20
+ import * as messenger from './tools/messenger.js';
21
+ import * as web from './tools/web.js';
22
+
23
+ // Create MCP server
24
+ const server = new Server(
25
+ {
26
+ name: 'mcp-browser-server',
27
+ version: '1.0.0',
28
+ },
29
+ {
30
+ capabilities: {
31
+ tools: {},
32
+ },
33
+ }
34
+ );
35
+
36
+ // Define available tools
37
+ const TOOLS = [
38
+ // Messenger tools
39
+ {
40
+ name: 'messenger_list_conversations',
41
+ description: 'List recent Messenger conversations',
42
+ inputSchema: {
43
+ type: 'object' as const,
44
+ properties: {},
45
+ required: [],
46
+ },
47
+ },
48
+ {
49
+ name: 'messenger_search_conversation',
50
+ description: 'Search for a Messenger conversation by name',
51
+ inputSchema: {
52
+ type: 'object' as const,
53
+ properties: {
54
+ query: { type: 'string', description: 'Search query for finding a conversation' },
55
+ },
56
+ required: ['query'],
57
+ },
58
+ },
59
+ {
60
+ name: 'messenger_send_message',
61
+ description: 'Send a message to a Messenger conversation',
62
+ inputSchema: {
63
+ type: 'object' as const,
64
+ properties: {
65
+ conversationName: { type: 'string', description: 'Name of the conversation/contact' },
66
+ message: { type: 'string', description: 'Message text to send' },
67
+ },
68
+ required: ['conversationName', 'message'],
69
+ },
70
+ },
71
+ {
72
+ name: 'messenger_read_messages',
73
+ description: 'Read messages from the current Messenger conversation',
74
+ inputSchema: {
75
+ type: 'object' as const,
76
+ properties: {
77
+ count: { type: 'number', description: 'Number of messages to read (default: 20)' },
78
+ },
79
+ required: [],
80
+ },
81
+ },
82
+ {
83
+ name: 'messenger_send_file',
84
+ description: 'Send a file to a Messenger conversation',
85
+ inputSchema: {
86
+ type: 'object' as const,
87
+ properties: {
88
+ conversationName: { type: 'string', description: 'Name of the conversation/contact' },
89
+ filePath: { type: 'string', description: 'Absolute path to the file' },
90
+ },
91
+ required: ['conversationName', 'filePath'],
92
+ },
93
+ },
94
+ {
95
+ name: 'messenger_get_info',
96
+ description: 'Get information about the current Messenger conversation',
97
+ inputSchema: {
98
+ type: 'object' as const,
99
+ properties: {},
100
+ required: [],
101
+ },
102
+ },
103
+ // Web tools
104
+ {
105
+ name: 'web_navigate',
106
+ description: 'Navigate to a URL in the browser',
107
+ inputSchema: {
108
+ type: 'object' as const,
109
+ properties: {
110
+ url: { type: 'string', description: 'The URL to navigate to' },
111
+ },
112
+ required: ['url'],
113
+ },
114
+ },
115
+ {
116
+ name: 'web_screenshot',
117
+ description: 'Take a screenshot of the current page',
118
+ inputSchema: {
119
+ type: 'object' as const,
120
+ properties: {
121
+ fullPage: { type: 'boolean', description: 'Whether to capture the full page' },
122
+ },
123
+ required: [],
124
+ },
125
+ },
126
+ {
127
+ name: 'web_click',
128
+ description: 'Click on an element by CSS selector',
129
+ inputSchema: {
130
+ type: 'object' as const,
131
+ properties: {
132
+ selector: { type: 'string', description: 'CSS selector of the element to click' },
133
+ },
134
+ required: ['selector'],
135
+ },
136
+ },
137
+ {
138
+ name: 'web_type',
139
+ description: 'Type text into an input field',
140
+ inputSchema: {
141
+ type: 'object' as const,
142
+ properties: {
143
+ selector: { type: 'string', description: 'CSS selector of the input field' },
144
+ text: { type: 'string', description: 'Text to type' },
145
+ },
146
+ required: ['selector', 'text'],
147
+ },
148
+ },
149
+ {
150
+ name: 'web_extract_text',
151
+ description: 'Extract text content from the page or specific element',
152
+ inputSchema: {
153
+ type: 'object' as const,
154
+ properties: {
155
+ selector: { type: 'string', description: 'CSS selector (default: body)' },
156
+ },
157
+ required: [],
158
+ },
159
+ },
160
+ {
161
+ name: 'web_execute_js',
162
+ description: 'Execute JavaScript on the current page',
163
+ inputSchema: {
164
+ type: 'object' as const,
165
+ properties: {
166
+ script: { type: 'string', description: 'JavaScript code to execute' },
167
+ },
168
+ required: ['script'],
169
+ },
170
+ },
171
+ {
172
+ name: 'web_wait_for',
173
+ description: 'Wait for an element to appear on the page',
174
+ inputSchema: {
175
+ type: 'object' as const,
176
+ properties: {
177
+ selector: { type: 'string', description: 'CSS selector to wait for' },
178
+ timeout: { type: 'number', description: 'Timeout in milliseconds (default: 5000)' },
179
+ },
180
+ required: ['selector'],
181
+ },
182
+ },
183
+ {
184
+ name: 'web_get_url',
185
+ description: 'Get the current page URL',
186
+ inputSchema: {
187
+ type: 'object' as const,
188
+ properties: {},
189
+ required: [],
190
+ },
191
+ },
192
+ {
193
+ name: 'web_accessibility_snapshot',
194
+ description: 'Get accessibility snapshot of the page for AI understanding',
195
+ inputSchema: {
196
+ type: 'object' as const,
197
+ properties: {},
198
+ required: [],
199
+ },
200
+ },
201
+ {
202
+ name: 'web_list_tabs',
203
+ description: 'List all open tabs/pages in the browser',
204
+ inputSchema: {
205
+ type: 'object' as const,
206
+ properties: {},
207
+ required: [],
208
+ },
209
+ },
210
+ {
211
+ name: 'web_switch_tab',
212
+ description: 'Switch to a specific tab by index',
213
+ inputSchema: {
214
+ type: 'object' as const,
215
+ properties: {
216
+ index: { type: 'number', description: 'Index of the tab to switch to (from web_list_tabs)' },
217
+ },
218
+ required: ['index'],
219
+ },
220
+ },
221
+ {
222
+ name: 'browser_close',
223
+ description: 'Close the browser',
224
+ inputSchema: {
225
+ type: 'object' as const,
226
+ properties: {},
227
+ required: [],
228
+ },
229
+ },
230
+ ];
231
+
232
+ // Handle list tools request
233
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
234
+ return { tools: TOOLS };
235
+ });
236
+
237
+ // Handle tool execution
238
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
239
+ const { name, arguments: args } = request.params;
240
+
241
+ try {
242
+ let result: unknown;
243
+
244
+ switch (name) {
245
+ // Messenger tools
246
+ case 'messenger_list_conversations':
247
+ result = await messenger.listConversations();
248
+ break;
249
+ case 'messenger_search_conversation':
250
+ result = await messenger.searchConversation((args as { query: string }).query);
251
+ break;
252
+ case 'messenger_send_message':
253
+ result = await messenger.sendMessage(
254
+ (args as { conversationName: string; message: string }).conversationName,
255
+ (args as { conversationName: string; message: string }).message
256
+ );
257
+ break;
258
+ case 'messenger_read_messages':
259
+ result = await messenger.readMessages((args as { count?: number }).count);
260
+ break;
261
+ case 'messenger_send_file':
262
+ result = await messenger.sendFile(
263
+ (args as { conversationName: string; filePath: string }).conversationName,
264
+ (args as { conversationName: string; filePath: string }).filePath
265
+ );
266
+ break;
267
+ case 'messenger_get_info':
268
+ result = await messenger.getConversationInfo();
269
+ break;
270
+ // Web tools
271
+ case 'web_navigate':
272
+ result = await web.navigate((args as { url: string }).url);
273
+ break;
274
+ case 'web_screenshot':
275
+ result = await web.screenshot((args as { fullPage?: boolean }).fullPage);
276
+ break;
277
+ case 'web_click':
278
+ result = await web.click((args as { selector: string }).selector);
279
+ break;
280
+ case 'web_type':
281
+ result = await web.type(
282
+ (args as { selector: string; text: string }).selector,
283
+ (args as { selector: string; text: string }).text
284
+ );
285
+ break;
286
+ case 'web_extract_text':
287
+ result = await web.extractText((args as { selector?: string }).selector);
288
+ break;
289
+ case 'web_execute_js':
290
+ result = await web.executeJs((args as { script: string }).script);
291
+ break;
292
+ case 'web_wait_for':
293
+ result = await web.waitFor(
294
+ (args as { selector: string; timeout?: number }).selector,
295
+ (args as { selector: string; timeout?: number }).timeout
296
+ );
297
+ break;
298
+ case 'web_get_url':
299
+ result = await web.getCurrentUrl();
300
+ break;
301
+ case 'web_accessibility_snapshot':
302
+ result = await web.getAccessibilitySnapshot();
303
+ break;
304
+ case 'web_new_tab':
305
+ result = await web.newTab((args as { url?: string }).url);
306
+ break;
307
+ case 'web_close_tab':
308
+ result = await web.closeTab();
309
+ break;
310
+ case 'web_list_tabs':
311
+ result = await web.listTabs();
312
+ break;
313
+ case 'web_switch_tab':
314
+ result = await web.switchTab((args as { index: number }).index);
315
+ break;
316
+ case 'browser_close':
317
+ await browserManager.close();
318
+ result = { success: true };
319
+ break;
320
+ default:
321
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
322
+ }
323
+
324
+ return {
325
+ content: [
326
+ {
327
+ type: 'text',
328
+ text: JSON.stringify(result, null, 2),
329
+ },
330
+ ],
331
+ };
332
+ } catch (error) {
333
+ if (error instanceof McpError) throw error;
334
+ throw new McpError(
335
+ ErrorCode.InternalError,
336
+ `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`
337
+ );
338
+ }
339
+ });
340
+
341
+ // Start the server
342
+ async function main() {
343
+ const transport = new StdioServerTransport();
344
+ await server.connect(transport);
345
+ console.error('MCP Browser Server running on stdio');
346
+ }
347
+
348
+ main().catch((error) => {
349
+ console.error('Failed to start MCP server:', error);
350
+ process.exit(1);
351
+ });
src/tools/index.ts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ /**
2
+ * Tools Index - Exports all MCP tools
3
+ */
4
+
5
+ export * from './messenger.js';
6
+ export * from './web.js';
src/tools/messenger.ts ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Messenger-specific MCP Tools
3
+ * Provides tools for interacting with Facebook Messenger
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { browserManager } from '../browser.js';
8
+ import { config } from '../config.js';
9
+
10
+ // Tool schemas
11
+ export const sendMessageSchema = z.object({
12
+ conversationName: z.string().describe('Name of the conversation/contact to send message to'),
13
+ message: z.string().describe('The message text to send'),
14
+ });
15
+
16
+ export const readMessagesSchema = z.object({
17
+ count: z.number().optional().default(20).describe('Number of messages to read (default: 20)'),
18
+ });
19
+
20
+ export const searchConversationSchema = z.object({
21
+ query: z.string().describe('Search query for finding a conversation'),
22
+ });
23
+
24
+ export const sendFileSchema = z.object({
25
+ conversationName: z.string().describe('Name of the conversation/contact'),
26
+ filePath: z.string().describe('Absolute path to the file to send'),
27
+ });
28
+
29
+ // Messenger selectors (may need updates as Messenger changes)
30
+ const SELECTORS = {
31
+ searchInput: '[aria-label="Search Messenger"]',
32
+ conversationList: '[role="navigation"] [role="row"]',
33
+ messageInput: '[aria-label="Message"]',
34
+ sendButton: '[aria-label="Press enter to send"]',
35
+ messageList: '[role="main"] [role="row"]',
36
+ fileInput: 'input[type="file"]',
37
+ attachButton: '[aria-label="Attach a file"]',
38
+ };
39
+
40
+ /**
41
+ * Navigate to Messenger and ensure we're logged in
42
+ */
43
+ export async function ensureMessengerOpen(): Promise<{ success: boolean; error?: string }> {
44
+ try {
45
+ const page = await browserManager.getPage();
46
+ const currentUrl = page.url();
47
+
48
+ const configuredUrl = config.messenger.url.replace(/\/$/, '');
49
+ const currentUrlClean = currentUrl.replace(/\/$/, '');
50
+
51
+ if (currentUrlClean !== configuredUrl) {
52
+ await page.goto(config.messenger.url);
53
+ await page.waitForLoadState('networkidle');
54
+ }
55
+
56
+ // Check if we're on the login page
57
+ const isLoginPage = await page.$('input[name="email"]');
58
+ if (isLoginPage) {
59
+ return {
60
+ success: false,
61
+ error: 'Please log in to Messenger manually in the browser window, then try again.'
62
+ };
63
+ }
64
+
65
+ return { success: true };
66
+ } catch (error) {
67
+ return { success: false, error: String(error) };
68
+ }
69
+ }
70
+
71
+ /**
72
+ * List recent conversations
73
+ */
74
+ export async function listConversations(): Promise<{ conversations: string[]; error?: string }> {
75
+ try {
76
+ const messengerStatus = await ensureMessengerOpen();
77
+ if (!messengerStatus.success) {
78
+ return { conversations: [], error: messengerStatus.error };
79
+ }
80
+
81
+ const page = await browserManager.getPage();
82
+
83
+ // Get conversation names from the sidebar
84
+ const conversations = await page.$$eval(
85
+ SELECTORS.conversationList,
86
+ (rows) => rows.slice(0, 20).map((row) => {
87
+ const nameEl = row.querySelector('[dir="auto"]');
88
+ return nameEl?.textContent?.trim() || '';
89
+ }).filter(Boolean)
90
+ );
91
+
92
+ return { conversations };
93
+ } catch (error) {
94
+ return { conversations: [], error: String(error) };
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Search for a conversation
100
+ */
101
+ export async function searchConversation(query: string): Promise<{ results: string[]; error?: string }> {
102
+ try {
103
+ const messengerStatus = await ensureMessengerOpen();
104
+ if (!messengerStatus.success) {
105
+ return { results: [], error: messengerStatus.error };
106
+ }
107
+
108
+ const page = await browserManager.getPage();
109
+
110
+ // Click search and type query
111
+ const searchInput = await page.$(SELECTORS.searchInput);
112
+ if (!searchInput) {
113
+ return { results: [], error: 'Could not find search input' };
114
+ }
115
+
116
+ await searchInput.click();
117
+ await searchInput.fill(query);
118
+ await page.waitForTimeout(1000); // Wait for search results
119
+
120
+ // Get search results
121
+ const results = await page.$$eval(
122
+ '[role="listbox"] [role="option"]',
123
+ (options) => options.map((opt) => opt.textContent?.trim() || '').filter(Boolean)
124
+ );
125
+
126
+ // Clear search
127
+ await searchInput.fill('');
128
+ await page.keyboard.press('Escape');
129
+
130
+ return { results };
131
+ } catch (error) {
132
+ return { results: [], error: String(error) };
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Open a specific conversation
138
+ */
139
+ async function openConversation(conversationName: string): Promise<{ success: boolean; error?: string }> {
140
+ try {
141
+ const page = await browserManager.getPage();
142
+
143
+ // Search for the conversation
144
+ const searchInput = await page.$(SELECTORS.searchInput);
145
+ if (!searchInput) {
146
+ return { success: false, error: 'Could not find search input' };
147
+ }
148
+
149
+ await searchInput.click();
150
+ await searchInput.fill(conversationName);
151
+ await page.waitForTimeout(1000);
152
+
153
+ // Click the first result
154
+ const firstResult = await page.$('[role="listbox"] [role="option"]');
155
+ if (!firstResult) {
156
+ return { success: false, error: `Could not find conversation: ${conversationName}` };
157
+ }
158
+
159
+ await firstResult.click();
160
+ await page.waitForTimeout(500);
161
+
162
+ return { success: true };
163
+ } catch (error) {
164
+ return { success: false, error: String(error) };
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Send a message to a conversation
170
+ */
171
+ export async function sendMessage(
172
+ conversationName: string,
173
+ message: string
174
+ ): Promise<{ success: boolean; error?: string }> {
175
+ try {
176
+ const messengerStatus = await ensureMessengerOpen();
177
+ if (!messengerStatus.success) {
178
+ return { success: false, error: messengerStatus.error };
179
+ }
180
+
181
+ const openResult = await openConversation(conversationName);
182
+ if (!openResult.success) {
183
+ return openResult;
184
+ }
185
+
186
+ const page = await browserManager.getPage();
187
+
188
+ // Find message input and send
189
+ const messageInput = await page.$(SELECTORS.messageInput);
190
+ if (!messageInput) {
191
+ return { success: false, error: 'Could not find message input' };
192
+ }
193
+
194
+ await messageInput.click();
195
+ await messageInput.fill(message);
196
+ await page.keyboard.press('Enter');
197
+ await page.waitForTimeout(500);
198
+
199
+ return { success: true };
200
+ } catch (error) {
201
+ return { success: false, error: String(error) };
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Read messages from current conversation
207
+ */
208
+ export async function readMessages(count: number = 20): Promise<{ messages: string[]; error?: string }> {
209
+ try {
210
+ const messengerStatus = await ensureMessengerOpen();
211
+ if (!messengerStatus.success) {
212
+ return { messages: [], error: messengerStatus.error };
213
+ }
214
+
215
+ const page = await browserManager.getPage();
216
+
217
+ // Get messages from the current conversation
218
+ const messages = await page.$$eval(
219
+ SELECTORS.messageList,
220
+ (rows, limit) => rows.slice(-limit).map((row) => {
221
+ const text = row.textContent?.trim() || '';
222
+ return text;
223
+ }).filter(Boolean),
224
+ count
225
+ );
226
+
227
+ return { messages };
228
+ } catch (error) {
229
+ return { messages: [], error: String(error) };
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Send a file to a conversation
235
+ */
236
+ export async function sendFile(
237
+ conversationName: string,
238
+ filePath: string
239
+ ): Promise<{ success: boolean; error?: string }> {
240
+ try {
241
+ const messengerStatus = await ensureMessengerOpen();
242
+ if (!messengerStatus.success) {
243
+ return { success: false, error: messengerStatus.error };
244
+ }
245
+
246
+ const openResult = await openConversation(conversationName);
247
+ if (!openResult.success) {
248
+ return openResult;
249
+ }
250
+
251
+ const page = await browserManager.getPage();
252
+
253
+ // Click attach button and upload file
254
+ const attachButton = await page.$(SELECTORS.attachButton);
255
+ if (attachButton) {
256
+ await attachButton.click();
257
+ }
258
+
259
+ // Set file input
260
+ const fileInput = await page.$(SELECTORS.fileInput);
261
+ if (!fileInput) {
262
+ return { success: false, error: 'Could not find file input' };
263
+ }
264
+
265
+ await fileInput.setInputFiles(filePath);
266
+ await page.waitForTimeout(1000);
267
+
268
+ // Send the file
269
+ await page.keyboard.press('Enter');
270
+ await page.waitForTimeout(1000);
271
+
272
+ return { success: true };
273
+ } catch (error) {
274
+ return { success: false, error: String(error) };
275
+ }
276
+ }
277
+
278
+ /**
279
+ * Get information about the current conversation
280
+ */
281
+ export async function getConversationInfo(): Promise<{
282
+ name?: string;
283
+ participants?: string[];
284
+ error?: string;
285
+ }> {
286
+ try {
287
+ const messengerStatus = await ensureMessengerOpen();
288
+ if (!messengerStatus.success) {
289
+ return { error: messengerStatus.error };
290
+ }
291
+
292
+ const page = await browserManager.getPage();
293
+
294
+ // Get conversation name from header
295
+ const nameEl = await page.$('[role="main"] h1, [role="main"] [dir="auto"]');
296
+ const name = await nameEl?.textContent() || undefined;
297
+
298
+ return { name, participants: name ? [name] : [] };
299
+ } catch (error) {
300
+ return { error: String(error) };
301
+ }
302
+ }
src/tools/web.ts ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * General Web Interaction MCP Tools
3
+ * Provides tools for interacting with any website
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { browserManager } from '../browser.js';
8
+
9
+ // Tool schemas
10
+ export const navigateSchema = z.object({
11
+ url: z.string().url().describe('The URL to navigate to'),
12
+ });
13
+
14
+ export const screenshotSchema = z.object({
15
+ fullPage: z.boolean().optional().default(false).describe('Whether to capture the full page'),
16
+ });
17
+
18
+ export const clickSchema = z.object({
19
+ selector: z.string().describe('CSS selector of the element to click'),
20
+ });
21
+
22
+ export const typeSchema = z.object({
23
+ selector: z.string().describe('CSS selector of the input field'),
24
+ text: z.string().describe('Text to type'),
25
+ });
26
+
27
+ export const extractTextSchema = z.object({
28
+ selector: z.string().optional().describe('CSS selector to extract text from (default: body)'),
29
+ });
30
+
31
+ export const executeJsSchema = z.object({
32
+ script: z.string().describe('JavaScript code to execute on the page'),
33
+ });
34
+
35
+ export const waitForSchema = z.object({
36
+ selector: z.string().describe('CSS selector to wait for'),
37
+ timeout: z.number().optional().default(5000).describe('Timeout in milliseconds'),
38
+ });
39
+
40
+ /**
41
+ * Navigate to a URL
42
+ */
43
+ export async function navigate(url: string): Promise<{ success: boolean; title?: string; error?: string }> {
44
+ try {
45
+ const page = await browserManager.getPage();
46
+ await page.goto(url);
47
+ await page.waitForLoadState('networkidle');
48
+ const title = await page.title();
49
+ return { success: true, title };
50
+ } catch (error) {
51
+ return { success: false, error: String(error) };
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Take a screenshot of the current page
57
+ */
58
+ export async function screenshot(fullPage: boolean = false): Promise<{
59
+ success: boolean;
60
+ base64?: string;
61
+ error?: string
62
+ }> {
63
+ try {
64
+ const page = await browserManager.getPage();
65
+ const buffer = await page.screenshot({ fullPage });
66
+ const base64 = buffer.toString('base64');
67
+ return { success: true, base64 };
68
+ } catch (error) {
69
+ return { success: false, error: String(error) };
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Click on an element
75
+ */
76
+ export async function click(selector: string): Promise<{ success: boolean; error?: string }> {
77
+ try {
78
+ const page = await browserManager.getPage();
79
+ await page.click(selector);
80
+ return { success: true };
81
+ } catch (error) {
82
+ return { success: false, error: String(error) };
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Type text into an input field
88
+ */
89
+ export async function type(selector: string, text: string): Promise<{ success: boolean; error?: string }> {
90
+ try {
91
+ const page = await browserManager.getPage();
92
+ await page.fill(selector, text);
93
+ return { success: true };
94
+ } catch (error) {
95
+ return { success: false, error: String(error) };
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Extract text content from the page or specific element
101
+ */
102
+ export async function extractText(selector?: string): Promise<{
103
+ success: boolean;
104
+ text?: string;
105
+ error?: string
106
+ }> {
107
+ try {
108
+ const page = await browserManager.getPage();
109
+ const element = selector ? await page.$(selector) : await page.$('body');
110
+
111
+ if (!element) {
112
+ return { success: false, error: `Element not found: ${selector || 'body'}` };
113
+ }
114
+
115
+ const text = await element.textContent();
116
+ return { success: true, text: text?.trim() || '' };
117
+ } catch (error) {
118
+ return { success: false, error: String(error) };
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Execute JavaScript on the page
124
+ */
125
+ export async function executeJs(script: string): Promise<{
126
+ success: boolean;
127
+ result?: unknown;
128
+ error?: string
129
+ }> {
130
+ try {
131
+ const page = await browserManager.getPage();
132
+ const result = await page.evaluate(script);
133
+ return { success: true, result };
134
+ } catch (error) {
135
+ return { success: false, error: String(error) };
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Wait for an element to appear
141
+ */
142
+ export async function waitFor(selector: string, timeout: number = 5000): Promise<{
143
+ success: boolean;
144
+ error?: string
145
+ }> {
146
+ try {
147
+ const page = await browserManager.getPage();
148
+ await page.waitForSelector(selector, { timeout });
149
+ return { success: true };
150
+ } catch (error) {
151
+ return { success: false, error: String(error) };
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Get the current page URL
157
+ */
158
+ export async function getCurrentUrl(): Promise<{ url: string; error?: string }> {
159
+ try {
160
+ const page = await browserManager.getPage();
161
+ return { url: page.url() };
162
+ } catch (error) {
163
+ return { url: '', error: String(error) };
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Open a new tab and return its index
169
+ */
170
+ export async function newTab(url?: string): Promise<{ index: number; success: boolean; error?: string }> {
171
+ try {
172
+ const page = await browserManager.getPage();
173
+ const context = page.context();
174
+ const newPage = await context.newPage();
175
+
176
+ // Update active page in manager
177
+ await browserManager.setActivePage(newPage);
178
+
179
+ if (url) {
180
+ await newPage.goto(url);
181
+ await newPage.waitForLoadState('networkidle');
182
+ }
183
+
184
+ const index = context.pages().length - 1;
185
+ return { index, success: true };
186
+ } catch (error) {
187
+ return { index: -1, success: false, error: String(error) };
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Close the current tab
193
+ */
194
+ export async function closeTab(): Promise<{ success: boolean; error?: string }> {
195
+ try {
196
+ const page = await browserManager.getPage();
197
+ const context = page.context();
198
+ const pages = context.pages();
199
+
200
+ if (pages.length <= 1) {
201
+ return { success: false, error: 'Cannot close the last remaining tab' };
202
+ }
203
+
204
+ await page.close();
205
+
206
+ // Set active page to the last one
207
+ const remainingPages = context.pages();
208
+ await browserManager.setActivePage(remainingPages[remainingPages.length - 1]);
209
+
210
+ return { success: true };
211
+ } catch (error) {
212
+ return { success: false, error: String(error) };
213
+ }
214
+ }
215
+
216
+ /**
217
+ * List all open tabs in the current browser context
218
+ */
219
+ export async function listTabs(): Promise<{
220
+ tabs: { title: string; url: string; index: number }[];
221
+ error?: string
222
+ }> {
223
+ try {
224
+ const page = await browserManager.getPage();
225
+ const context = page.context();
226
+ const pages = context.pages();
227
+
228
+ const tabs = await Promise.all(pages.map(async (p, i) => ({
229
+ title: await p.title(),
230
+ url: p.url(),
231
+ index: i
232
+ })));
233
+
234
+ return { tabs };
235
+ } catch (error) {
236
+ return { tabs: [], error: String(error) };
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Switch to a specific tab by index
242
+ */
243
+ export async function switchTab(index: number): Promise<{ success: boolean; error?: string }> {
244
+ try {
245
+ const page = await browserManager.getPage();
246
+ const context = page.context();
247
+ const pages = context.pages();
248
+
249
+ if (index < 0 || index >= pages.length) {
250
+ return { success: false, error: `Invalid tab index: ${index}` };
251
+ }
252
+
253
+ // In Playwright, we conceptually just "use" the other page object
254
+ // For MCP, we'll tell the BrowserManager to update its active page
255
+ await browserManager.setActivePage(pages[index]);
256
+
257
+ return { success: true };
258
+ } catch (error) {
259
+ return { success: false, error: String(error) };
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Get page accessibility snapshot for AI understanding
265
+ */
266
+ export async function getAccessibilitySnapshot(): Promise<{
267
+ success: boolean;
268
+ snapshot?: unknown;
269
+ error?: string
270
+ }> {
271
+ try {
272
+ const page = await browserManager.getPage();
273
+ // Use locator-based approach for accessibility info
274
+ const bodyHandle = await page.$('body');
275
+ if (!bodyHandle) {
276
+ return { success: false, error: 'Could not get page body' };
277
+ }
278
+
279
+ // Get a simplified accessibility tree by extracting key elements
280
+ const snapshot = await page.evaluate(() => {
281
+ const getAccessibleTree = (element: Element, depth = 0): object | null => {
282
+ if (depth > 5) return null;
283
+
284
+ const role = element.getAttribute('role') || element.tagName.toLowerCase();
285
+ const label = element.getAttribute('aria-label') ||
286
+ element.getAttribute('title') ||
287
+ (element as HTMLElement).innerText?.slice(0, 100);
288
+
289
+ const children: object[] = [];
290
+ for (const child of element.children) {
291
+ const childTree = getAccessibleTree(child as Element, depth + 1);
292
+ if (childTree) children.push(childTree);
293
+ }
294
+
295
+ return {
296
+ role,
297
+ name: label || undefined,
298
+ children: children.length > 0 ? children : undefined,
299
+ };
300
+ };
301
+
302
+ return getAccessibleTree(document.body);
303
+ });
304
+
305
+ return { success: true, snapshot };
306
+ } catch (error) {
307
+ return { success: false, error: String(error) };
308
+ }
309
+ }
test-tabs.ts ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Test client to verify tab listing
3
+ */
4
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
+ import { join, dirname } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const serverPath = join(__dirname, 'dist', 'index.js');
11
+
12
+ async function test() {
13
+ const transport = new StdioClientTransport({
14
+ command: 'node',
15
+ args: [serverPath],
16
+ });
17
+
18
+ const client = new Client(
19
+ {
20
+ name: 'test-client',
21
+ version: '1.0.0',
22
+ },
23
+ {
24
+ capabilities: {},
25
+ }
26
+ );
27
+
28
+ await client.connect(transport);
29
+
30
+ // Call list_tabs
31
+ const result = await client.callTool({
32
+ name: 'web_list_tabs',
33
+ arguments: {},
34
+ });
35
+
36
+ console.log(JSON.stringify(result, null, 2));
37
+
38
+ await transport.close();
39
+ }
40
+
41
+ test().catch(console.error);
tsconfig.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true
15
+ },
16
+ "include": [
17
+ "src/**/*"
18
+ ],
19
+ "exclude": [
20
+ "node_modules",
21
+ "dist"
22
+ ]
23
+ }