@quanta-intellect/vessel-browser 0.1.26 → 0.1.27
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/README.md +32 -7
- package/out/main/index.js +44 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
<a href="https://snapcraft.io/vessel-browser">
|
|
6
|
+
<img alt="Get it from the Snap Store" src=https://snapcraft.io/en/dark/install.svg />
|
|
7
|
+
</a>
|
|
8
|
+
<a href="https://www.producthunt.com/products/quanta-intellect?embed=true&utm_source=badge-featured&utm_medium=badge&utm_campaign=badge-vessel-browser-from-quanta-intellect" target="_blank" rel="noopener noreferrer"><img alt="Vessel Browser from Quanta Intellect - The browser where agents drive and humans supervise | Product Hunt" width="250" height="54" src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1107491&theme=dark&t=1774779141692"></a>
|
|
2
9
|
|
|
3
10
|
# Vessel: Your Agent's Browser
|
|
11
|
+
</div>
|
|
12
|
+
|
|
4
13
|
|
|
5
|
-
Open
|
|
14
|
+
Open source chromium-based browser for persistent web agents on Linux (Mac/Windows support to come).
|
|
6
15
|
|
|
7
16
|
Vessel gives external agent harnesses a real browser with durable state, MCP control, and a human-visible supervisory UI. It is built for long-running workflows where the agent drives and the human audits, intervenes, and redirects when needed.
|
|
8
17
|
|
|
@@ -12,13 +21,19 @@ Vessel gives external agent harnesses a real browser with durable state, MCP con
|
|
|
12
21
|
|
|
13
22
|
*Vessel is in active development and currently makes no security assurances. Use and deploy it with care.*
|
|
14
23
|
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
https://github.com/user-attachments/assets/0a72b48a-873a-4eb0-b8f2-23e34d8472c4
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
15
30
|
## Quick Start
|
|
16
31
|
|
|
17
32
|
Want the full agent toolkit from day one? [Start a 5-Day Free Trial of Vessel Premium](https://vesselpremium.quantaintellect.com/checkout).
|
|
18
33
|
|
|
19
34
|
### Fastest Install Today
|
|
20
35
|
|
|
21
|
-
|
|
36
|
+
Linux AppImage from GitHub Releases:
|
|
22
37
|
|
|
23
38
|
1. Download the latest `Vessel-<version>-x64.AppImage`
|
|
24
39
|
2. Mark it executable: `chmod +x Vessel-*.AppImage`
|
|
@@ -57,11 +72,13 @@ If you want extra local AI tracing in development, create an optional `src/main/
|
|
|
57
72
|
|
|
58
73
|
Most browser automation stacks are either headless, stateless, or designed around a human as the primary operator. Vessel is built around the opposite model: the browser is the agent's operating surface, and the human stays in the loop through a visible interface with clear supervisory controls.
|
|
59
74
|
|
|
75
|
+
<img width="1280" height="800" alt="@quanta-intellectvessel-browser_2026-03-17_200224_6613" src="https://github.com/user-attachments/assets/8e208ee1-cb89-4318-87a2-9561a7d9aecf" />
|
|
60
76
|
<img width="1280" height="800" alt="vessel_2026-03-16_144201_7545" src="https://github.com/user-attachments/assets/da7b28ea-6c5f-4aa7-909e-0a255c80d508" />
|
|
77
|
+
<img width="1280" height="800" alt="@quanta-intellectvessel-browser_2026-03-17_195754_6624" src="https://github.com/user-attachments/assets/3b3d2033-5a59-4806-bbc1-359efb7b43a9" />
|
|
61
78
|
|
|
62
79
|
|
|
63
|
-
<img width="1280" height="785" alt="vessel_2026-03-16_171108_8677" src="https://github.com/user-attachments/assets/613c285f-0253-4344-b335-f74a64e124ac" />
|
|
64
80
|
|
|
81
|
+
<img width="1280" height="800" alt="vessel_2026-03-17_145154_5389" src="https://github.com/user-attachments/assets/b1c08d6c-bcdf-4c9a-8429-a71a23a61903" />
|
|
65
82
|
|
|
66
83
|
Vessel is built for persistent web agents that need a real browser, durable state, and a human-visible interface. The agent is the primary operator. The human follows along in the live browser UI, audits what the agent is doing, and steers when needed.
|
|
67
84
|
|
|
@@ -306,7 +323,10 @@ Generic HTTP MCP config:
|
|
|
306
323
|
"mcpServers": {
|
|
307
324
|
"vessel": {
|
|
308
325
|
"type": "http",
|
|
309
|
-
"url": "http://127.0.0.1:3100/mcp"
|
|
326
|
+
"url": "http://127.0.0.1:3100/mcp",
|
|
327
|
+
"headers": {
|
|
328
|
+
"Authorization": "Bearer <token from ~/.config/vessel/mcp-auth.json>"
|
|
329
|
+
}
|
|
310
330
|
}
|
|
311
331
|
}
|
|
312
332
|
}
|
|
@@ -318,6 +338,8 @@ Hermes Agent `config.yaml` MCP config:
|
|
|
318
338
|
mcp_servers:
|
|
319
339
|
vessel:
|
|
320
340
|
url: "http://127.0.0.1:3100/mcp"
|
|
341
|
+
headers:
|
|
342
|
+
Authorization: "Bearer <token from ~/.config/vessel/mcp-auth.json>"
|
|
321
343
|
timeout: 180
|
|
322
344
|
connect_timeout: 30
|
|
323
345
|
```
|
|
@@ -338,14 +360,17 @@ vessel-browser-mcp
|
|
|
338
360
|
Helper examples:
|
|
339
361
|
|
|
340
362
|
```bash
|
|
341
|
-
# Generic JSON snippet
|
|
363
|
+
# Generic JSON snippet with Authorization header
|
|
342
364
|
vessel-browser-mcp
|
|
343
365
|
|
|
344
|
-
# Hermes-ready YAML snippet
|
|
366
|
+
# Hermes-ready YAML snippet with Authorization header
|
|
345
367
|
vessel-browser-mcp --format hermes
|
|
346
368
|
|
|
347
369
|
# Raw MCP endpoint URL
|
|
348
370
|
vessel-browser-mcp --format url
|
|
371
|
+
|
|
372
|
+
# Raw MCP bearer token
|
|
373
|
+
vessel-browser-mcp --format token
|
|
349
374
|
```
|
|
350
375
|
|
|
351
376
|
Source install update helpers:
|
package/out/main/index.js
CHANGED
|
@@ -13755,6 +13755,23 @@ function getMcpAuthFilePath() {
|
|
|
13755
13755
|
);
|
|
13756
13756
|
return path$1.join(configDir, MCP_AUTH_FILENAME);
|
|
13757
13757
|
}
|
|
13758
|
+
function readMcpAuthFile() {
|
|
13759
|
+
try {
|
|
13760
|
+
const raw = fs$1.readFileSync(getMcpAuthFilePath(), "utf8");
|
|
13761
|
+
const parsed = JSON.parse(raw);
|
|
13762
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
13763
|
+
} catch {
|
|
13764
|
+
return null;
|
|
13765
|
+
}
|
|
13766
|
+
}
|
|
13767
|
+
const MIN_TOKEN_LENGTH = 32;
|
|
13768
|
+
function getPersistentMcpAuthToken() {
|
|
13769
|
+
const existingToken = readMcpAuthFile()?.token?.trim();
|
|
13770
|
+
if (existingToken && existingToken.length >= MIN_TOKEN_LENGTH) {
|
|
13771
|
+
return existingToken;
|
|
13772
|
+
}
|
|
13773
|
+
return crypto$2.randomBytes(32).toString("hex");
|
|
13774
|
+
}
|
|
13758
13775
|
function writeMcpAuthFile(endpoint, token) {
|
|
13759
13776
|
try {
|
|
13760
13777
|
const filePath = getMcpAuthFilePath();
|
|
@@ -13769,9 +13786,28 @@ function writeMcpAuthFile(endpoint, token) {
|
|
|
13769
13786
|
}
|
|
13770
13787
|
}
|
|
13771
13788
|
function clearMcpAuthFile() {
|
|
13789
|
+
const existingToken = readMcpAuthFile()?.token?.trim();
|
|
13790
|
+
if (!existingToken) {
|
|
13791
|
+
try {
|
|
13792
|
+
fs$1.unlinkSync(getMcpAuthFilePath());
|
|
13793
|
+
} catch {
|
|
13794
|
+
}
|
|
13795
|
+
return;
|
|
13796
|
+
}
|
|
13772
13797
|
try {
|
|
13773
|
-
|
|
13774
|
-
|
|
13798
|
+
const filePath = getMcpAuthFilePath();
|
|
13799
|
+
fs$1.mkdirSync(path$1.dirname(filePath), { recursive: true });
|
|
13800
|
+
fs$1.writeFileSync(
|
|
13801
|
+
filePath,
|
|
13802
|
+
JSON.stringify(
|
|
13803
|
+
{ endpoint: "", token: existingToken, pid: null },
|
|
13804
|
+
null,
|
|
13805
|
+
2
|
|
13806
|
+
) + "\n",
|
|
13807
|
+
{ mode: 384 }
|
|
13808
|
+
);
|
|
13809
|
+
} catch (err) {
|
|
13810
|
+
console.warn("[Vessel MCP] Failed to clear auth file:", err);
|
|
13775
13811
|
}
|
|
13776
13812
|
}
|
|
13777
13813
|
function asTextResponse(text) {
|
|
@@ -18310,7 +18346,7 @@ function startMcpServer(tabManager, runtime2, port) {
|
|
|
18310
18346
|
status: "starting",
|
|
18311
18347
|
message: `Starting MCP server on port ${port}.`
|
|
18312
18348
|
});
|
|
18313
|
-
mcpAuthToken =
|
|
18349
|
+
mcpAuthToken = getPersistentMcpAuthToken();
|
|
18314
18350
|
return new Promise((resolve) => {
|
|
18315
18351
|
const server = http.createServer(async (req, res) => {
|
|
18316
18352
|
const url = new URL(req.url || "/", `http://localhost:${port}`);
|
|
@@ -18337,7 +18373,11 @@ function startMcpServer(tabManager, runtime2, port) {
|
|
|
18337
18373
|
return;
|
|
18338
18374
|
}
|
|
18339
18375
|
const authHeader = req.headers.authorization;
|
|
18340
|
-
|
|
18376
|
+
const expected = `Bearer ${mcpAuthToken}`;
|
|
18377
|
+
const headerBuf = Buffer.from(authHeader ?? "");
|
|
18378
|
+
const expectedBuf = Buffer.from(expected);
|
|
18379
|
+
const tokenValid = headerBuf.length === expectedBuf.length && crypto$2.timingSafeEqual(headerBuf, expectedBuf);
|
|
18380
|
+
if (!authHeader || !tokenValid) {
|
|
18341
18381
|
res.writeHead(401, { "Content-Type": "application/json" });
|
|
18342
18382
|
res.end(JSON.stringify({ error: "Unauthorized — missing or invalid bearer token" }));
|
|
18343
18383
|
return;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quanta-intellect/vessel-browser",
|
|
3
3
|
"mcpName": "io.github.unmodeled-tyler/vessel-browser",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.27",
|
|
5
5
|
"description": "AI-native web browser for Linux — persistent browser runtime for autonomous agents with human supervision",
|
|
6
6
|
"main": "./out/main/index.js",
|
|
7
7
|
"bin": {
|