brave-real-browser-mcp-server 2.14.4 → 2.14.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -498,29 +498,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
498
498
  return await executeToolByName(name, args);
499
499
  });
500
500
  // Main function - now using multi-protocol launcher
501
- import { main as launcherMain } from "./launcher.js";
501
+ // Main function
502
502
  async function main() {
503
- // Check if user wants multi-protocol mode
504
- const hasProtocolArg = process.argv.some((arg) => arg === "--mode" || arg === "-m" || arg === "--http" || arg === "--lsp");
505
- if (hasProtocolArg) {
506
- // Use multi-protocol launcher
507
- await launcherMain();
508
- }
509
- else {
510
- // Default: MCP mode (backward compatibility)
511
- console.error("🔍 [DEBUG] Starting in MCP mode (default)...");
512
- console.error("💡 Tip: Use --mode http or --mode lsp for other protocols");
513
- setupProcessCleanup(async () => {
514
- await closeBrowser();
515
- await forceKillAllBraveProcesses();
516
- });
517
- const transport = new StdioServerTransport();
518
- await withErrorHandling(async () => {
519
- await server.connect(transport);
520
- console.error("🚀 Brave Real Browser MCP Server started successfully");
521
- console.error("📋 Available tools:", TOOLS.map((t) => t.name).join(", "));
522
- }, "Failed to start MCP server");
523
- }
503
+ console.error("🔍 [DEBUG] Starting in STDIO mode...");
504
+ setupProcessCleanup(async () => {
505
+ await closeBrowser();
506
+ await forceKillAllBraveProcesses();
507
+ });
508
+ const transport = new StdioServerTransport();
509
+ await withErrorHandling(async () => {
510
+ await server.connect(transport);
511
+ console.error("🚀 Brave Real Browser MCP Server started successfully");
512
+ console.error("📋 Available tools:", TOOLS.map((t) => t.name).join(", "));
513
+ }, "Failed to start MCP server");
524
514
  }
525
515
  // Enhanced error handling with debug info
526
516
  console.error("🔍 [DEBUG] Setting up error handlers...");
@@ -551,32 +541,9 @@ process.on("SIGINT", () => {
551
541
  });
552
542
  console.error("🔍 [DEBUG] All error handlers registered");
553
543
  // Start the server
554
- console.error("🔍 [DEBUG] Checking if module is main...");
555
- console.error(`🔍 [DEBUG] import.meta.url: ${import.meta.url}`);
556
- console.error(`🔍 [DEBUG] process.argv[1]: ${process.argv[1]}`);
557
- console.error(`🔍 [DEBUG] process.argv[0]: ${process.argv[0]}`);
558
- // Enhanced main module detection for npx compatibility
559
- const isMain = import.meta.url === `file://${process.argv[1]}` ||
560
- process.argv[1].includes("brave-real-browser-mcp-server") ||
561
- process.argv[1].endsWith(".bin/brave-real-browser-mcp-server") ||
562
- process.argv.some((arg) => arg.includes("brave-real-browser-mcp-server"));
563
- console.error(`🔍 [DEBUG] Enhanced main detection result: ${isMain}`);
564
- if (isMain) {
565
- console.error("🔍 [DEBUG] Module is main - starting server...");
566
- main().catch((error) => {
567
- console.error(`🔍 [DEBUG] Main function failed at ${new Date().toISOString()}`);
568
- console.error("❌ Failed to start server:", error);
569
- console.error(`🔍 [DEBUG] Error stack:`, error.stack);
570
- process.exit(1);
571
- });
572
- }
573
- else {
574
- console.error("🔍 [DEBUG] Module is not main - not starting server");
575
- console.error("🔍 [DEBUG] FORCE STARTING - This is likely an npx execution");
576
- main().catch((error) => {
577
- console.error(`🔍 [DEBUG] Forced main function failed at ${new Date().toISOString()}`);
578
- console.error("❌ Failed to start server:", error);
579
- console.error(`🔍 [DEBUG] Error stack:`, error.stack);
580
- process.exit(1);
581
- });
582
- }
544
+ main().catch((error) => {
545
+ console.error(`🔍 [DEBUG] Main function failed at ${new Date().toISOString()}`);
546
+ console.error("❌ Failed to start server:", error);
547
+ console.error(`🔍 [DEBUG] Error stack:`, error.stack);
548
+ process.exit(1);
549
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brave-real-browser-mcp-server",
3
- "version": "2.14.4",
3
+ "version": "2.14.5",
4
4
  "description": "Universal AI IDE MCP Server - Auto-detects and supports all AI IDEs (Claude Desktop, Cursor, Windsurf, Cline, Zed, VSCode, Qoder AI, etc.) with Brave browser automation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -19,12 +19,7 @@
19
19
  "build": "tsc",
20
20
  "rebuild": "npm run clean && npm run build",
21
21
  "start": "node dist/index.js",
22
- "start:http": "node dist/index.js --mode http",
23
- "start:lsp": "node dist/index.js --mode lsp",
24
- "start:all": "node dist/index.js --mode all",
25
22
  "dev": "tsx src/index.ts",
26
- "dev:http": "tsx src/index.ts --mode http",
27
- "dev:lsp": "tsx src/index.ts --mode lsp",
28
23
  "test": "vitest",
29
24
  "test:watch": "vitest --watch",
30
25
  "test:ui": "vitest --ui",
@@ -44,13 +39,12 @@
44
39
  "ajv": "^8.12.0",
45
40
  "axios": "^1.6.5",
46
41
  "brave-real-browser": "^1.5.105",
47
- "brave-real-launcher": "^1.2.19",
48
- "brave-real-puppeteer-core": "^24.26.1",
42
+ "brave-real-launcher": "^1.2.28",
43
+ "brave-real-puppeteer-core": "^24.33.0-patch.1",
49
44
  "cheerio": "^1.0.0-rc.12",
50
45
  "chrono-node": "^2.7.0",
51
46
  "compromise": "^14.13.0",
52
47
  "dotenv": "^17.2.3",
53
- "express": "^4.21.2",
54
48
  "franc": "^6.2.0",
55
49
  "libphonenumber-js": "^1.10.51",
56
50
  "natural": "^6.12.0",
@@ -60,20 +54,15 @@
60
54
  "sentiment": "^5.0.2",
61
55
  "tesseract.js": "^5.0.5",
62
56
  "turndown": "^7.2.2",
63
- "vscode-languageserver": "^9.0.1",
64
- "vscode-languageserver-textdocument": "^1.0.12",
65
- "ws": "^8.18.3",
66
57
  "xml2js": "^0.6.2"
67
58
  },
68
59
  "devDependencies": {
69
60
  "@types/cheerio": "^0.22.35",
70
- "@types/express": "^4.17.23",
71
61
  "@types/node": "latest",
72
- "@types/ws": "^8.18.1",
73
62
  "@types/xml2js": "^0.4.14",
74
63
  "@vitest/coverage-v8": "^3.2.4",
75
64
  "@vitest/ui": "^3.2.4",
76
- "rimraf": "^6.0.1",
65
+ "rimraf": "^6.1.2",
77
66
  "tsx": "latest",
78
67
  "typescript": "^5.5.3",
79
68
  "vitest": "^3.2.4"
package/dist/launcher.js DELETED
@@ -1,266 +0,0 @@
1
- #!/usr/bin/env node
2
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
- import { HttpTransport } from "./transports/http-transport.js";
4
- import { LspTransport } from "./transports/lsp-transport.js";
5
- import { SseTransport } from "./transports/sse-transport.js";
6
- import { closeBrowser, forceKillAllBraveProcesses } from "./browser-manager.js";
7
- import { setupProcessCleanup } from "./core-infrastructure.js";
8
- import { UniversalIDEAdapter, ProtocolType, } from "./universal-ide-adapter.js";
9
- export class MultiProtocolLauncher {
10
- config;
11
- httpTransport;
12
- lspTransport;
13
- sseTransport;
14
- mcpServer;
15
- universalAdapter;
16
- constructor(config = {}) {
17
- this.config = {
18
- mode: config.mode || "auto",
19
- httpPort: config.httpPort || 3000,
20
- httpHost: config.httpHost || "0.0.0.0",
21
- ssePort: config.ssePort || 3001,
22
- sseHost: config.sseHost || "0.0.0.0",
23
- enableWebSocket: config.enableWebSocket !== false,
24
- enableCors: config.enableCors !== false,
25
- enableAutoDetection: config.enableAutoDetection !== false,
26
- };
27
- }
28
- async start() {
29
- console.error("🚀 Multi-Protocol Brave Browser Server Starting...");
30
- console.error(`📡 Mode: ${this.config.mode.toUpperCase()}`);
31
- // Initialize Universal IDE Adapter if auto-detection is enabled
32
- if (this.config.enableAutoDetection && this.config.mode === "auto") {
33
- console.error("🔍 Initializing Universal IDE Adapter...");
34
- this.universalAdapter = new UniversalIDEAdapter({
35
- enableAutoDetection: true,
36
- fallbackToHttp: true,
37
- httpPort: this.config.httpPort,
38
- logDetectionDetails: true,
39
- });
40
- const detectionResult = await this.universalAdapter.initialize();
41
- // Override mode based on detection
42
- if (detectionResult.protocol === ProtocolType.MCP ||
43
- detectionResult.protocol === ProtocolType.STDIO) {
44
- this.config.mode = "mcp";
45
- }
46
- else if (detectionResult.protocol === ProtocolType.LSP) {
47
- this.config.mode = "lsp";
48
- }
49
- else if (detectionResult.protocol === ProtocolType.HTTP ||
50
- detectionResult.protocol === ProtocolType.WEBSOCKET) {
51
- this.config.mode = "http";
52
- }
53
- console.error(`✅ Auto-detected mode: ${this.config.mode.toUpperCase()}`);
54
- }
55
- // Setup cleanup handlers
56
- setupProcessCleanup(async () => {
57
- await this.stop();
58
- });
59
- switch (this.config.mode) {
60
- case "auto":
61
- // Fallback to MCP if auto-detection didn't override
62
- await this.startMcp();
63
- break;
64
- case "mcp":
65
- await this.startMcp();
66
- break;
67
- case "http":
68
- await this.startHttp();
69
- break;
70
- case "lsp":
71
- await this.startLsp();
72
- break;
73
- case "sse":
74
- await this.startSse();
75
- break;
76
- case "all":
77
- await this.startAll();
78
- break;
79
- default:
80
- throw new Error(`Unknown mode: ${this.config.mode}`);
81
- }
82
- }
83
- async startMcp() {
84
- console.error("🔵 [MCP] Starting MCP server with STDIO transport...");
85
- if (this.universalAdapter?.getDetectionResult()) {
86
- const result = this.universalAdapter.getDetectionResult();
87
- console.error(`🎯 [MCP] Optimized for: ${result.capabilities.name}`);
88
- }
89
- // Import MCP server setup from index.ts
90
- const { createMcpServer } = await import("./mcp-server.js");
91
- this.mcpServer = await createMcpServer();
92
- const transport = new StdioServerTransport();
93
- await this.mcpServer.connect(transport);
94
- console.error("✅ [MCP] Server started successfully");
95
- console.error("💡 [MCP] Compatible with: Claude Desktop, Cursor, Windsurf, Cline, Warp, Roo Coder");
96
- }
97
- async startHttp() {
98
- console.error("🟢 [HTTP] Starting HTTP/WebSocket server...");
99
- if (this.universalAdapter?.getDetectionResult()) {
100
- const result = this.universalAdapter.getDetectionResult();
101
- console.error(`🎯 [HTTP] Optimized for: ${result.capabilities.name}`);
102
- }
103
- this.httpTransport = new HttpTransport({
104
- port: this.config.httpPort,
105
- host: this.config.httpHost,
106
- enableWebSocket: this.config.enableWebSocket,
107
- });
108
- await this.httpTransport.start();
109
- console.error("💡 [HTTP] Universal mode - works with ALL AI IDEs");
110
- }
111
- async startLsp() {
112
- console.error("🟣 [LSP] Starting Language Server Protocol...");
113
- if (this.universalAdapter?.getDetectionResult()) {
114
- const result = this.universalAdapter.getDetectionResult();
115
- console.error(`🎯 [LSP] Optimized for: ${result.capabilities.name}`);
116
- }
117
- this.lspTransport = new LspTransport();
118
- await this.lspTransport.start();
119
- console.error("💡 [LSP] Compatible with: Zed Editor, VSCode, Neovim, Emacs, Sublime Text");
120
- }
121
- async startSse() {
122
- console.error("🟠 [SSE] Starting Server-Sent Events transport...");
123
- if (this.universalAdapter?.getDetectionResult()) {
124
- const result = this.universalAdapter.getDetectionResult();
125
- console.error(`🎯 [SSE] Optimized for: ${result.capabilities.name}`);
126
- }
127
- this.sseTransport = new SseTransport({
128
- port: this.config.ssePort,
129
- host: this.config.sseHost,
130
- });
131
- await this.sseTransport.start();
132
- console.error("💡 [SSE] Real-time streaming - works with web apps and modern clients");
133
- }
134
- async startAll() {
135
- console.error("🌈 Starting all protocols...");
136
- // Start HTTP in background
137
- if (!this.httpTransport) {
138
- this.httpTransport = new HttpTransport({
139
- port: this.config.httpPort,
140
- host: this.config.httpHost,
141
- enableWebSocket: this.config.enableWebSocket,
142
- });
143
- await this.httpTransport.start();
144
- }
145
- // Note: LSP and MCP use stdio/IPC, so they can't run simultaneously
146
- // In 'all' mode, we prioritize HTTP/WebSocket for universal access
147
- console.error('⚠️ [Note] MCP and LSP use stdio, so only HTTP/WebSocket is active in "all" mode');
148
- console.error("💡 Use separate instances for MCP or LSP: --mode=mcp or --mode=lsp");
149
- }
150
- async stop() {
151
- console.error("🛑 Stopping servers...");
152
- await closeBrowser();
153
- await forceKillAllBraveProcesses();
154
- if (this.httpTransport) {
155
- await this.httpTransport.stop();
156
- }
157
- if (this.lspTransport) {
158
- await this.lspTransport.stop();
159
- }
160
- if (this.sseTransport) {
161
- await this.sseTransport.stop();
162
- }
163
- console.error("✅ All servers stopped");
164
- }
165
- }
166
- // Parse CLI arguments
167
- export function parseArgs() {
168
- const args = process.argv.slice(2);
169
- const config = {};
170
- for (let i = 0; i < args.length; i++) {
171
- const arg = args[i];
172
- if (arg === "--mode" || arg === "-m") {
173
- const mode = args[++i];
174
- if (["auto", "mcp", "http", "lsp", "sse", "all"].includes(mode)) {
175
- config.mode = mode;
176
- }
177
- else {
178
- console.error(`❌ Invalid mode: ${mode}. Use: auto, mcp, http, lsp, sse, or all`);
179
- process.exit(1);
180
- }
181
- }
182
- else if (arg === "--port" || arg === "-p") {
183
- config.httpPort = parseInt(args[++i]);
184
- }
185
- else if (arg === "--sse-port") {
186
- config.ssePort = parseInt(args[++i]);
187
- }
188
- else if (arg === "--host" || arg === "-h") {
189
- config.httpHost = args[++i];
190
- }
191
- else if (arg === "--no-websocket") {
192
- config.enableWebSocket = false;
193
- }
194
- else if (arg === "--no-auto-detect") {
195
- config.enableAutoDetection = false;
196
- }
197
- else if (arg === "--list-ides") {
198
- UniversalIDEAdapter.printSupportedIDEs();
199
- process.exit(0);
200
- }
201
- else if (arg === "--help") {
202
- console.log(`
203
- Brave Real Browser MCP Server - Universal AI IDE Support
204
-
205
- Usage: brave-real-browser-mcp-server [options]
206
-
207
- Options:
208
- --mode, -m <mode> Protocol mode: auto, mcp, http, lsp, sse, or all (default: auto)
209
- --port, -p <port> HTTP server port (default: 3000)
210
- --sse-port <port> SSE server port (default: 3001)
211
- --host, -h <host> HTTP/SSE server host (default: 0.0.0.0)
212
- --no-websocket Disable WebSocket support in HTTP mode
213
- --no-auto-detect Disable automatic IDE detection
214
- --list-ides Show list of all supported AI IDEs
215
- --help Show this help message
216
-
217
- Supported AI IDEs (with auto-detection):
218
- ✓ Claude Desktop ✓ Cursor AI ✓ Windsurf
219
- ✓ Cline (VSCode) ✓ Roo Coder ✓ Zed Editor
220
- ✓ Continue.dev ✓ Qoder AI ✓ Warp Terminal
221
- ✓ GitHub Copilot ✓ Amazon CodeWhisperer ✓ Tabnine
222
- ✓ Cody (Sourcegraph) ✓ Aider ✓ Pieces for Developers
223
- ✓ VSCode (Generic) ✓ Any LSP-compatible editor
224
-
225
- Examples:
226
- # Auto mode (automatically detects your IDE and uses optimal protocol)
227
- brave-real-browser-mcp-server --mode auto
228
-
229
- # Or simply run without arguments (auto is default)
230
- brave-real-browser-mcp-server
231
-
232
- # MCP mode (for Claude Desktop, Cursor, Windsurf, Cline, Warp, Roo Coder)
233
- brave-real-browser-mcp-server --mode mcp
234
-
235
- # HTTP/WebSocket mode (universal - works with ALL IDEs)
236
- brave-real-browser-mcp-server --mode http --port 3000
237
-
238
- # LSP mode (for Zed, VSCode, Neovim, Emacs, Sublime Text)
239
- brave-real-browser-mcp-server --mode lsp
240
-
241
- # SSE mode (for real-time streaming, web apps)
242
- brave-real-browser-mcp-server --mode sse --sse-port 3001
243
-
244
- # All protocols (HTTP only, MCP/LSP/SSE need separate instances)
245
- brave-real-browser-mcp-server --mode all
246
-
247
- # Show all supported IDEs
248
- brave-real-browser-mcp-server --list-ides
249
- `);
250
- process.exit(0);
251
- }
252
- }
253
- return config;
254
- }
255
- // Main entry point
256
- export async function main() {
257
- const config = parseArgs();
258
- const launcher = new MultiProtocolLauncher(config);
259
- try {
260
- await launcher.start();
261
- }
262
- catch (error) {
263
- console.error("❌ Failed to start server:", error);
264
- process.exit(1);
265
- }
266
- }
@@ -1,198 +0,0 @@
1
- import express from 'express';
2
- import { createServer } from 'http';
3
- import { WebSocketServer } from 'ws';
4
- import { TOOLS } from '../tool-definitions.js';
5
- import { executeToolByName } from '../index.js';
6
- // Import specific handlers for direct endpoints (for backward compatibility)
7
- import { handleBrowserInit, handleBrowserClose } from '../handlers/browser-handlers.js';
8
- import { handleNavigate } from '../handlers/navigation-handlers.js';
9
- import { handleClick, handleType } from '../handlers/interaction-handlers.js';
10
- import { handleGetContent } from '../handlers/content-handlers.js';
11
- export class HttpTransport {
12
- app;
13
- server = null;
14
- wss = null;
15
- config;
16
- constructor(config = {}) {
17
- this.config = {
18
- port: config.port || 3000,
19
- host: config.host || '0.0.0.0',
20
- enableWebSocket: config.enableWebSocket !== false,
21
- corsOrigins: config.corsOrigins || ['*'],
22
- };
23
- this.app = express();
24
- this.setupMiddleware();
25
- this.setupRoutes();
26
- }
27
- setupMiddleware() {
28
- // Body parsing
29
- this.app.use(express.json());
30
- this.app.use(express.urlencoded({ extended: true }));
31
- // CORS
32
- this.app.use((req, res, next) => {
33
- res.header('Access-Control-Allow-Origin', this.config.corsOrigins?.[0] || '*');
34
- res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
35
- res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
36
- if (req.method === 'OPTIONS') {
37
- return res.sendStatus(200);
38
- }
39
- next();
40
- });
41
- // Request logging
42
- this.app.use((req, res, next) => {
43
- console.error(`📡 [HTTP] ${req.method} ${req.path} - ${new Date().toISOString()}`);
44
- next();
45
- });
46
- }
47
- setupRoutes() {
48
- // Health check
49
- this.app.get('/health', (req, res) => {
50
- res.json({ status: 'ok', timestamp: new Date().toISOString() });
51
- });
52
- // List all available tools
53
- this.app.get('/tools', (req, res) => {
54
- res.json({ tools: TOOLS });
55
- });
56
- // Execute tool - Generic endpoint
57
- this.app.post('/tools/:toolName', async (req, res) => {
58
- const { toolName } = req.params;
59
- const args = req.body;
60
- try {
61
- const result = await this.executeTool(toolName, args);
62
- res.json({ success: true, result });
63
- }
64
- catch (error) {
65
- const errorMessage = error instanceof Error ? error.message : String(error);
66
- res.status(500).json({ success: false, error: errorMessage });
67
- }
68
- });
69
- // Browser automation endpoints
70
- this.app.post('/browser/init', async (req, res) => {
71
- try {
72
- const result = await handleBrowserInit(req.body);
73
- res.json({ success: true, result });
74
- }
75
- catch (error) {
76
- res.status(500).json({ success: false, error: error.message });
77
- }
78
- });
79
- this.app.post('/browser/navigate', async (req, res) => {
80
- try {
81
- const result = await handleNavigate(req.body);
82
- res.json({ success: true, result });
83
- }
84
- catch (error) {
85
- res.status(500).json({ success: false, error: error.message });
86
- }
87
- });
88
- this.app.post('/browser/click', async (req, res) => {
89
- try {
90
- const result = await handleClick(req.body);
91
- res.json({ success: true, result });
92
- }
93
- catch (error) {
94
- res.status(500).json({ success: false, error: error.message });
95
- }
96
- });
97
- this.app.post('/browser/type', async (req, res) => {
98
- try {
99
- const result = await handleType(req.body);
100
- res.json({ success: true, result });
101
- }
102
- catch (error) {
103
- res.status(500).json({ success: false, error: error.message });
104
- }
105
- });
106
- this.app.post('/browser/get-content', async (req, res) => {
107
- try {
108
- const result = await handleGetContent(req.body);
109
- res.json({ success: true, result });
110
- }
111
- catch (error) {
112
- res.status(500).json({ success: false, error: error.message });
113
- }
114
- });
115
- this.app.post('/browser/close', async (req, res) => {
116
- try {
117
- const result = await handleBrowserClose();
118
- res.json({ success: true, result });
119
- }
120
- catch (error) {
121
- res.status(500).json({ success: false, error: error.message });
122
- }
123
- });
124
- // Error handling
125
- this.app.use((err, req, res, next) => {
126
- console.error('❌ [HTTP] Error:', err);
127
- res.status(500).json({ success: false, error: err.message });
128
- });
129
- }
130
- async executeTool(toolName, args) {
131
- // Use universal tool executor from index.ts (supports all 110 tools)
132
- return await executeToolByName(toolName, args);
133
- }
134
- setupWebSocket() {
135
- if (!this.server || !this.config.enableWebSocket)
136
- return;
137
- this.wss = new WebSocketServer({ server: this.server });
138
- this.wss.on('connection', (ws) => {
139
- console.error('🔌 [WebSocket] Client connected');
140
- ws.on('message', async (message) => {
141
- try {
142
- const data = JSON.parse(message.toString());
143
- const { id, tool, args } = data;
144
- const result = await this.executeTool(tool, args);
145
- ws.send(JSON.stringify({
146
- id,
147
- success: true,
148
- result,
149
- }));
150
- }
151
- catch (error) {
152
- const errorMessage = error instanceof Error ? error.message : String(error);
153
- ws.send(JSON.stringify({
154
- success: false,
155
- error: errorMessage,
156
- }));
157
- }
158
- });
159
- ws.on('close', () => {
160
- console.error('🔌 [WebSocket] Client disconnected');
161
- });
162
- ws.on('error', (error) => {
163
- console.error('❌ [WebSocket] Error:', error);
164
- });
165
- });
166
- }
167
- async start() {
168
- return new Promise((resolve) => {
169
- this.server = createServer(this.app);
170
- this.setupWebSocket();
171
- this.server.listen(this.config.port, this.config.host, () => {
172
- console.error(`✅ [HTTP] Server running on http://${this.config.host}:${this.config.port}`);
173
- if (this.config.enableWebSocket) {
174
- console.error(`✅ [WebSocket] Server running on ws://${this.config.host}:${this.config.port}`);
175
- }
176
- resolve();
177
- });
178
- });
179
- }
180
- async stop() {
181
- return new Promise((resolve, reject) => {
182
- if (this.wss) {
183
- this.wss.close();
184
- }
185
- if (this.server) {
186
- this.server.close((err) => {
187
- if (err)
188
- reject(err);
189
- else
190
- resolve();
191
- });
192
- }
193
- else {
194
- resolve();
195
- }
196
- });
197
- }
198
- }