viyv-browser-mcp 0.3.4 → 0.3.6
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 +149 -200
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// src/index.ts
|
|
4
|
-
import { existsSync as existsSync4, readdirSync } from "fs";
|
|
5
|
-
|
|
6
3
|
// src/native-host/bridge.ts
|
|
7
|
-
import { existsSync } from "fs";
|
|
8
4
|
import { createConnection } from "net";
|
|
9
5
|
|
|
10
6
|
// ../shared/dist/constants.js
|
|
@@ -64,6 +60,12 @@ var RECONNECT = {
|
|
|
64
60
|
/** Backoff multiplier */
|
|
65
61
|
MULTIPLIER: 2
|
|
66
62
|
};
|
|
63
|
+
var BRIDGE = {
|
|
64
|
+
/** TCP port for MCP Server ↔ Native Host bridge communication */
|
|
65
|
+
TCP_PORT: 9224,
|
|
66
|
+
/** Loopback address for bridge */
|
|
67
|
+
TCP_HOST: "127.0.0.1"
|
|
68
|
+
};
|
|
67
69
|
var MCP_SERVER = {
|
|
68
70
|
/** Server name for MCP protocol */
|
|
69
71
|
NAME: "viyv-browser",
|
|
@@ -149,7 +151,7 @@ function writeMessage(stream, message) {
|
|
|
149
151
|
// src/native-host/bridge.ts
|
|
150
152
|
var MAX_BUFFER_SIZE = 1e3;
|
|
151
153
|
function startBridge(options) {
|
|
152
|
-
const {
|
|
154
|
+
const { port = BRIDGE.TCP_PORT, host = BRIDGE.TCP_HOST, onError } = options;
|
|
153
155
|
let socket = null;
|
|
154
156
|
let reconnecting = false;
|
|
155
157
|
let retryCount = 0;
|
|
@@ -177,35 +179,31 @@ function startBridge(options) {
|
|
|
177
179
|
reconnecting = true;
|
|
178
180
|
const POLL_INTERVAL = 2e3;
|
|
179
181
|
function attemptReconnect() {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
retryCount++;
|
|
183
|
+
process.stderr.write(
|
|
184
|
+
`[viyv-browser:native-host] Reconnecting to ${host}:${port} (attempt ${retryCount})
|
|
183
185
|
`
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
} else {
|
|
188
|
-
retryCount++;
|
|
189
|
-
if (retryCount > 60) {
|
|
190
|
-
process.stderr.write(
|
|
191
|
-
"[viyv-browser:native-host] Socket not found after 120s, slowing down polling\n"
|
|
192
|
-
);
|
|
193
|
-
setTimeout(attemptReconnect, RECONNECT.MAX_DELAY);
|
|
194
|
-
} else {
|
|
195
|
-
setTimeout(attemptReconnect, POLL_INTERVAL);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
186
|
+
);
|
|
187
|
+
reconnecting = false;
|
|
188
|
+
connectSocket();
|
|
198
189
|
}
|
|
199
190
|
const delay = retryCount === 0 ? RECONNECT.INITIAL_DELAY : POLL_INTERVAL;
|
|
200
191
|
setTimeout(attemptReconnect, delay);
|
|
201
192
|
}
|
|
202
193
|
function connectSocket() {
|
|
203
|
-
socket = createConnection(
|
|
194
|
+
socket = createConnection({ port, host });
|
|
204
195
|
socket.on("connect", () => {
|
|
205
|
-
process.stderr.write(
|
|
206
|
-
`
|
|
196
|
+
process.stderr.write(
|
|
197
|
+
`[viyv-browser:native-host] Connected to MCP server at ${host}:${port}
|
|
198
|
+
`
|
|
199
|
+
);
|
|
207
200
|
retryCount = 0;
|
|
208
201
|
flushBuffer();
|
|
202
|
+
writeMessage(process.stdout, {
|
|
203
|
+
type: "bridge_status",
|
|
204
|
+
connected: true,
|
|
205
|
+
timestamp: Date.now()
|
|
206
|
+
});
|
|
209
207
|
});
|
|
210
208
|
let lineBuffer = "";
|
|
211
209
|
socket.on("data", (data) => {
|
|
@@ -234,6 +232,11 @@ function startBridge(options) {
|
|
|
234
232
|
socket.on("close", () => {
|
|
235
233
|
process.stderr.write("[viyv-browser:native-host] Socket closed\n");
|
|
236
234
|
socket = null;
|
|
235
|
+
writeMessage(process.stdout, {
|
|
236
|
+
type: "bridge_status",
|
|
237
|
+
connected: false,
|
|
238
|
+
timestamp: Date.now()
|
|
239
|
+
});
|
|
237
240
|
scheduleReconnect();
|
|
238
241
|
});
|
|
239
242
|
}
|
|
@@ -283,7 +286,7 @@ function startBridge(options) {
|
|
|
283
286
|
|
|
284
287
|
// src/server.ts
|
|
285
288
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
286
|
-
import {
|
|
289
|
+
import { existsSync, statSync } from "fs";
|
|
287
290
|
import http from "http";
|
|
288
291
|
import { createConnection as createConnection2, createServer } from "net";
|
|
289
292
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -2250,12 +2253,12 @@ function createConfiguredMcpServer() {
|
|
|
2250
2253
|
};
|
|
2251
2254
|
return server;
|
|
2252
2255
|
}
|
|
2253
|
-
async function startMcpServer(
|
|
2256
|
+
async function startMcpServer(agentName, options) {
|
|
2254
2257
|
if (agentName) {
|
|
2255
2258
|
setDefaultAgentId(agentName);
|
|
2256
2259
|
}
|
|
2257
|
-
await evictExistingBridge(
|
|
2258
|
-
const
|
|
2260
|
+
await evictExistingBridge();
|
|
2261
|
+
const bridgeServer = createBridgeServer();
|
|
2259
2262
|
if (options?.transport === "sse") {
|
|
2260
2263
|
const sessions2 = /* @__PURE__ */ new Map();
|
|
2261
2264
|
const httpServer = http.createServer();
|
|
@@ -2277,8 +2280,10 @@ async function startMcpServer(socketPath, agentName, options) {
|
|
|
2277
2280
|
process.stderr.write(`[viyv-browser:mcp] SSE server listening on 127.0.0.1:${port}
|
|
2278
2281
|
`);
|
|
2279
2282
|
});
|
|
2280
|
-
process.stderr.write(
|
|
2281
|
-
`)
|
|
2283
|
+
process.stderr.write(
|
|
2284
|
+
`[viyv-browser:mcp] MCP Server started (SSE), bridge: ${BRIDGE.TCP_HOST}:${BRIDGE.TCP_PORT}
|
|
2285
|
+
`
|
|
2286
|
+
);
|
|
2282
2287
|
let shuttingDown = false;
|
|
2283
2288
|
const shutdown = async () => {
|
|
2284
2289
|
if (shuttingDown) return;
|
|
@@ -2289,9 +2294,8 @@ async function startMcpServer(socketPath, agentName, options) {
|
|
|
2289
2294
|
}
|
|
2290
2295
|
httpServer.close(() => {
|
|
2291
2296
|
});
|
|
2292
|
-
|
|
2297
|
+
bridgeServer.close(() => {
|
|
2293
2298
|
});
|
|
2294
|
-
cleanupSocket(socketPath);
|
|
2295
2299
|
process.exit(0);
|
|
2296
2300
|
};
|
|
2297
2301
|
process.on("SIGINT", () => {
|
|
@@ -2300,9 +2304,6 @@ async function startMcpServer(socketPath, agentName, options) {
|
|
|
2300
2304
|
process.on("SIGTERM", () => {
|
|
2301
2305
|
shutdown();
|
|
2302
2306
|
});
|
|
2303
|
-
process.on("exit", () => {
|
|
2304
|
-
cleanupSocket(socketPath);
|
|
2305
|
-
});
|
|
2306
2307
|
} else if (options?.transport === "streamable-http") {
|
|
2307
2308
|
const sessions2 = /* @__PURE__ */ new Map();
|
|
2308
2309
|
const SESSION_TTL = 30 * 60 * 1e3;
|
|
@@ -2344,7 +2345,7 @@ async function startMcpServer(socketPath, agentName, options) {
|
|
|
2344
2345
|
);
|
|
2345
2346
|
});
|
|
2346
2347
|
process.stderr.write(
|
|
2347
|
-
`[viyv-browser:mcp] MCP Server started (streamable-http),
|
|
2348
|
+
`[viyv-browser:mcp] MCP Server started (streamable-http), bridge: ${BRIDGE.TCP_HOST}:${BRIDGE.TCP_PORT}
|
|
2348
2349
|
`
|
|
2349
2350
|
);
|
|
2350
2351
|
let shuttingDown = false;
|
|
@@ -2358,9 +2359,8 @@ async function startMcpServer(socketPath, agentName, options) {
|
|
|
2358
2359
|
}
|
|
2359
2360
|
httpServer.close(() => {
|
|
2360
2361
|
});
|
|
2361
|
-
|
|
2362
|
+
bridgeServer.close(() => {
|
|
2362
2363
|
});
|
|
2363
|
-
cleanupSocket(socketPath);
|
|
2364
2364
|
process.exit(0);
|
|
2365
2365
|
};
|
|
2366
2366
|
process.on("SIGINT", () => {
|
|
@@ -2369,20 +2369,18 @@ async function startMcpServer(socketPath, agentName, options) {
|
|
|
2369
2369
|
process.on("SIGTERM", () => {
|
|
2370
2370
|
shutdown();
|
|
2371
2371
|
});
|
|
2372
|
-
process.on("exit", () => {
|
|
2373
|
-
cleanupSocket(socketPath);
|
|
2374
|
-
});
|
|
2375
2372
|
} else {
|
|
2376
2373
|
const server = createConfiguredMcpServer();
|
|
2377
2374
|
const transport = new StdioServerTransport();
|
|
2378
2375
|
await server.connect(transport);
|
|
2379
|
-
process.stderr.write(
|
|
2380
|
-
`)
|
|
2376
|
+
process.stderr.write(
|
|
2377
|
+
`[viyv-browser:mcp] MCP Server started (stdio), bridge: ${BRIDGE.TCP_HOST}:${BRIDGE.TCP_PORT}
|
|
2378
|
+
`
|
|
2379
|
+
);
|
|
2381
2380
|
process.on("SIGINT", () => process.exit(0));
|
|
2382
2381
|
process.on("SIGTERM", () => process.exit(0));
|
|
2383
2382
|
process.on("exit", () => {
|
|
2384
|
-
|
|
2385
|
-
cleanupSocket(socketPath);
|
|
2383
|
+
bridgeServer.close();
|
|
2386
2384
|
});
|
|
2387
2385
|
}
|
|
2388
2386
|
}
|
|
@@ -2554,14 +2552,13 @@ function parseJsonBody(req) {
|
|
|
2554
2552
|
});
|
|
2555
2553
|
});
|
|
2556
2554
|
}
|
|
2557
|
-
function evictExistingBridge(
|
|
2558
|
-
if (!existsSync2(socketPath)) return Promise.resolve();
|
|
2555
|
+
function evictExistingBridge() {
|
|
2559
2556
|
return new Promise((resolve2) => {
|
|
2560
2557
|
const timeout = setTimeout(() => {
|
|
2561
2558
|
tempSocket.destroy();
|
|
2562
2559
|
resolve2();
|
|
2563
2560
|
}, 2e3);
|
|
2564
|
-
const tempSocket = createConnection2(
|
|
2561
|
+
const tempSocket = createConnection2({ port: BRIDGE.TCP_PORT, host: BRIDGE.TCP_HOST });
|
|
2565
2562
|
tempSocket.on("connect", () => {
|
|
2566
2563
|
process.stderr.write("[viyv-browser:mcp] Evicted bridge from previous MCP server\n");
|
|
2567
2564
|
setTimeout(() => {
|
|
@@ -2576,90 +2573,112 @@ function evictExistingBridge(socketPath) {
|
|
|
2576
2573
|
});
|
|
2577
2574
|
});
|
|
2578
2575
|
}
|
|
2579
|
-
function
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
}
|
|
2586
|
-
process.stderr.write("[viyv-browser:mcp] Extension connected via Unix socket\n");
|
|
2587
|
-
extensionSocket = socket;
|
|
2588
|
-
setExtensionConnected(true);
|
|
2589
|
-
const agentId = getDefaultAgentId();
|
|
2590
|
-
createSession(agentId);
|
|
2591
|
-
const initMsg = {
|
|
2592
|
-
id: randomUUID2(),
|
|
2593
|
-
type: "session_init",
|
|
2594
|
-
agentId,
|
|
2595
|
-
protocolVersion: PROTOCOL_VERSION,
|
|
2596
|
-
timestamp: Date.now()
|
|
2597
|
-
};
|
|
2598
|
-
socket.write(`${JSON.stringify(initMsg)}
|
|
2576
|
+
function handleBridgeConnection(socket, label) {
|
|
2577
|
+
if (extensionSocket && !extensionSocket.destroyed) {
|
|
2578
|
+
process.stderr.write("[viyv-browser:mcp] Replacing existing extension connection\n");
|
|
2579
|
+
extensionSocket.destroy();
|
|
2580
|
+
}
|
|
2581
|
+
process.stderr.write(`[viyv-browser:mcp] Extension connected via ${label}
|
|
2599
2582
|
`);
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
}
|
|
2613
|
-
handleExtensionMessage(parsed);
|
|
2614
|
-
} catch (error) {
|
|
2615
|
-
process.stderr.write(`[viyv-browser:mcp] Parse error: ${error.message}
|
|
2583
|
+
extensionSocket = socket;
|
|
2584
|
+
setExtensionConnected(true);
|
|
2585
|
+
const agentId = getDefaultAgentId();
|
|
2586
|
+
createSession(agentId);
|
|
2587
|
+
const initMsg = {
|
|
2588
|
+
id: randomUUID2(),
|
|
2589
|
+
type: "session_init",
|
|
2590
|
+
agentId,
|
|
2591
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
2592
|
+
timestamp: Date.now()
|
|
2593
|
+
};
|
|
2594
|
+
socket.write(`${JSON.stringify(initMsg)}
|
|
2616
2595
|
`);
|
|
2596
|
+
const heartbeatInterval = setInterval(() => {
|
|
2597
|
+
if (socket.destroyed) {
|
|
2598
|
+
clearInterval(heartbeatInterval);
|
|
2599
|
+
return;
|
|
2600
|
+
}
|
|
2601
|
+
socket.write(
|
|
2602
|
+
`${JSON.stringify({
|
|
2603
|
+
id: randomUUID2(),
|
|
2604
|
+
type: "session_heartbeat",
|
|
2605
|
+
agentId,
|
|
2606
|
+
timestamp: Date.now()
|
|
2607
|
+
})}
|
|
2608
|
+
`
|
|
2609
|
+
);
|
|
2610
|
+
}, TIMEOUTS.HEARTBEAT);
|
|
2611
|
+
let lineBuffer = "";
|
|
2612
|
+
socket.on("data", (data) => {
|
|
2613
|
+
lineBuffer += data.toString("utf-8");
|
|
2614
|
+
const lines = lineBuffer.split("\n");
|
|
2615
|
+
lineBuffer = lines.pop() ?? "";
|
|
2616
|
+
for (const line of lines) {
|
|
2617
|
+
if (!line) continue;
|
|
2618
|
+
try {
|
|
2619
|
+
let parsed = JSON.parse(line);
|
|
2620
|
+
if (parsed.type === "compressed" && typeof parsed.data === "string") {
|
|
2621
|
+
const decompressed = decompressPayload(parsed.data, true);
|
|
2622
|
+
parsed = JSON.parse(decompressed);
|
|
2617
2623
|
}
|
|
2624
|
+
handleExtensionMessage(parsed);
|
|
2625
|
+
} catch (error) {
|
|
2626
|
+
process.stderr.write(`[viyv-browser:mcp] Parse error: ${error.message}
|
|
2627
|
+
`);
|
|
2618
2628
|
}
|
|
2619
|
-
}
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2629
|
+
}
|
|
2630
|
+
});
|
|
2631
|
+
socket.on("close", () => {
|
|
2632
|
+
clearInterval(heartbeatInterval);
|
|
2633
|
+
process.stderr.write("[viyv-browser:mcp] Extension disconnected\n");
|
|
2634
|
+
if (extensionSocket === socket) {
|
|
2635
|
+
extensionSocket = null;
|
|
2636
|
+
setExtensionConnected(false);
|
|
2637
|
+
}
|
|
2638
|
+
for (const [id, pending] of pendingRequests) {
|
|
2639
|
+
clearTimeout(pending.timer);
|
|
2640
|
+
pendingRequests.delete(id);
|
|
2641
|
+
pending.resolve({
|
|
2642
|
+
error: {
|
|
2643
|
+
code: "EXTENSION_NOT_CONNECTED",
|
|
2644
|
+
message: "Extension disconnected while request was pending"
|
|
2645
|
+
}
|
|
2646
|
+
});
|
|
2647
|
+
}
|
|
2648
|
+
});
|
|
2649
|
+
socket.on("error", (error) => {
|
|
2650
|
+
process.stderr.write(`[viyv-browser:mcp] Socket error: ${error.message}
|
|
2639
2651
|
`);
|
|
2640
|
-
});
|
|
2641
2652
|
});
|
|
2653
|
+
}
|
|
2654
|
+
function createBridgeServer() {
|
|
2655
|
+
const server = createServer((socket) => handleBridgeConnection(socket, "TCP"));
|
|
2642
2656
|
server.on("error", (error) => {
|
|
2643
2657
|
if (error.code === "EADDRINUSE") {
|
|
2644
2658
|
process.stderr.write(
|
|
2645
|
-
`[viyv-browser:mcp]
|
|
2659
|
+
`[viyv-browser:mcp] TCP port ${BRIDGE.TCP_PORT} already in use, retrying...
|
|
2646
2660
|
`
|
|
2647
2661
|
);
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
`
|
|
2653
|
-
|
|
2662
|
+
setTimeout(() => {
|
|
2663
|
+
server.listen(BRIDGE.TCP_PORT, BRIDGE.TCP_HOST, () => {
|
|
2664
|
+
process.stderr.write(
|
|
2665
|
+
`[viyv-browser:mcp] TCP bridge listening on ${BRIDGE.TCP_HOST}:${BRIDGE.TCP_PORT} (retry)
|
|
2666
|
+
`
|
|
2667
|
+
);
|
|
2668
|
+
});
|
|
2669
|
+
}, 1e3);
|
|
2654
2670
|
} else {
|
|
2655
|
-
process.stderr.write(
|
|
2656
|
-
`)
|
|
2671
|
+
process.stderr.write(
|
|
2672
|
+
`[viyv-browser:mcp] TCP bridge error: ${error.message} (${error.code})
|
|
2673
|
+
`
|
|
2674
|
+
);
|
|
2657
2675
|
}
|
|
2658
2676
|
});
|
|
2659
|
-
server.listen(
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
`
|
|
2677
|
+
server.listen(BRIDGE.TCP_PORT, BRIDGE.TCP_HOST, () => {
|
|
2678
|
+
process.stderr.write(
|
|
2679
|
+
`[viyv-browser:mcp] TCP bridge listening on ${BRIDGE.TCP_HOST}:${BRIDGE.TCP_PORT}
|
|
2680
|
+
`
|
|
2681
|
+
);
|
|
2663
2682
|
});
|
|
2664
2683
|
return server;
|
|
2665
2684
|
}
|
|
@@ -2742,7 +2761,7 @@ async function callExtensionTool(tool, input) {
|
|
|
2742
2761
|
if (paths) {
|
|
2743
2762
|
for (const p of paths) {
|
|
2744
2763
|
try {
|
|
2745
|
-
if (!
|
|
2764
|
+
if (!existsSync(p) || !statSync(p).isFile()) {
|
|
2746
2765
|
return {
|
|
2747
2766
|
content: [
|
|
2748
2767
|
{
|
|
@@ -2928,36 +2947,10 @@ async function handleSwitchBrowser() {
|
|
|
2928
2947
|
}, SWITCH_TIMEOUT);
|
|
2929
2948
|
});
|
|
2930
2949
|
}
|
|
2931
|
-
function cleanupSocket(socketPath) {
|
|
2932
|
-
if (!existsSync2(socketPath)) return;
|
|
2933
|
-
try {
|
|
2934
|
-
unlinkSync(socketPath);
|
|
2935
|
-
} catch (error) {
|
|
2936
|
-
const err = error;
|
|
2937
|
-
if (err.code === "EPERM" || err.code === "EACCES") {
|
|
2938
|
-
process.stderr.write(
|
|
2939
|
-
`[viyv-browser:mcp] Cannot remove stale socket (${err.code}), retrying with chmod...
|
|
2940
|
-
`
|
|
2941
|
-
);
|
|
2942
|
-
try {
|
|
2943
|
-
chmodSync(socketPath, 438);
|
|
2944
|
-
unlinkSync(socketPath);
|
|
2945
|
-
} catch (retryError) {
|
|
2946
|
-
process.stderr.write(
|
|
2947
|
-
`[viyv-browser:mcp] Failed to remove socket after chmod: ${retryError.message}
|
|
2948
|
-
`
|
|
2949
|
-
);
|
|
2950
|
-
}
|
|
2951
|
-
} else if (err.code !== "ENOENT") {
|
|
2952
|
-
process.stderr.write(`[viyv-browser:mcp] Socket cleanup error: ${err.message}
|
|
2953
|
-
`);
|
|
2954
|
-
}
|
|
2955
|
-
}
|
|
2956
|
-
}
|
|
2957
2950
|
|
|
2958
2951
|
// src/setup.ts
|
|
2959
2952
|
import { execSync } from "child_process";
|
|
2960
|
-
import { chmodSync
|
|
2953
|
+
import { chmodSync, existsSync as existsSync2, mkdirSync, writeFileSync } from "fs";
|
|
2961
2954
|
import { homedir, platform } from "os";
|
|
2962
2955
|
import { dirname, resolve } from "path";
|
|
2963
2956
|
function runSetup(options = {}) {
|
|
@@ -2967,7 +2960,7 @@ function runSetup(options = {}) {
|
|
|
2967
2960
|
console.log("================================================");
|
|
2968
2961
|
console.log(`Platform: ${os}`);
|
|
2969
2962
|
console.log(`Binary: ${binaryPath}`);
|
|
2970
|
-
if (!
|
|
2963
|
+
if (!existsSync2(binaryPath)) {
|
|
2971
2964
|
console.error(`WARNING: Binary not found at ${binaryPath}`);
|
|
2972
2965
|
console.error("The Native Messaging Host may not work until the binary is available.");
|
|
2973
2966
|
}
|
|
@@ -2991,7 +2984,7 @@ function runSetup(options = {}) {
|
|
|
2991
2984
|
console.log(`Manifest path: ${manifestPath}`);
|
|
2992
2985
|
mkdirSync(manifestDir, { recursive: true });
|
|
2993
2986
|
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
2994
|
-
|
|
2987
|
+
chmodSync(manifestPath, 420);
|
|
2995
2988
|
console.log("\nNative Messaging Host registered successfully!");
|
|
2996
2989
|
console.log("\nNext steps:");
|
|
2997
2990
|
console.log("1. Start the MCP Server: node <path>/dist/index.js");
|
|
@@ -3023,7 +3016,7 @@ function createNativeHostWrapper(os, binaryPath) {
|
|
|
3023
3016
|
writeFileSync(wrapperPath, `#!/bin/bash
|
|
3024
3017
|
exec "${nodePath}" "${binaryPath}" --native-host
|
|
3025
3018
|
`);
|
|
3026
|
-
|
|
3019
|
+
chmodSync(wrapperPath, 493);
|
|
3027
3020
|
return wrapperPath;
|
|
3028
3021
|
}
|
|
3029
3022
|
function getNodePath() {
|
|
@@ -3062,44 +3055,14 @@ if (args.includes("setup")) {
|
|
|
3062
3055
|
const extensionId = extensionIdIdx >= 0 ? args[extensionIdIdx + 1] : void 0;
|
|
3063
3056
|
runSetup({ extensionId });
|
|
3064
3057
|
} else if (args.includes("--native-host")) {
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
if (socketPath) {
|
|
3070
|
-
process.stderr.write(`[viyv-browser:native-host] Found socket at ${socketPath}
|
|
3071
|
-
`);
|
|
3072
|
-
startBridge({
|
|
3073
|
-
socketPath,
|
|
3074
|
-
onError: (error) => {
|
|
3075
|
-
process.stderr.write(`[viyv-browser:native-host] Error: ${error.message}
|
|
3058
|
+
process.stderr.write("[viyv-browser:native-host] Starting bridge (TCP mode)\n");
|
|
3059
|
+
startBridge({
|
|
3060
|
+
onError: (error) => {
|
|
3061
|
+
process.stderr.write(`[viyv-browser:native-host] Error: ${error.message}
|
|
3076
3062
|
`);
|
|
3077
|
-
}
|
|
3078
|
-
});
|
|
3079
|
-
return;
|
|
3080
|
-
}
|
|
3081
|
-
if (Date.now() - start > MAX_WAIT) {
|
|
3082
|
-
process.stderr.write(
|
|
3083
|
-
`[viyv-browser:native-host] MCP server socket not found after ${MAX_WAIT / 1e3}s. Exiting.
|
|
3084
|
-
`
|
|
3085
|
-
);
|
|
3086
|
-
process.exit(1);
|
|
3087
|
-
}
|
|
3088
|
-
process.stderr.write(
|
|
3089
|
-
`[viyv-browser:native-host] Waiting for MCP server socket (${SOCKET_PATH})...
|
|
3090
|
-
`
|
|
3091
|
-
);
|
|
3092
|
-
setTimeout(poll, POLL_INTERVAL);
|
|
3093
3063
|
}
|
|
3094
|
-
|
|
3095
|
-
};
|
|
3096
|
-
waitForSocket2 = waitForSocket;
|
|
3097
|
-
const SOCKET_PATH = "/tmp/viyv-browser.sock";
|
|
3098
|
-
const POLL_INTERVAL = 2e3;
|
|
3099
|
-
const MAX_WAIT = 12e4;
|
|
3100
|
-
waitForSocket();
|
|
3064
|
+
});
|
|
3101
3065
|
} else {
|
|
3102
|
-
const socketPath = "/tmp/viyv-browser.sock";
|
|
3103
3066
|
const agentNameIdx = args.indexOf("--agent-name");
|
|
3104
3067
|
const agentName = agentNameIdx >= 0 ? args[agentNameIdx + 1] : void 0;
|
|
3105
3068
|
const transportIdx = args.indexOf("--transport");
|
|
@@ -3113,20 +3076,6 @@ if (args.includes("setup")) {
|
|
|
3113
3076
|
}
|
|
3114
3077
|
const portIdx = args.indexOf("--port");
|
|
3115
3078
|
const port = portIdx >= 0 ? Number(args[portIdx + 1]) : void 0;
|
|
3116
|
-
startMcpServer(
|
|
3117
|
-
}
|
|
3118
|
-
var waitForSocket2;
|
|
3119
|
-
function findSocketPath() {
|
|
3120
|
-
const envSocket = process.env.VIYV_BROWSER_SOCKET;
|
|
3121
|
-
if (envSocket) return envSocket;
|
|
3122
|
-
const fixedPath = "/tmp/viyv-browser.sock";
|
|
3123
|
-
if (existsSync4(fixedPath)) return fixedPath;
|
|
3124
|
-
try {
|
|
3125
|
-
const tmpFiles = readdirSync("/tmp");
|
|
3126
|
-
const socketFile = tmpFiles.find((f) => f.startsWith("viyv-browser-") && f.endsWith(".sock"));
|
|
3127
|
-
if (socketFile) return `/tmp/${socketFile}`;
|
|
3128
|
-
} catch {
|
|
3129
|
-
}
|
|
3130
|
-
return null;
|
|
3079
|
+
startMcpServer(agentName, { transport: transportMode, port });
|
|
3131
3080
|
}
|
|
3132
3081
|
//# sourceMappingURL=index.js.map
|