@vitalsend/mcp 0.1.0 → 0.2.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/README.md CHANGED
@@ -67,11 +67,13 @@ Ask your agent: "Send `.env` to kalle@example.com with VitalSend."
67
67
  The first time, your browser opens on vitalsend.eu: sign in (or create an account) and allow the
68
68
  connection. After that:
69
69
 
70
- 1. You confirm each send: file, recipient and cost.
71
- 2. A page on your computer shows the password. Send it to the recipient another way than the link,
72
- by text message for example.
73
- 3. VitalSend emails the link to the recipient. Without a recipient, the link appears on the same
74
- page for you to share.
70
+ 1. Your app asks you to confirm each send: file, recipient, cost and the password. Copy the
71
+ password and send it to the recipient yourself, by text message for example, not by email.
72
+ 2. VitalSend emails the link to the recipient. Without a recipient, your app shows you the link to
73
+ share.
74
+
75
+ These dialogs go to you, not to the model. An app that cannot show them opens a page on your
76
+ computer for the same steps.
75
77
 
76
78
  The agent is told who it went to and when it expires. Nothing else.
77
79
 
@@ -90,7 +92,9 @@ the folder it was started in, unless that is your home folder or `/`, where it r
90
92
  - When VitalSend emails the link, its server handles the link key for that delivery. With a
91
93
  password, that key alone does not open the file. To keep VitalSend out entirely, leave out the
92
94
  recipient and share the link yourself.
93
- - The page that shows the password lives on `127.0.0.1` at a random address, answers only the
95
+ - The dialogs that show the password and the link are your app's own; their text and your answer go
96
+ between the app and this tool, never into the conversation the model reads.
97
+ - The page that shows the password, for apps without such dialogs, lives on `127.0.0.1` at a random address, answers only the
94
98
  browser tab that loaded it, and closes afterwards. A program running as you that loads it first
95
99
  stops the send. Beyond that, anything running as you can read what you can read.
96
100
  - Your login is a send-only grant: it can send files and spend credits, nothing else. Revoke it
@@ -1039,11 +1039,19 @@ const base = location.pathname;
1039
1039
  const $ = (id) => document.getElementById(id);
1040
1040
  const post = (action) => fetch(base + '/action', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action }) });
1041
1041
  const labels = { sms: 'SMS', whatsapp: 'WhatsApp', telegram: 'Telegram', email: 'Email' };
1042
+ // Rebuilt only when what it shows changes: a button replaced by the next poll
1043
+ // loses a click that is under way.
1042
1044
  function shares(el, item, s) {
1045
+ const key = JSON.stringify([s[item], s.dimmed[item]]);
1046
+ if (el.dataset.key === key) return;
1047
+ el.dataset.key = key;
1043
1048
  el.textContent = '';
1044
1049
  const copy = document.createElement('button');
1045
1050
  copy.textContent = 'Copy';
1046
- copy.onclick = () => navigator.clipboard?.writeText(item === 'password' ? s.password.value : s.link.value);
1051
+ copy.onclick = () => navigator.clipboard?.writeText(item === 'password' ? s.password.value : s.link.value).then(() => {
1052
+ copy.textContent = '\u2713 Done';
1053
+ setTimeout(() => { copy.textContent = 'Copy'; }, 2000);
1054
+ }, () => {});
1047
1055
  el.append(copy);
1048
1056
  if (navigator.share) {
1049
1057
  const b = document.createElement('button');
@@ -1071,8 +1079,8 @@ async function tick() {
1071
1079
  $('c-credits').textContent = String(s.confirm.credits);
1072
1080
  }
1073
1081
  // A secret is only in the page while its view is on screen.
1074
- if (s.view !== 'password') $('p-value').textContent = '';
1075
- if (s.view !== 'link') $('l-value').textContent = '';
1082
+ if (s.view !== 'password') { $('p-value').textContent = ''; $('p-share').textContent = ''; delete $('p-share').dataset.key; }
1083
+ if (s.view !== 'link') { $('l-value').textContent = ''; $('l-share').textContent = ''; delete $('l-share').dataset.key; }
1076
1084
  if (s.view === 'password') { $('p-value').textContent = s.password.value; shares($('p-share'), 'password', s); }
1077
1085
  if (s.view === 'link') {
1078
1086
  $('l-value').textContent = s.link.value;
@@ -1285,23 +1293,26 @@ async function sendFile(input, deps) {
1285
1293
  } catch (err) {
1286
1294
  if (!(err instanceof LoginRequired)) throw err;
1287
1295
  const login2 = await startLogin2({ connectionName: clientName });
1288
- await io.openLogin(login2.url);
1296
+ await io.openLogin(login2.url, login2);
1289
1297
  accessToken = await credentials2.adopt(await login2.done);
1290
1298
  }
1291
1299
  const session = newSession(accessToken);
1292
1300
  await session.init();
1293
1301
  const { creditsNeeded } = await session.quote({ sizeBytes, password: withPassword, recipient });
1302
+ const password = withPassword ? generatePassword() : null;
1303
+ const inDialogs = mode !== "api_key" && !!io.canShowSecrets;
1294
1304
  if (mode !== "api_key") {
1295
- const details = { recipient, name, sizeBytes, credits: creditsNeeded };
1305
+ const details = { recipient, name, sizeBytes, size: formatSize2(sizeBytes), credits: creditsNeeded, password: inDialogs ? password : null };
1296
1306
  let decision = await io.confirm(details);
1297
1307
  if (decision === "unavailable") decision = await (await getPage()).confirm(details);
1298
1308
  if (decision !== "send") return fail("The send was cancelled.");
1299
1309
  }
1300
- if (mode !== "api_key") await (await getPage()).open();
1301
- const password = withPassword ? generatePassword() : null;
1302
- if (password) {
1303
- const shown = await (await getPage()).showPassword(password);
1304
- if (shown !== "saved") return fail("The password was not confirmed in the browser, so nothing was sent and no credits were used.");
1310
+ if (mode !== "api_key" && !inDialogs) {
1311
+ await (await getPage()).open();
1312
+ if (password) {
1313
+ const shown = await (await getPage()).showPassword(password);
1314
+ if (shown !== "saved") return fail("The password was not confirmed in the browser, so nothing was sent and no credits were used.");
1315
+ }
1305
1316
  }
1306
1317
  const linkKey = new Uint8Array(randomBytes4(32));
1307
1318
  const reserved = await session.reserve({
@@ -1324,7 +1335,9 @@ async function sendFile(input, deps) {
1324
1335
  }
1325
1336
  }
1326
1337
  }
1327
- if (mode !== "api_key") {
1338
+ let linkShown = emailed || mode === "api_key";
1339
+ if (!linkShown && inDialogs) linkShown = await io.showLink(link, { password: !!password }).catch(() => "cancel") === "accept";
1340
+ if (mode !== "api_key" && (!inDialogs || !linkShown)) {
1328
1341
  const p = await getPage();
1329
1342
  pageHandedOff = true;
1330
1343
  p.showLink({ link, emailedTo: emailed ? recipient : "" }).catch(() => {
@@ -1335,11 +1348,11 @@ async function sendFile(input, deps) {
1335
1348
  lines.push(`VitalSend emailed the download link to ${recipient}.`);
1336
1349
  } else {
1337
1350
  if (recipient) lines.push(`VitalSend could not email the link to ${recipient}.`);
1338
- lines.push("The download link is waiting in the user's browser to be shared; it was not given to you.");
1351
+ lines.push(linkShown ? "The download link was shown to the user to share; it was not given to you." : "The download link is waiting in the user's browser to be shared; it was not given to you.");
1339
1352
  }
1340
1353
  const expiry = formatExpiry(reserved.expiresAt);
1341
1354
  if (expiry) lines.push(`It can be downloaded once, until ${expiry}.`);
1342
- if (password) lines.push("A password was set and shown to the user in the browser. The recipient needs it; the user should send it another way than the link.");
1355
+ if (password) lines.push("A password was set and shown to the user" + (inDialogs ? "" : " in the browser") + ". The recipient needs it; the user should send it another way than the link.");
1343
1356
  lines.push(`Cost: ${creditsNeeded} credit${creditsNeeded === 1 ? "" : "s"}.`);
1344
1357
  return { isError: false, text: lines.join(" ") };
1345
1358
  } catch (err) {
@@ -1367,6 +1380,7 @@ function createIo({ server: server2, ctx, openBrowser: openBrowser2 }) {
1367
1380
  const elicitation = caps.elicitation;
1368
1381
  const canForm = !!elicitation && (Object.keys(elicitation).length === 0 || !!elicitation.form);
1369
1382
  const canUrl = !!elicitation?.url;
1383
+ const canShowSecrets = canForm && !era2026;
1370
1384
  const ask = (key, request) => {
1371
1385
  throw new NeedInput(inputRequired({ inputRequests: { [key]: request } }));
1372
1386
  };
@@ -1377,18 +1391,38 @@ function createIo({ server: server2, ctx, openBrowser: openBrowser2 }) {
1377
1391
  if (answers.roots?.roots) return answers.roots.roots.map((r) => r.uri);
1378
1392
  return ask("roots", inputRequired.listRoots());
1379
1393
  },
1380
- async openLogin(url) {
1394
+ // login: { done, cancel } from startLogin. On 2025-era connections the
1395
+ // client may hold its dialog open until told the login is complete, so the
1396
+ // dialog is not awaited: completing the login closes it, declining it
1397
+ // cancels the login.
1398
+ async openLogin(url, login2) {
1381
1399
  if (!canUrl) return openBrowser2(url);
1382
1400
  if (!era2026) {
1383
- await ctx.mcpReq.elicitInput({ mode: "url", url, message: LOGIN_MESSAGE, elicitationId: `login-${Date.now()}` });
1401
+ const elicitationId = `login-${Date.now()}`;
1402
+ ctx.mcpReq.elicitInput({ mode: "url", url, message: LOGIN_MESSAGE, elicitationId }).then((res) => {
1403
+ if (res?.action !== "accept") login2?.cancel();
1404
+ }, () => login2?.cancel());
1405
+ login2?.done.then(() => server2.server.createElicitationCompletionNotifier(elicitationId)(), () => {
1406
+ }).catch(() => {
1407
+ });
1384
1408
  return void 0;
1385
1409
  }
1386
1410
  if (answers.login) return void 0;
1387
1411
  return ask("login", inputRequired.elicitUrl({ url, message: LOGIN_MESSAGE }));
1388
1412
  },
1389
- async confirm({ recipient, name, sizeBytes, credits }) {
1413
+ canShowSecrets,
1414
+ async confirm({ recipient, name, sizeBytes, size, credits, password }) {
1390
1415
  if (!canForm) return "unavailable";
1391
- const message = `Send ${name} (${sizeBytes} bytes) ${recipient ? `to ${recipient}` : "and share the link yourself"}? It costs ${credits} credit${credits === 1 ? "" : "s"}.`;
1416
+ const cost = `${credits} credit${credits === 1 ? "" : "s"}`;
1417
+ let message = `Send ${name} (${size || `${sizeBytes} bytes`}) ${recipient ? `to ${recipient}` : "and share the link yourself"} for ${cost}?`;
1418
+ if (password && canShowSecrets) {
1419
+ const to = recipient || "the recipient";
1420
+ message += `
1421
+
1422
+ Password: ${password}
1423
+
1424
+ Copy the password now and send it to ${to} yourself, by text message for example. ` + (recipient ? "Not by email: the link arrives by email, and the two must travel separately." : "Not together with the link.") + " The password is shown only here.";
1425
+ }
1392
1426
  const request = { mode: "form", message, requestedSchema: { type: "object", properties: {} } };
1393
1427
  if (!era2026) {
1394
1428
  const res = await ctx.mcpReq.elicitInput(request);
@@ -1396,13 +1430,24 @@ function createIo({ server: server2, ctx, openBrowser: openBrowser2 }) {
1396
1430
  }
1397
1431
  if (answers.confirm) return answers.confirm.action === "accept" ? "send" : "cancel";
1398
1432
  return ask("confirm", inputRequired.elicit({ message, requestedSchema: request.requestedSchema }));
1433
+ },
1434
+ async showLink(link, { password = false } = {}) {
1435
+ if (!canShowSecrets) return "unavailable";
1436
+ const res = await ctx.mcpReq.elicitInput({
1437
+ mode: "form",
1438
+ requestedSchema: { type: "object", properties: {} },
1439
+ message: `Uploaded. Copy the link and send it to the recipient; it can be downloaded once:
1440
+
1441
+ ${link}` + (password ? "\n\nSend the password another way than the link." : "")
1442
+ });
1443
+ return res?.action || "cancel";
1399
1444
  }
1400
1445
  };
1401
1446
  }
1402
1447
 
1403
1448
  // src/server.js
1404
- var VERSION = "0.1.0";
1405
- var DESCRIPTION = `Send a file end-to-end encrypted through VitalSend. The file is encrypted on this computer; the recipient can download it once. With recipient_email, VitalSend emails the download link; without it, the link appears in the user's browser for the user to share. You never see the link, its key or the password. By default a password is set and shown to the user in the browser. Each send is confirmed by the user first.`;
1449
+ var VERSION = "0.2.0";
1450
+ var DESCRIPTION = `Send a file end-to-end encrypted through VitalSend. The file is encrypted on this computer; the recipient can download it once. With recipient_email, VitalSend emails the download link; without it, the link is shown to the user to share. You never see the link, its key or the password. By default a password is set and shown to the user, who sends it to the recipient another way. Each send is confirmed by the user first.`;
1406
1451
  function buildServer({ sendFileDeps, openBrowser: openBrowser2 }) {
1407
1452
  const server2 = new McpServer({ name: "vitalsend", version: VERSION });
1408
1453
  server2.registerTool("send_file", {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@vitalsend/mcp",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@vitalsend/mcp",
9
- "version": "0.1.0",
9
+ "version": "0.2.0",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "@modelcontextprotocol/server": "2.4.0",
@@ -18,12 +18,142 @@
18
18
  },
19
19
  "devDependencies": {
20
20
  "esbuild": "^0.28.0",
21
+ "jsdom": "26.1.0",
21
22
  "vitest": "^4.1.8"
22
23
  },
23
24
  "engines": {
24
25
  "node": ">=20"
25
26
  }
26
27
  },
28
+ "node_modules/@asamuzakjp/css-color": {
29
+ "version": "3.2.0",
30
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
31
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
32
+ "dev": true,
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "@csstools/css-calc": "^2.1.3",
36
+ "@csstools/css-color-parser": "^3.0.9",
37
+ "@csstools/css-parser-algorithms": "^3.0.4",
38
+ "@csstools/css-tokenizer": "^3.0.3",
39
+ "lru-cache": "^10.4.3"
40
+ }
41
+ },
42
+ "node_modules/@csstools/color-helpers": {
43
+ "version": "5.1.0",
44
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
45
+ "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
46
+ "dev": true,
47
+ "funding": [
48
+ {
49
+ "type": "github",
50
+ "url": "https://github.com/sponsors/csstools"
51
+ },
52
+ {
53
+ "type": "opencollective",
54
+ "url": "https://opencollective.com/csstools"
55
+ }
56
+ ],
57
+ "license": "MIT-0",
58
+ "engines": {
59
+ "node": ">=18"
60
+ }
61
+ },
62
+ "node_modules/@csstools/css-calc": {
63
+ "version": "2.1.4",
64
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
65
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
66
+ "dev": true,
67
+ "funding": [
68
+ {
69
+ "type": "github",
70
+ "url": "https://github.com/sponsors/csstools"
71
+ },
72
+ {
73
+ "type": "opencollective",
74
+ "url": "https://opencollective.com/csstools"
75
+ }
76
+ ],
77
+ "license": "MIT",
78
+ "engines": {
79
+ "node": ">=18"
80
+ },
81
+ "peerDependencies": {
82
+ "@csstools/css-parser-algorithms": "^3.0.5",
83
+ "@csstools/css-tokenizer": "^3.0.4"
84
+ }
85
+ },
86
+ "node_modules/@csstools/css-color-parser": {
87
+ "version": "3.1.0",
88
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
89
+ "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
90
+ "dev": true,
91
+ "funding": [
92
+ {
93
+ "type": "github",
94
+ "url": "https://github.com/sponsors/csstools"
95
+ },
96
+ {
97
+ "type": "opencollective",
98
+ "url": "https://opencollective.com/csstools"
99
+ }
100
+ ],
101
+ "license": "MIT",
102
+ "dependencies": {
103
+ "@csstools/color-helpers": "^5.1.0",
104
+ "@csstools/css-calc": "^2.1.4"
105
+ },
106
+ "engines": {
107
+ "node": ">=18"
108
+ },
109
+ "peerDependencies": {
110
+ "@csstools/css-parser-algorithms": "^3.0.5",
111
+ "@csstools/css-tokenizer": "^3.0.4"
112
+ }
113
+ },
114
+ "node_modules/@csstools/css-parser-algorithms": {
115
+ "version": "3.0.5",
116
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
117
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
118
+ "dev": true,
119
+ "funding": [
120
+ {
121
+ "type": "github",
122
+ "url": "https://github.com/sponsors/csstools"
123
+ },
124
+ {
125
+ "type": "opencollective",
126
+ "url": "https://opencollective.com/csstools"
127
+ }
128
+ ],
129
+ "license": "MIT",
130
+ "engines": {
131
+ "node": ">=18"
132
+ },
133
+ "peerDependencies": {
134
+ "@csstools/css-tokenizer": "^3.0.4"
135
+ }
136
+ },
137
+ "node_modules/@csstools/css-tokenizer": {
138
+ "version": "3.0.4",
139
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
140
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
141
+ "dev": true,
142
+ "funding": [
143
+ {
144
+ "type": "github",
145
+ "url": "https://github.com/sponsors/csstools"
146
+ },
147
+ {
148
+ "type": "opencollective",
149
+ "url": "https://opencollective.com/csstools"
150
+ }
151
+ ],
152
+ "license": "MIT",
153
+ "engines": {
154
+ "node": ">=18"
155
+ }
156
+ },
27
157
  "node_modules/@esbuild/aix-ppc64": {
28
158
  "version": "0.28.2",
29
159
  "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
@@ -933,6 +1063,16 @@
933
1063
  "url": "https://opencollective.com/vitest"
934
1064
  }
935
1065
  },
1066
+ "node_modules/agent-base": {
1067
+ "version": "7.1.4",
1068
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
1069
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
1070
+ "dev": true,
1071
+ "license": "MIT",
1072
+ "engines": {
1073
+ "node": ">= 14"
1074
+ }
1075
+ },
936
1076
  "node_modules/assertion-error": {
937
1077
  "version": "2.0.1",
938
1078
  "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
@@ -960,6 +1100,59 @@
960
1100
  "dev": true,
961
1101
  "license": "MIT"
962
1102
  },
1103
+ "node_modules/cssstyle": {
1104
+ "version": "4.6.0",
1105
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
1106
+ "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
1107
+ "dev": true,
1108
+ "license": "MIT",
1109
+ "dependencies": {
1110
+ "@asamuzakjp/css-color": "^3.2.0",
1111
+ "rrweb-cssom": "^0.8.0"
1112
+ },
1113
+ "engines": {
1114
+ "node": ">=18"
1115
+ }
1116
+ },
1117
+ "node_modules/data-urls": {
1118
+ "version": "5.0.0",
1119
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
1120
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
1121
+ "dev": true,
1122
+ "license": "MIT",
1123
+ "dependencies": {
1124
+ "whatwg-mimetype": "^4.0.0",
1125
+ "whatwg-url": "^14.0.0"
1126
+ },
1127
+ "engines": {
1128
+ "node": ">=18"
1129
+ }
1130
+ },
1131
+ "node_modules/debug": {
1132
+ "version": "4.4.3",
1133
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
1134
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
1135
+ "dev": true,
1136
+ "license": "MIT",
1137
+ "dependencies": {
1138
+ "ms": "^2.1.3"
1139
+ },
1140
+ "engines": {
1141
+ "node": ">=6.0"
1142
+ },
1143
+ "peerDependenciesMeta": {
1144
+ "supports-color": {
1145
+ "optional": true
1146
+ }
1147
+ }
1148
+ },
1149
+ "node_modules/decimal.js": {
1150
+ "version": "10.6.0",
1151
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
1152
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
1153
+ "dev": true,
1154
+ "license": "MIT"
1155
+ },
963
1156
  "node_modules/detect-libc": {
964
1157
  "version": "2.1.2",
965
1158
  "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -970,6 +1163,19 @@
970
1163
  "node": ">=8"
971
1164
  }
972
1165
  },
1166
+ "node_modules/entities": {
1167
+ "version": "6.0.1",
1168
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
1169
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
1170
+ "dev": true,
1171
+ "license": "BSD-2-Clause",
1172
+ "engines": {
1173
+ "node": ">=0.12"
1174
+ },
1175
+ "funding": {
1176
+ "url": "https://github.com/fb55/entities?sponsor=1"
1177
+ }
1178
+ },
973
1179
  "node_modules/es-module-lexer": {
974
1180
  "version": "2.3.2",
975
1181
  "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz",
@@ -1072,6 +1278,107 @@
1072
1278
  "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1073
1279
  }
1074
1280
  },
1281
+ "node_modules/html-encoding-sniffer": {
1282
+ "version": "4.0.0",
1283
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
1284
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
1285
+ "dev": true,
1286
+ "license": "MIT",
1287
+ "dependencies": {
1288
+ "whatwg-encoding": "^3.1.1"
1289
+ },
1290
+ "engines": {
1291
+ "node": ">=18"
1292
+ }
1293
+ },
1294
+ "node_modules/http-proxy-agent": {
1295
+ "version": "7.0.2",
1296
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
1297
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
1298
+ "dev": true,
1299
+ "license": "MIT",
1300
+ "dependencies": {
1301
+ "agent-base": "^7.1.0",
1302
+ "debug": "^4.3.4"
1303
+ },
1304
+ "engines": {
1305
+ "node": ">= 14"
1306
+ }
1307
+ },
1308
+ "node_modules/https-proxy-agent": {
1309
+ "version": "7.0.6",
1310
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
1311
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
1312
+ "dev": true,
1313
+ "license": "MIT",
1314
+ "dependencies": {
1315
+ "agent-base": "^7.1.2",
1316
+ "debug": "4"
1317
+ },
1318
+ "engines": {
1319
+ "node": ">= 14"
1320
+ }
1321
+ },
1322
+ "node_modules/iconv-lite": {
1323
+ "version": "0.6.3",
1324
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
1325
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
1326
+ "dev": true,
1327
+ "license": "MIT",
1328
+ "dependencies": {
1329
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
1330
+ },
1331
+ "engines": {
1332
+ "node": ">=0.10.0"
1333
+ }
1334
+ },
1335
+ "node_modules/is-potential-custom-element-name": {
1336
+ "version": "1.0.1",
1337
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
1338
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
1339
+ "dev": true,
1340
+ "license": "MIT"
1341
+ },
1342
+ "node_modules/jsdom": {
1343
+ "version": "26.1.0",
1344
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
1345
+ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
1346
+ "dev": true,
1347
+ "license": "MIT",
1348
+ "dependencies": {
1349
+ "cssstyle": "^4.2.1",
1350
+ "data-urls": "^5.0.0",
1351
+ "decimal.js": "^10.5.0",
1352
+ "html-encoding-sniffer": "^4.0.0",
1353
+ "http-proxy-agent": "^7.0.2",
1354
+ "https-proxy-agent": "^7.0.6",
1355
+ "is-potential-custom-element-name": "^1.0.1",
1356
+ "nwsapi": "^2.2.16",
1357
+ "parse5": "^7.2.1",
1358
+ "rrweb-cssom": "^0.8.0",
1359
+ "saxes": "^6.0.0",
1360
+ "symbol-tree": "^3.2.4",
1361
+ "tough-cookie": "^5.1.1",
1362
+ "w3c-xmlserializer": "^5.0.0",
1363
+ "webidl-conversions": "^7.0.0",
1364
+ "whatwg-encoding": "^3.1.1",
1365
+ "whatwg-mimetype": "^4.0.0",
1366
+ "whatwg-url": "^14.1.1",
1367
+ "ws": "^8.18.0",
1368
+ "xml-name-validator": "^5.0.0"
1369
+ },
1370
+ "engines": {
1371
+ "node": ">=18"
1372
+ },
1373
+ "peerDependencies": {
1374
+ "canvas": "^3.0.0"
1375
+ },
1376
+ "peerDependenciesMeta": {
1377
+ "canvas": {
1378
+ "optional": true
1379
+ }
1380
+ }
1381
+ },
1075
1382
  "node_modules/libsodium-sumo": {
1076
1383
  "version": "0.7.16",
1077
1384
  "resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.7.16.tgz",
@@ -1360,6 +1667,13 @@
1360
1667
  "url": "https://opencollective.com/parcel"
1361
1668
  }
1362
1669
  },
1670
+ "node_modules/lru-cache": {
1671
+ "version": "10.4.3",
1672
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
1673
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
1674
+ "dev": true,
1675
+ "license": "ISC"
1676
+ },
1363
1677
  "node_modules/magic-string": {
1364
1678
  "version": "0.30.21",
1365
1679
  "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -1370,6 +1684,13 @@
1370
1684
  "@jridgewell/sourcemap-codec": "^1.5.5"
1371
1685
  }
1372
1686
  },
1687
+ "node_modules/ms": {
1688
+ "version": "2.1.3",
1689
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1690
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1691
+ "dev": true,
1692
+ "license": "MIT"
1693
+ },
1373
1694
  "node_modules/nanoid": {
1374
1695
  "version": "3.3.20",
1375
1696
  "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz",
@@ -1389,6 +1710,13 @@
1389
1710
  "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1390
1711
  }
1391
1712
  },
1713
+ "node_modules/nwsapi": {
1714
+ "version": "2.2.28",
1715
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.28.tgz",
1716
+ "integrity": "sha512-IlVB7OS7qrOsVYlpnFIkETjMwT9jwvmocJmmM+GZU/PAB3uGi9Ezd7vcWhWBUnSc0ya4ppmQITOyP1ez9gg8cg==",
1717
+ "dev": true,
1718
+ "license": "MIT"
1719
+ },
1392
1720
  "node_modules/obug": {
1393
1721
  "version": "2.2.1",
1394
1722
  "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz",
@@ -1403,6 +1731,19 @@
1403
1731
  "node": ">=12.20.0"
1404
1732
  }
1405
1733
  },
1734
+ "node_modules/parse5": {
1735
+ "version": "7.3.0",
1736
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
1737
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
1738
+ "dev": true,
1739
+ "license": "MIT",
1740
+ "dependencies": {
1741
+ "entities": "^6.0.0"
1742
+ },
1743
+ "funding": {
1744
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
1745
+ }
1746
+ },
1406
1747
  "node_modules/pathe": {
1407
1748
  "version": "2.0.3",
1408
1749
  "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
@@ -1459,6 +1800,16 @@
1459
1800
  "node": "^10 || ^12 || >=14"
1460
1801
  }
1461
1802
  },
1803
+ "node_modules/punycode": {
1804
+ "version": "2.3.1",
1805
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
1806
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
1807
+ "dev": true,
1808
+ "license": "MIT",
1809
+ "engines": {
1810
+ "node": ">=6"
1811
+ }
1812
+ },
1462
1813
  "node_modules/rolldown": {
1463
1814
  "version": "1.2.16",
1464
1815
  "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.16.tgz",
@@ -1493,6 +1844,33 @@
1493
1844
  "@rolldown/binding-win32-x64-msvc": "1.2.16"
1494
1845
  }
1495
1846
  },
1847
+ "node_modules/rrweb-cssom": {
1848
+ "version": "0.8.0",
1849
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
1850
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
1851
+ "dev": true,
1852
+ "license": "MIT"
1853
+ },
1854
+ "node_modules/safer-buffer": {
1855
+ "version": "2.1.2",
1856
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1857
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1858
+ "dev": true,
1859
+ "license": "MIT"
1860
+ },
1861
+ "node_modules/saxes": {
1862
+ "version": "6.0.0",
1863
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
1864
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
1865
+ "dev": true,
1866
+ "license": "ISC",
1867
+ "dependencies": {
1868
+ "xmlchars": "^2.2.0"
1869
+ },
1870
+ "engines": {
1871
+ "node": ">=v12.22.7"
1872
+ }
1873
+ },
1496
1874
  "node_modules/siginfo": {
1497
1875
  "version": "2.0.0",
1498
1876
  "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
@@ -1524,6 +1902,13 @@
1524
1902
  "dev": true,
1525
1903
  "license": "MIT"
1526
1904
  },
1905
+ "node_modules/symbol-tree": {
1906
+ "version": "3.2.4",
1907
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
1908
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
1909
+ "dev": true,
1910
+ "license": "MIT"
1911
+ },
1527
1912
  "node_modules/tinybench": {
1528
1913
  "version": "2.9.0",
1529
1914
  "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
@@ -1568,6 +1953,52 @@
1568
1953
  "node": ">=14.0.0"
1569
1954
  }
1570
1955
  },
1956
+ "node_modules/tldts": {
1957
+ "version": "6.1.86",
1958
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
1959
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
1960
+ "dev": true,
1961
+ "license": "MIT",
1962
+ "dependencies": {
1963
+ "tldts-core": "^6.1.86"
1964
+ },
1965
+ "bin": {
1966
+ "tldts": "bin/cli.js"
1967
+ }
1968
+ },
1969
+ "node_modules/tldts-core": {
1970
+ "version": "6.1.86",
1971
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
1972
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
1973
+ "dev": true,
1974
+ "license": "MIT"
1975
+ },
1976
+ "node_modules/tough-cookie": {
1977
+ "version": "5.1.2",
1978
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
1979
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
1980
+ "dev": true,
1981
+ "license": "BSD-3-Clause",
1982
+ "dependencies": {
1983
+ "tldts": "^6.1.32"
1984
+ },
1985
+ "engines": {
1986
+ "node": ">=16"
1987
+ }
1988
+ },
1989
+ "node_modules/tr46": {
1990
+ "version": "5.1.1",
1991
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
1992
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
1993
+ "dev": true,
1994
+ "license": "MIT",
1995
+ "dependencies": {
1996
+ "punycode": "^2.3.1"
1997
+ },
1998
+ "engines": {
1999
+ "node": ">=18"
2000
+ }
2001
+ },
1571
2002
  "node_modules/vite": {
1572
2003
  "version": "8.3.5",
1573
2004
  "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz",
@@ -1736,6 +2167,67 @@
1736
2167
  }
1737
2168
  }
1738
2169
  },
2170
+ "node_modules/w3c-xmlserializer": {
2171
+ "version": "5.0.0",
2172
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
2173
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
2174
+ "dev": true,
2175
+ "license": "MIT",
2176
+ "dependencies": {
2177
+ "xml-name-validator": "^5.0.0"
2178
+ },
2179
+ "engines": {
2180
+ "node": ">=18"
2181
+ }
2182
+ },
2183
+ "node_modules/webidl-conversions": {
2184
+ "version": "7.0.0",
2185
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
2186
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
2187
+ "dev": true,
2188
+ "license": "BSD-2-Clause",
2189
+ "engines": {
2190
+ "node": ">=12"
2191
+ }
2192
+ },
2193
+ "node_modules/whatwg-encoding": {
2194
+ "version": "3.1.1",
2195
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
2196
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
2197
+ "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
2198
+ "dev": true,
2199
+ "license": "MIT",
2200
+ "dependencies": {
2201
+ "iconv-lite": "0.6.3"
2202
+ },
2203
+ "engines": {
2204
+ "node": ">=18"
2205
+ }
2206
+ },
2207
+ "node_modules/whatwg-mimetype": {
2208
+ "version": "4.0.0",
2209
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
2210
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
2211
+ "dev": true,
2212
+ "license": "MIT",
2213
+ "engines": {
2214
+ "node": ">=18"
2215
+ }
2216
+ },
2217
+ "node_modules/whatwg-url": {
2218
+ "version": "14.2.0",
2219
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
2220
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
2221
+ "dev": true,
2222
+ "license": "MIT",
2223
+ "dependencies": {
2224
+ "tr46": "^5.1.0",
2225
+ "webidl-conversions": "^7.0.0"
2226
+ },
2227
+ "engines": {
2228
+ "node": ">=18"
2229
+ }
2230
+ },
1739
2231
  "node_modules/why-is-node-running": {
1740
2232
  "version": "2.3.0",
1741
2233
  "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
@@ -1753,6 +2245,45 @@
1753
2245
  "node": ">=8"
1754
2246
  }
1755
2247
  },
2248
+ "node_modules/ws": {
2249
+ "version": "8.22.1",
2250
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.1.tgz",
2251
+ "integrity": "sha512-oyL6OPYme/CmiFvNuGzeoxCJ4nOrZE2O1FwM9MWM1AsGri6nLXB2pg+lNA8aLeXMSav0J6eIVS1j6vUPzUtK9g==",
2252
+ "dev": true,
2253
+ "license": "MIT",
2254
+ "engines": {
2255
+ "node": ">=10.0.0"
2256
+ },
2257
+ "peerDependencies": {
2258
+ "bufferutil": "^4.0.1",
2259
+ "utf-8-validate": ">=5.0.2"
2260
+ },
2261
+ "peerDependenciesMeta": {
2262
+ "bufferutil": {
2263
+ "optional": true
2264
+ },
2265
+ "utf-8-validate": {
2266
+ "optional": true
2267
+ }
2268
+ }
2269
+ },
2270
+ "node_modules/xml-name-validator": {
2271
+ "version": "5.0.0",
2272
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
2273
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
2274
+ "dev": true,
2275
+ "license": "Apache-2.0",
2276
+ "engines": {
2277
+ "node": ">=18"
2278
+ }
2279
+ },
2280
+ "node_modules/xmlchars": {
2281
+ "version": "2.2.0",
2282
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
2283
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
2284
+ "dev": true,
2285
+ "license": "MIT"
2286
+ },
1756
2287
  "node_modules/zod": {
1757
2288
  "version": "4.6.7",
1758
2289
  "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitalsend/mcp",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Send files end-to-end encrypted through VitalSend from an AI agent. The link key, the password and your login never reach the model.",
5
5
  "mcpName": "io.github.vitalsend/mcp",
6
6
  "homepage": "https://vitalsend.eu/mcp/",
@@ -47,6 +47,7 @@
47
47
  },
48
48
  "devDependencies": {
49
49
  "esbuild": "^0.28.0",
50
+ "jsdom": "26.1.0",
50
51
  "vitest": "^4.1.8"
51
52
  }
52
53
  }
package/server.json CHANGED
@@ -8,12 +8,12 @@
8
8
  "id": "1441821471"
9
9
  },
10
10
  "websiteUrl": "https://vitalsend.eu/mcp/",
11
- "version": "0.1.0",
11
+ "version": "0.2.0",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "@vitalsend/mcp",
16
- "version": "0.1.0",
16
+ "version": "0.2.0",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },