browser-console-mcp 1.0.8 → 1.1.0
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/browser/index.d.ts +0 -9
- package/dist/browser/index.js +1 -1
- package/dist/client/browser-console-mcp.js +1 -1
- package/dist/client/index.d.ts +0 -2
- package/dist/client/index.js +2 -15
- package/package.json +69 -68
- package/readme.md +189 -75
- package/dist/server/index.d.ts +0 -48
- package/dist/server/index.js +0 -154
- package/dist/server/static-server.d.ts +0 -44
- package/dist/server/static-server.js +0 -205
package/dist/server/index.d.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser Console MCP Server
|
|
3
|
-
*
|
|
4
|
-
* This server runs in Cursor and handles commands from the browser console
|
|
5
|
-
*/
|
|
6
|
-
import "node:process";
|
|
7
|
-
declare class BrowserConsoleMCPServer {
|
|
8
|
-
private wss;
|
|
9
|
-
private clients;
|
|
10
|
-
private port;
|
|
11
|
-
private staticServer;
|
|
12
|
-
private httpServer;
|
|
13
|
-
constructor(port?: number, staticPort?: number);
|
|
14
|
-
/**
|
|
15
|
-
* Start server
|
|
16
|
-
*/
|
|
17
|
-
start(): void;
|
|
18
|
-
/**
|
|
19
|
-
* Setup WebSocket server
|
|
20
|
-
*/
|
|
21
|
-
private setupWebSocketServer;
|
|
22
|
-
/**
|
|
23
|
-
* Handle client messages
|
|
24
|
-
*/
|
|
25
|
-
private handleClientMessage;
|
|
26
|
-
/**
|
|
27
|
-
* Execute command
|
|
28
|
-
*/
|
|
29
|
-
private executeCommand;
|
|
30
|
-
/**
|
|
31
|
-
* Send result to client
|
|
32
|
-
*/
|
|
33
|
-
private sendResultToClient;
|
|
34
|
-
/**
|
|
35
|
-
* Send error to client
|
|
36
|
-
*/
|
|
37
|
-
private sendErrorToClient;
|
|
38
|
-
/**
|
|
39
|
-
* Generate client ID
|
|
40
|
-
*/
|
|
41
|
-
private generateClientId;
|
|
42
|
-
/**
|
|
43
|
-
* Stop server
|
|
44
|
-
*/
|
|
45
|
-
stop(): void;
|
|
46
|
-
}
|
|
47
|
-
declare const server: BrowserConsoleMCPServer;
|
|
48
|
-
export default server;
|
package/dist/server/index.js
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser Console MCP Server
|
|
3
|
-
*
|
|
4
|
-
* This server runs in Cursor and handles commands from the browser console
|
|
5
|
-
*/
|
|
6
|
-
import { exec } from "node:child_process";
|
|
7
|
-
import * as http from "node:http";
|
|
8
|
-
import "node:process";
|
|
9
|
-
import { WebSocketServer } from "ws";
|
|
10
|
-
import { StaticFileServer } from "./static-server.js";
|
|
11
|
-
class BrowserConsoleMCPServer {
|
|
12
|
-
constructor(port = 3000, staticPort = 3001) {
|
|
13
|
-
this.clients = new Map();
|
|
14
|
-
this.port = port;
|
|
15
|
-
// Create HTTP server
|
|
16
|
-
this.httpServer = http.createServer((req, res) => {
|
|
17
|
-
// Redirect to static server
|
|
18
|
-
res.writeHead(302, {
|
|
19
|
-
Location: `http://localhost:${staticPort}${req.url}`,
|
|
20
|
-
});
|
|
21
|
-
res.end();
|
|
22
|
-
});
|
|
23
|
-
// Attach WebSocket server to HTTP server
|
|
24
|
-
this.wss = new WebSocketServer({
|
|
25
|
-
server: this.httpServer,
|
|
26
|
-
path: "/ws", // Specify WebSocket path
|
|
27
|
-
});
|
|
28
|
-
this.staticServer = new StaticFileServer(staticPort);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Start server
|
|
32
|
-
*/
|
|
33
|
-
start() {
|
|
34
|
-
this.setupWebSocketServer();
|
|
35
|
-
this.staticServer.start();
|
|
36
|
-
// Start HTTP server
|
|
37
|
-
this.httpServer.listen(this.port, () => {
|
|
38
|
-
console.log(`[MCP Server] HTTP server started on port ${this.port}`);
|
|
39
|
-
console.log(`[MCP Server] WebSocket server path: ws://localhost:${this.port}/ws`);
|
|
40
|
-
console.log(`[MCP Server] Static files will be redirected to port ${this.staticServer.getPort()}`);
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Setup WebSocket server
|
|
45
|
-
*/
|
|
46
|
-
setupWebSocketServer() {
|
|
47
|
-
this.wss.on("connection", (ws) => {
|
|
48
|
-
const clientId = this.generateClientId();
|
|
49
|
-
this.clients.set(clientId, { id: clientId, ws });
|
|
50
|
-
console.log(`[MCP Server] Client ${clientId} connected`);
|
|
51
|
-
ws.on("message", (data) => {
|
|
52
|
-
try {
|
|
53
|
-
const message = JSON.parse(data.toString());
|
|
54
|
-
this.handleClientMessage(clientId, message);
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
console.error("[MCP Server] Message parsing error:", error);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
ws.on("close", () => {
|
|
61
|
-
this.clients.delete(clientId);
|
|
62
|
-
console.log(`[MCP Server] Client ${clientId} disconnected`);
|
|
63
|
-
});
|
|
64
|
-
ws.on("error", (error) => {
|
|
65
|
-
console.error(`[MCP Server] WebSocket error (client ${clientId}):`, error);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
this.wss.on("error", (error) => {
|
|
69
|
-
console.error("[MCP Server] WebSocket server error:", error);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Handle client messages
|
|
74
|
-
*/
|
|
75
|
-
handleClientMessage(clientId, message) {
|
|
76
|
-
const client = this.clients.get(clientId);
|
|
77
|
-
if (!client) {
|
|
78
|
-
console.error(`[MCP Server] Client not found: ${clientId}`);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
// Only log message type, not the full message content
|
|
82
|
-
console.log(`[MCP Server] Received message type ${message.type} from client ${clientId}`);
|
|
83
|
-
switch (message.type) {
|
|
84
|
-
case "command":
|
|
85
|
-
this.executeCommand(client, message.payload?.command);
|
|
86
|
-
break;
|
|
87
|
-
default:
|
|
88
|
-
this.sendErrorToClient(client, `Unknown message type: ${message.type}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Execute command
|
|
93
|
-
*/
|
|
94
|
-
executeCommand(client, command) {
|
|
95
|
-
if (!command) {
|
|
96
|
-
this.sendErrorToClient(client, "Command is empty");
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
console.log(`[MCP Server] Executing command: ${command}`);
|
|
100
|
-
exec(command, (error, stdout, stderr) => {
|
|
101
|
-
if (error) {
|
|
102
|
-
this.sendErrorToClient(client, `Command execution error: ${error.message}`);
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const result = stdout || stderr;
|
|
106
|
-
this.sendResultToClient(client, result);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Send result to client
|
|
111
|
-
*/
|
|
112
|
-
sendResultToClient(client, result) {
|
|
113
|
-
const message = {
|
|
114
|
-
type: "command_result",
|
|
115
|
-
payload: { result },
|
|
116
|
-
};
|
|
117
|
-
client.ws.send(JSON.stringify(message));
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Send error to client
|
|
121
|
-
*/
|
|
122
|
-
sendErrorToClient(client, error) {
|
|
123
|
-
const message = {
|
|
124
|
-
type: "error",
|
|
125
|
-
payload: { error },
|
|
126
|
-
};
|
|
127
|
-
client.ws.send(JSON.stringify(message));
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Generate client ID
|
|
131
|
-
*/
|
|
132
|
-
generateClientId() {
|
|
133
|
-
return `client_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Stop server
|
|
137
|
-
*/
|
|
138
|
-
stop() {
|
|
139
|
-
this.httpServer.close();
|
|
140
|
-
this.wss.close();
|
|
141
|
-
this.staticServer.stop();
|
|
142
|
-
console.log("[MCP Server] Server closed");
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
// Create and start server instance
|
|
146
|
-
const server = new BrowserConsoleMCPServer();
|
|
147
|
-
server.start();
|
|
148
|
-
// Handle process exit
|
|
149
|
-
process.on("SIGINT", () => {
|
|
150
|
-
console.log("[MCP Server] Shutting down server...");
|
|
151
|
-
server.stop();
|
|
152
|
-
process.exit(0);
|
|
153
|
-
});
|
|
154
|
-
export default server;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Static File Server
|
|
3
|
-
*
|
|
4
|
-
* Used to serve client JS files
|
|
5
|
-
*/
|
|
6
|
-
export declare class StaticFileServer {
|
|
7
|
-
private server;
|
|
8
|
-
private port;
|
|
9
|
-
private clientJsPath;
|
|
10
|
-
constructor(port?: number, clientJsPath?: string);
|
|
11
|
-
/**
|
|
12
|
-
* Get server port
|
|
13
|
-
*/
|
|
14
|
-
getPort(): number;
|
|
15
|
-
/**
|
|
16
|
-
* Handle HTTP requests
|
|
17
|
-
*/
|
|
18
|
-
private handleRequest;
|
|
19
|
-
/**
|
|
20
|
-
* Serve client JS file
|
|
21
|
-
*/
|
|
22
|
-
private serveClientJs;
|
|
23
|
-
/**
|
|
24
|
-
* Serve index page
|
|
25
|
-
*/
|
|
26
|
-
private serveIndexPage;
|
|
27
|
-
/**
|
|
28
|
-
* Serve html2canvas file
|
|
29
|
-
*/
|
|
30
|
-
private serveStaticFile;
|
|
31
|
-
/**
|
|
32
|
-
* Start server
|
|
33
|
-
*/
|
|
34
|
-
start(): void;
|
|
35
|
-
/**
|
|
36
|
-
* Stop server
|
|
37
|
-
*/
|
|
38
|
-
stop(): void;
|
|
39
|
-
/**
|
|
40
|
-
* Get content type based on file extension
|
|
41
|
-
*/
|
|
42
|
-
private getContentType;
|
|
43
|
-
}
|
|
44
|
-
export default StaticFileServer;
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Static File Server
|
|
3
|
-
*
|
|
4
|
-
* Used to serve client JS files
|
|
5
|
-
*/
|
|
6
|
-
import * as fs from "node:fs";
|
|
7
|
-
import * as http from "node:http";
|
|
8
|
-
import * as path from "node:path";
|
|
9
|
-
export class StaticFileServer {
|
|
10
|
-
constructor(port = 3001, clientJsPath = path.join(process.cwd(), "dist", "client", "browser-console-mcp.js")) {
|
|
11
|
-
this.port = port;
|
|
12
|
-
this.clientJsPath = clientJsPath;
|
|
13
|
-
this.server = http.createServer(this.handleRequest.bind(this));
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Get server port
|
|
17
|
-
*/
|
|
18
|
-
getPort() {
|
|
19
|
-
return this.port;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Handle HTTP requests
|
|
23
|
-
*/
|
|
24
|
-
handleRequest(req, res) {
|
|
25
|
-
// Set CORS headers, allow access from any origin
|
|
26
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
27
|
-
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
28
|
-
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
|
29
|
-
// Handle preflight requests
|
|
30
|
-
if (req.method === "OPTIONS") {
|
|
31
|
-
res.writeHead(204);
|
|
32
|
-
res.end();
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
// Only handle GET requests
|
|
36
|
-
if (req.method !== "GET") {
|
|
37
|
-
res.writeHead(405, { "Content-Type": "text/plain" });
|
|
38
|
-
res.end("Method Not Allowed");
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
// Get request path
|
|
42
|
-
const requestPath = req.url || "/";
|
|
43
|
-
// Serve client JS file
|
|
44
|
-
if (requestPath === "/browser-console-mcp.js") {
|
|
45
|
-
this.serveClientJs(res);
|
|
46
|
-
}
|
|
47
|
-
// Serve html2canvas file
|
|
48
|
-
else if (requestPath === "/html2canvas.min.js") {
|
|
49
|
-
this.serveStaticFile(path.join(process.cwd(), "dist", "static", "html2canvas.min.js"), "application/javascript", res);
|
|
50
|
-
}
|
|
51
|
-
// Try to serve files from static directory
|
|
52
|
-
else if (requestPath.startsWith("/static/")) {
|
|
53
|
-
const filePath = path.join(process.cwd(), "dist", requestPath);
|
|
54
|
-
const contentType = this.getContentType(filePath);
|
|
55
|
-
this.serveStaticFile(filePath, contentType, res);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
// Return a simple HTML page explaining how to use
|
|
59
|
-
this.serveIndexPage(res);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Serve client JS file
|
|
64
|
-
*/
|
|
65
|
-
serveClientJs(res) {
|
|
66
|
-
this.serveStaticFile(this.clientJsPath, "application/javascript", res);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Serve index page
|
|
70
|
-
*/
|
|
71
|
-
serveIndexPage(res) {
|
|
72
|
-
const html = `
|
|
73
|
-
<!DOCTYPE html>
|
|
74
|
-
<html lang="en">
|
|
75
|
-
<head>
|
|
76
|
-
<meta charset="UTF-8">
|
|
77
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
78
|
-
<title>Browser Console MCP</title>
|
|
79
|
-
<style>
|
|
80
|
-
body {
|
|
81
|
-
font-family: Arial, sans-serif;
|
|
82
|
-
line-height: 1.6;
|
|
83
|
-
max-width: 800px;
|
|
84
|
-
margin: 0 auto;
|
|
85
|
-
padding: 20px;
|
|
86
|
-
}
|
|
87
|
-
pre {
|
|
88
|
-
background-color: #f5f5f5;
|
|
89
|
-
padding: 10px;
|
|
90
|
-
border-radius: 5px;
|
|
91
|
-
overflow-x: auto;
|
|
92
|
-
}
|
|
93
|
-
code {
|
|
94
|
-
font-family: monospace;
|
|
95
|
-
}
|
|
96
|
-
</style>
|
|
97
|
-
</head>
|
|
98
|
-
<body>
|
|
99
|
-
<h1>Browser Console MCP</h1>
|
|
100
|
-
<p>This is the Browser Console MCP static file server.</p>
|
|
101
|
-
<p>Client JS file is available at the following URL:</p>
|
|
102
|
-
<pre><code>http://localhost:${this.port}/browser-console-mcp.js</code></pre>
|
|
103
|
-
|
|
104
|
-
<h2>Usage</h2>
|
|
105
|
-
<p>Paste the following code in your browser console:</p>
|
|
106
|
-
<pre><code>// Load client script
|
|
107
|
-
const script = document.createElement('script');
|
|
108
|
-
script.src = 'http://localhost:${this.port}/browser-console-mcp.js';
|
|
109
|
-
document.head.appendChild(script);</code></pre>
|
|
110
|
-
|
|
111
|
-
<p>Then interact with the server using these commands:</p>
|
|
112
|
-
<pre><code>// Execute command
|
|
113
|
-
mcp.exec('ls -la');
|
|
114
|
-
|
|
115
|
-
// View help
|
|
116
|
-
mcp.help();
|
|
117
|
-
|
|
118
|
-
// Disconnect
|
|
119
|
-
mcp.disconnect();
|
|
120
|
-
|
|
121
|
-
// Reconnect
|
|
122
|
-
mcp.reconnect();</code></pre>
|
|
123
|
-
</body>
|
|
124
|
-
</html>
|
|
125
|
-
`;
|
|
126
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
127
|
-
res.end(html);
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Serve html2canvas file
|
|
131
|
-
*/
|
|
132
|
-
serveStaticFile(filePath, contentType, res) {
|
|
133
|
-
try {
|
|
134
|
-
if (fs.existsSync(filePath)) {
|
|
135
|
-
const fileContent = fs.readFileSync(filePath);
|
|
136
|
-
// Set correct content type and cache control headers
|
|
137
|
-
res.writeHead(200, {
|
|
138
|
-
"Content-Type": contentType,
|
|
139
|
-
"Cache-Control": "no-cache, no-store, must-revalidate",
|
|
140
|
-
Pragma: "no-cache",
|
|
141
|
-
Expires: "0",
|
|
142
|
-
});
|
|
143
|
-
res.end(fileContent);
|
|
144
|
-
console.log(`[Static Server] Successfully served static file: ${filePath}`);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
console.error(`[Static Server] Static file not found: ${filePath}`);
|
|
148
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
149
|
-
res.end("File not found");
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
catch (error) {
|
|
153
|
-
console.error("[Static Server] Error serving static file:", error);
|
|
154
|
-
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
155
|
-
res.end("Internal Server Error");
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Start server
|
|
160
|
-
*/
|
|
161
|
-
start() {
|
|
162
|
-
this.server.listen(this.port, () => {
|
|
163
|
-
console.log(`[Static Server] Server started, listening on port ${this.port}`);
|
|
164
|
-
console.log(`[Static Server] Client JS file URL: http://localhost:${this.port}/browser-console-mcp.js`);
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Stop server
|
|
169
|
-
*/
|
|
170
|
-
stop() {
|
|
171
|
-
this.server.close(() => {
|
|
172
|
-
console.log("[Static Server] Server closed");
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Get content type based on file extension
|
|
177
|
-
*/
|
|
178
|
-
getContentType(filePath) {
|
|
179
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
180
|
-
switch (ext) {
|
|
181
|
-
case ".html":
|
|
182
|
-
return "text/html";
|
|
183
|
-
case ".js":
|
|
184
|
-
return "application/javascript";
|
|
185
|
-
case ".css":
|
|
186
|
-
return "text/css";
|
|
187
|
-
case ".json":
|
|
188
|
-
return "application/json";
|
|
189
|
-
case ".png":
|
|
190
|
-
return "image/png";
|
|
191
|
-
case ".jpg":
|
|
192
|
-
case ".jpeg":
|
|
193
|
-
return "image/jpeg";
|
|
194
|
-
case ".gif":
|
|
195
|
-
return "image/gif";
|
|
196
|
-
case ".svg":
|
|
197
|
-
return "image/svg+xml";
|
|
198
|
-
case ".ico":
|
|
199
|
-
return "image/x-icon";
|
|
200
|
-
default:
|
|
201
|
-
return "application/octet-stream";
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
export default StaticFileServer;
|