@rndmjoker/proton-mcp 0.4.13 → 0.5.1

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.
Files changed (95) hide show
  1. package/README.md +138 -21
  2. package/dist/browser/channel.d.ts +76 -0
  3. package/dist/browser/channel.js +162 -0
  4. package/dist/browser/channel.js.map +1 -0
  5. package/dist/browser/client.d.ts +50 -0
  6. package/dist/browser/client.js +284 -0
  7. package/dist/browser/client.js.map +1 -0
  8. package/dist/browser/connector.d.ts +15 -0
  9. package/dist/browser/connector.js +26 -0
  10. package/dist/browser/connector.js.map +1 -0
  11. package/dist/browser/host.d.ts +50 -0
  12. package/dist/browser/host.js +258 -0
  13. package/dist/browser/host.js.map +1 -0
  14. package/dist/browser/messages.d.ts +163 -0
  15. package/dist/browser/messages.js +338 -0
  16. package/dist/browser/messages.js.map +1 -0
  17. package/dist/browser/paths.d.ts +51 -0
  18. package/dist/browser/paths.js +92 -0
  19. package/dist/browser/paths.js.map +1 -0
  20. package/dist/browser/setup.d.ts +42 -0
  21. package/dist/browser/setup.js +170 -0
  22. package/dist/browser/setup.js.map +1 -0
  23. package/dist/filters/order.d.ts +66 -0
  24. package/dist/filters/order.js +108 -0
  25. package/dist/filters/order.js.map +1 -0
  26. package/dist/filters/sieve.d.ts +184 -0
  27. package/dist/filters/sieve.js +1312 -0
  28. package/dist/filters/sieve.js.map +1 -0
  29. package/dist/instances.d.ts +58 -0
  30. package/dist/instances.js +145 -0
  31. package/dist/instances.js.map +1 -0
  32. package/dist/mail/compose.d.ts +10 -0
  33. package/dist/mail/compose.js.map +1 -1
  34. package/dist/mail/record.d.ts +36 -0
  35. package/dist/mail/record.js +74 -0
  36. package/dist/mail/record.js.map +1 -0
  37. package/dist/permissions.d.ts +139 -0
  38. package/dist/permissions.js +355 -0
  39. package/dist/permissions.js.map +1 -0
  40. package/dist/server.js +330 -16
  41. package/dist/server.js.map +1 -1
  42. package/dist/session.d.ts +12 -0
  43. package/dist/session.js +23 -0
  44. package/dist/session.js.map +1 -1
  45. package/dist/settings.d.ts +81 -11
  46. package/dist/settings.js +160 -25
  47. package/dist/settings.js.map +1 -1
  48. package/dist/tools/confirm.d.ts +4 -2
  49. package/dist/tools/confirm.js +12 -3
  50. package/dist/tools/confirm.js.map +1 -1
  51. package/dist/tools/failures.d.ts +6 -8
  52. package/dist/tools/failures.js +36 -17
  53. package/dist/tools/failures.js.map +1 -1
  54. package/dist/tools/filter-tools.d.ts +82 -0
  55. package/dist/tools/filter-tools.js +729 -0
  56. package/dist/tools/filter-tools.js.map +1 -0
  57. package/dist/tools/filters.d.ts +8 -1
  58. package/dist/tools/filters.js +24 -12
  59. package/dist/tools/filters.js.map +1 -1
  60. package/dist/tools/format.d.ts +15 -0
  61. package/dist/tools/format.js +4 -3
  62. package/dist/tools/format.js.map +1 -1
  63. package/dist/tools/guidance.js +12 -7
  64. package/dist/tools/guidance.js.map +1 -1
  65. package/dist/tools/interface.d.ts +20 -6
  66. package/dist/tools/interface.js +40 -16
  67. package/dist/tools/interface.js.map +1 -1
  68. package/dist/tools/send.d.ts +9 -0
  69. package/dist/tools/send.js +51 -9
  70. package/dist/tools/send.js.map +1 -1
  71. package/dist/tools/sign-in-required.d.ts +15 -2
  72. package/dist/tools/sign-in-required.js +30 -2
  73. package/dist/tools/sign-in-required.js.map +1 -1
  74. package/dist/web/layout.d.ts +12 -5
  75. package/dist/web/layout.js +32 -9
  76. package/dist/web/layout.js.map +1 -1
  77. package/dist/web/pages.d.ts +4 -2
  78. package/dist/web/pages.js +10 -9
  79. package/dist/web/pages.js.map +1 -1
  80. package/dist/web/pending.d.ts +9 -6
  81. package/dist/web/pending.js +9 -7
  82. package/dist/web/pending.js.map +1 -1
  83. package/dist/web/preview-server.d.ts +33 -0
  84. package/dist/web/preview-server.js +102 -0
  85. package/dist/web/preview-server.js.map +1 -0
  86. package/dist/web/sections.d.ts +86 -1
  87. package/dist/web/sections.js +290 -7
  88. package/dist/web/sections.js.map +1 -1
  89. package/dist/web/security.d.ts +48 -13
  90. package/dist/web/security.js +68 -16
  91. package/dist/web/security.js.map +1 -1
  92. package/dist/web/server.d.ts +81 -24
  93. package/dist/web/server.js +478 -117
  94. package/dist/web/server.js.map +1 -1
  95. package/package.json +1 -1
@@ -0,0 +1,338 @@
1
+ /**
2
+ * What the server, the connector and the browser extension may say to each other
3
+ * (#59).
4
+ *
5
+ * Three programs pass messages along: this server asks, the connector Chrome
6
+ * starts relays, and the extension does the work in the signed-in Proton page.
7
+ * Each of them checks every message against the fixed list below and drops
8
+ * anything else, so a program that reaches one of the channels can ask for
9
+ * nothing beyond these seven things. Unknown fields are refused rather than
10
+ * ignored: a field nobody reads today is one somebody may read tomorrow.
11
+ *
12
+ * The limits here are about shape, not about what is allowed. Whether a script
13
+ * may be saved is decided by src/filters/sieve.ts, in this server and again in
14
+ * the extension.
15
+ *
16
+ * Nothing from Node in here: the extension imports this file as well.
17
+ */
18
+ /** The name Chrome knows the connector by. It has to match the host manifest. */
19
+ export const HOST_NAME = 'com.rndmjoker.proton_mcp';
20
+ /**
21
+ * The id of the extension, fixed by the public key in its manifest.
22
+ *
23
+ * Chrome starts the connector only for the extensions its manifest names, and
24
+ * the connector checks the origin Chrome hands it once more.
25
+ */
26
+ export const EXTENSION_ID = 'nfmconelbflppeoolebhcckbmffiokkd';
27
+ /** Raised whenever a message changes shape, so an old connector and a new server notice each other. */
28
+ export const PROTOCOL_VERSION = 1;
29
+ const ERROR_CODES = new Set([
30
+ 'no-proton-tab',
31
+ 'signed-out',
32
+ 'wrong-account',
33
+ 'refused',
34
+ 'proton-error',
35
+ 'app-version',
36
+ 'not-found',
37
+ 'busy',
38
+ 'timeout',
39
+ 'internal',
40
+ 'unknown-request',
41
+ ]);
42
+ const OUTCOMES = new Set([
43
+ 'added',
44
+ 'replaced',
45
+ 'applied',
46
+ 'reordered',
47
+ 'deleted',
48
+ 'enabled',
49
+ 'disabled',
50
+ 'rejected',
51
+ 'failed',
52
+ 'queued',
53
+ 'cancelled',
54
+ ]);
55
+ /** Generous bounds on shape. The real limits on names and scripts are in sieve.ts. */
56
+ export const LIMITS = {
57
+ account: 320,
58
+ name: 1_000,
59
+ /** Above the longest script sieve.ts takes, so a stored filter just over it can still be read. */
60
+ sieve: 60_000,
61
+ id: 256,
62
+ message: 4_000,
63
+ version: 64,
64
+ filters: 1_000,
65
+ moves: 50,
66
+ queue: 100,
67
+ recent: 50,
68
+ };
69
+ /** Proton's ids: base64 with - and _ and = padding. */
70
+ const FILTER_ID = /^[A-Za-z0-9_=-]+$/;
71
+ function isPlain(value) {
72
+ return typeof value === 'object' && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
73
+ }
74
+ /** True when the object has exactly these keys, the optional ones allowed to be missing. */
75
+ function hasOnly(value, required, optional = []) {
76
+ const keys = Object.keys(value);
77
+ return required.every((key) => keys.includes(key)) && keys.every((key) => required.includes(key) || optional.includes(key));
78
+ }
79
+ function isText(value, max, allowEmpty = false) {
80
+ return typeof value === 'string' && value.length <= max && (allowEmpty || value.length > 0);
81
+ }
82
+ function isFilterId(value) {
83
+ return isText(value, LIMITS.id) && FILTER_ID.test(value);
84
+ }
85
+ function isAccount(value) {
86
+ return isText(value, LIMITS.account) && value.includes('@') && !/[\s<>"]/.test(value);
87
+ }
88
+ function parseMoves(value) {
89
+ if (!Array.isArray(value) || value.length === 0 || value.length > LIMITS.moves)
90
+ return undefined;
91
+ const moves = [];
92
+ for (const move of value) {
93
+ if (!isPlain(move) || !hasOnly(move, ['id', 'position']))
94
+ return undefined;
95
+ if (!isFilterId(move.id) || !Number.isInteger(move.position) || move.position < 1 || move.position > 10_000) {
96
+ return undefined;
97
+ }
98
+ moves.push({ id: move.id, position: move.position });
99
+ }
100
+ return moves;
101
+ }
102
+ /** A request as one of the seven kinds, or nothing when it is anything else. */
103
+ export function parseRequest(value) {
104
+ if (!isPlain(value))
105
+ return undefined;
106
+ switch (value.kind) {
107
+ case 'status':
108
+ return hasOnly(value, ['kind']) ? { kind: 'status' } : undefined;
109
+ case 'list_filters':
110
+ return hasOnly(value, ['kind', 'account']) && isAccount(value.account)
111
+ ? { kind: 'list_filters', account: value.account }
112
+ : undefined;
113
+ case 'propose_filter': {
114
+ if (!hasOnly(value, ['kind', 'account', 'proposal', 'confirm', 'applyAllowed']))
115
+ return undefined;
116
+ if (!isAccount(value.account) || typeof value.confirm !== 'boolean' || typeof value.applyAllowed !== 'boolean')
117
+ return undefined;
118
+ const proposal = value.proposal;
119
+ if (!isPlain(proposal) || !hasOnly(proposal, ['name', 'sieve'], ['replaces', 'apply']))
120
+ return undefined;
121
+ if (!isText(proposal.name, LIMITS.name) || !isText(proposal.sieve, LIMITS.sieve))
122
+ return undefined;
123
+ if (proposal.replaces !== undefined && !isFilterId(proposal.replaces))
124
+ return undefined;
125
+ if (proposal.apply !== undefined && typeof proposal.apply !== 'boolean')
126
+ return undefined;
127
+ return {
128
+ kind: 'propose_filter',
129
+ account: value.account,
130
+ confirm: value.confirm,
131
+ applyAllowed: value.applyAllowed,
132
+ proposal: {
133
+ name: proposal.name,
134
+ sieve: proposal.sieve,
135
+ ...(proposal.replaces !== undefined ? { replaces: proposal.replaces } : {}),
136
+ ...(proposal.apply !== undefined ? { apply: proposal.apply } : {}),
137
+ },
138
+ };
139
+ }
140
+ case 'apply_filter':
141
+ if (!hasOnly(value, ['kind', 'account', 'filterId', 'confirm']))
142
+ return undefined;
143
+ if (!isAccount(value.account) || !isFilterId(value.filterId) || typeof value.confirm !== 'boolean')
144
+ return undefined;
145
+ return { kind: 'apply_filter', account: value.account, filterId: value.filterId, confirm: value.confirm };
146
+ case 'reorder_filters': {
147
+ if (!hasOnly(value, ['kind', 'account', 'moves', 'confirm']))
148
+ return undefined;
149
+ if (!isAccount(value.account) || typeof value.confirm !== 'boolean')
150
+ return undefined;
151
+ const moves = parseMoves(value.moves);
152
+ return moves ? { kind: 'reorder_filters', account: value.account, moves, confirm: value.confirm } : undefined;
153
+ }
154
+ case 'delete_filter':
155
+ if (!hasOnly(value, ['kind', 'account', 'filterId', 'confirm']))
156
+ return undefined;
157
+ if (!isAccount(value.account) || !isFilterId(value.filterId) || typeof value.confirm !== 'boolean')
158
+ return undefined;
159
+ return { kind: 'delete_filter', account: value.account, filterId: value.filterId, confirm: value.confirm };
160
+ case 'set_filter_status':
161
+ if (!hasOnly(value, ['kind', 'account', 'filterId', 'enabled', 'confirm']))
162
+ return undefined;
163
+ if (!isAccount(value.account) || !isFilterId(value.filterId))
164
+ return undefined;
165
+ if (typeof value.enabled !== 'boolean' || typeof value.confirm !== 'boolean')
166
+ return undefined;
167
+ return {
168
+ kind: 'set_filter_status',
169
+ account: value.account,
170
+ filterId: value.filterId,
171
+ enabled: value.enabled,
172
+ confirm: value.confirm,
173
+ };
174
+ default:
175
+ return undefined;
176
+ }
177
+ }
178
+ function parseFilter(value) {
179
+ if (!isPlain(value) || !hasOnly(value, ['id', 'name', 'enabled', 'order', 'version', 'sieve']))
180
+ return undefined;
181
+ if (!isFilterId(value.id) || !isText(value.name, LIMITS.name, true) || typeof value.enabled !== 'boolean')
182
+ return undefined;
183
+ if (!Number.isInteger(value.order) || !Number.isInteger(value.version))
184
+ return undefined;
185
+ if (!isText(value.sieve, LIMITS.sieve, true))
186
+ return undefined;
187
+ return {
188
+ id: value.id,
189
+ name: value.name,
190
+ enabled: value.enabled,
191
+ order: value.order,
192
+ version: value.version,
193
+ sieve: value.sieve,
194
+ };
195
+ }
196
+ /** An answer as one of the known shapes, or nothing when it is anything else. */
197
+ export function parseResponse(value) {
198
+ if (!isPlain(value))
199
+ return undefined;
200
+ if (value.ok === false) {
201
+ if (!hasOnly(value, ['ok', 'error', 'message']))
202
+ return undefined;
203
+ if (typeof value.error !== 'string' || !ERROR_CODES.has(value.error))
204
+ return undefined;
205
+ if (!isText(value.message, LIMITS.message, true))
206
+ return undefined;
207
+ return { ok: false, error: value.error, message: value.message };
208
+ }
209
+ if (value.ok !== true)
210
+ return undefined;
211
+ switch (value.kind) {
212
+ case 'status':
213
+ if (!hasOnly(value, ['ok', 'kind', 'extensionVersion', 'protonTabs']))
214
+ return undefined;
215
+ if (!isText(value.extensionVersion, LIMITS.version) || !Number.isInteger(value.protonTabs))
216
+ return undefined;
217
+ return { ok: true, kind: 'status', extensionVersion: value.extensionVersion, protonTabs: value.protonTabs };
218
+ case 'list_filters': {
219
+ if (!hasOnly(value, ['ok', 'kind', 'filters'], ['queue', 'recent']) || !Array.isArray(value.filters))
220
+ return undefined;
221
+ if (value.filters.length > LIMITS.filters)
222
+ return undefined;
223
+ const filters = [];
224
+ for (const entry of value.filters) {
225
+ const filter = parseFilter(entry);
226
+ if (!filter)
227
+ return undefined;
228
+ filters.push(filter);
229
+ }
230
+ const queue = value.queue === undefined ? [] : parseQueue(value.queue);
231
+ const recent = value.recent === undefined ? [] : parseRecent(value.recent);
232
+ if (!queue || !recent)
233
+ return undefined;
234
+ return {
235
+ ok: true,
236
+ kind: 'list_filters',
237
+ filters,
238
+ ...(value.queue !== undefined ? { queue } : {}),
239
+ ...(value.recent !== undefined ? { recent } : {}),
240
+ };
241
+ }
242
+ case 'propose_filter': {
243
+ if (!hasOnly(value, ['ok', 'kind', 'outcome'], ['filterId', 'apply']))
244
+ return undefined;
245
+ if (value.outcome !== 'shown' && value.outcome !== 'added' && value.outcome !== 'replaced' && value.outcome !== 'queued') {
246
+ return undefined;
247
+ }
248
+ if (value.filterId !== undefined && !isFilterId(value.filterId))
249
+ return undefined;
250
+ if (value.apply !== undefined && value.apply !== 'done' && value.apply !== 'queued' && value.apply !== 'failed' && value.apply !== 'shown') {
251
+ return undefined;
252
+ }
253
+ return {
254
+ ok: true,
255
+ kind: 'propose_filter',
256
+ outcome: value.outcome,
257
+ ...(value.filterId !== undefined ? { filterId: value.filterId } : {}),
258
+ ...(value.apply !== undefined ? { apply: value.apply } : {}),
259
+ };
260
+ }
261
+ case 'apply_filter':
262
+ if (!hasOnly(value, ['ok', 'kind', 'outcome']))
263
+ return undefined;
264
+ if (value.outcome !== 'shown' && value.outcome !== 'applied' && value.outcome !== 'queued')
265
+ return undefined;
266
+ return { ok: true, kind: 'apply_filter', outcome: value.outcome };
267
+ case 'reorder_filters':
268
+ if (!hasOnly(value, ['ok', 'kind', 'outcome']))
269
+ return undefined;
270
+ if (value.outcome !== 'shown' && value.outcome !== 'reordered' && value.outcome !== 'queued')
271
+ return undefined;
272
+ return { ok: true, kind: 'reorder_filters', outcome: value.outcome };
273
+ case 'delete_filter':
274
+ if (!hasOnly(value, ['ok', 'kind', 'outcome']))
275
+ return undefined;
276
+ if (value.outcome !== 'shown' && value.outcome !== 'deleted' && value.outcome !== 'queued')
277
+ return undefined;
278
+ return { ok: true, kind: 'delete_filter', outcome: value.outcome };
279
+ case 'set_filter_status':
280
+ if (!hasOnly(value, ['ok', 'kind', 'outcome']))
281
+ return undefined;
282
+ if (value.outcome !== 'shown' && value.outcome !== 'switched' && value.outcome !== 'queued')
283
+ return undefined;
284
+ return { ok: true, kind: 'set_filter_status', outcome: value.outcome };
285
+ default:
286
+ return undefined;
287
+ }
288
+ }
289
+ function parseQueue(value) {
290
+ if (!Array.isArray(value) || value.length > LIMITS.queue)
291
+ return undefined;
292
+ const queue = [];
293
+ for (const entry of value) {
294
+ if (!isPlain(entry) || !hasOnly(entry, ['action', 'name', 'since', 'attempts']))
295
+ return undefined;
296
+ if (!['save', 'apply', 'reorder', 'delete', 'status'].includes(entry.action))
297
+ return undefined;
298
+ if (!isText(entry.name, LIMITS.name, true) || !Number.isInteger(entry.since) || !Number.isInteger(entry.attempts))
299
+ return undefined;
300
+ queue.push({
301
+ action: entry.action,
302
+ name: entry.name,
303
+ since: entry.since,
304
+ attempts: entry.attempts,
305
+ });
306
+ }
307
+ return queue;
308
+ }
309
+ function parseRecent(value) {
310
+ if (!Array.isArray(value) || value.length > LIMITS.recent)
311
+ return undefined;
312
+ const recent = [];
313
+ for (const entry of value) {
314
+ if (!isPlain(entry) || !hasOnly(entry, ['at', 'name', 'outcome', 'how'], ['detail']))
315
+ return undefined;
316
+ if (!Number.isInteger(entry.at) || !isText(entry.name, LIMITS.name, true))
317
+ return undefined;
318
+ if (typeof entry.outcome !== 'string' || !OUTCOMES.has(entry.outcome))
319
+ return undefined;
320
+ if (entry.how !== 'confirmed' && entry.how !== 'without asking')
321
+ return undefined;
322
+ if (entry.detail !== undefined && !isText(entry.detail, LIMITS.message, true))
323
+ return undefined;
324
+ recent.push({
325
+ at: entry.at,
326
+ name: entry.name,
327
+ outcome: entry.outcome,
328
+ how: entry.how,
329
+ ...(entry.detail !== undefined ? { detail: entry.detail } : {}),
330
+ });
331
+ }
332
+ return recent;
333
+ }
334
+ /** True for the ids the server and the connector put on a request: short and plain. */
335
+ export function isRequestId(value) {
336
+ return typeof value === 'string' && /^[A-Za-z0-9-]{1,64}$/.test(value);
337
+ }
338
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/browser/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Where everything belonging to the browser channel lives (#59).
3
+ *
4
+ * Two processes have to agree on these paths without talking first: this
5
+ * server, started by an assistant with a reduced environment, and the connector,
6
+ * started by Chrome with the desktop's environment. So the paths depend on the
7
+ * home directory and the user, never on variables like XDG_RUNTIME_DIR or
8
+ * TMPDIR that one of the two may not have. The MCP SDK passes a server only
9
+ * HOME, LOGNAME, PATH, SHELL, TERM and USER, measured on 02.11.2026.
10
+ *
11
+ * This file is copied next to the connector by the setup, so it imports nothing
12
+ * but Node and the message list.
13
+ */
14
+ export type BrowserPlatform = 'linux' | 'darwin' | 'win32';
15
+ export interface BrowserPaths {
16
+ platform: BrowserPlatform;
17
+ /** ~/.config/proton-mcp, the same directory the settings live in. */
18
+ configDir: string;
19
+ /** Everything of the channel: the secret, the connector, the manifest on Windows. */
20
+ browserDir: string;
21
+ /** The secret both ends prove they know. Written by the setup, readable by the user only. */
22
+ secretFile: string;
23
+ /** The connector's own copy of its code, so it does not depend on an npx cache. */
24
+ hostDir: string;
25
+ hostScript: string;
26
+ /** What Chrome starts: a script that runs the connector with the Node the setup ran under. */
27
+ launcher: string;
28
+ /** The socket file, or on Windows the named pipe. */
29
+ socket: string;
30
+ /** Where Chrome looks for the manifest that names the connector. */
31
+ manifestFile: string;
32
+ /** On Windows, the registry key that points Chrome at the manifest. */
33
+ registryKey?: string;
34
+ }
35
+ /**
36
+ * Longest socket path used before falling back to a short one. Linux allows
37
+ * 107 bytes and macOS 103; longer paths fail with an error that names neither.
38
+ */
39
+ export declare const MAX_SOCKET_PATH = 100;
40
+ export interface PathOptions {
41
+ env?: NodeJS.ProcessEnv;
42
+ platform?: string;
43
+ home?: string;
44
+ uid?: number;
45
+ user?: string;
46
+ }
47
+ /** Turns an unsupported platform into a clear statement instead of a wrong path. */
48
+ export declare class UnsupportedPlatform extends Error {
49
+ }
50
+ export declare function browserPlatform(name?: string): BrowserPlatform;
51
+ export declare function browserPaths(options?: PathOptions): BrowserPaths;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Where everything belonging to the browser channel lives (#59).
3
+ *
4
+ * Two processes have to agree on these paths without talking first: this
5
+ * server, started by an assistant with a reduced environment, and the connector,
6
+ * started by Chrome with the desktop's environment. So the paths depend on the
7
+ * home directory and the user, never on variables like XDG_RUNTIME_DIR or
8
+ * TMPDIR that one of the two may not have. The MCP SDK passes a server only
9
+ * HOME, LOGNAME, PATH, SHELL, TERM and USER, measured on 02.11.2026.
10
+ *
11
+ * This file is copied next to the connector by the setup, so it imports nothing
12
+ * but Node and the message list.
13
+ */
14
+ import { homedir, platform as currentPlatform, userInfo } from 'node:os';
15
+ import { createHash } from 'node:crypto';
16
+ import { posix, win32 } from 'node:path';
17
+ import { HOST_NAME } from './messages.js';
18
+ /**
19
+ * Longest socket path used before falling back to a short one. Linux allows
20
+ * 107 bytes and macOS 103; longer paths fail with an error that names neither.
21
+ */
22
+ export const MAX_SOCKET_PATH = 100;
23
+ /** Turns an unsupported platform into a clear statement instead of a wrong path. */
24
+ export class UnsupportedPlatform extends Error {
25
+ }
26
+ export function browserPlatform(name = currentPlatform()) {
27
+ if (name === 'linux' || name === 'darwin' || name === 'win32')
28
+ return name;
29
+ throw new UnsupportedPlatform(`The browser extension's connector is available on Linux, macOS and Windows, not on ${name}.`);
30
+ }
31
+ export function browserPaths(options = {}) {
32
+ const env = options.env ?? process.env;
33
+ const platform = browserPlatform(options.platform);
34
+ const path = platform === 'win32' ? win32 : posix;
35
+ const home = options.home ?? homedir();
36
+ const configDir = path.join(home, '.config', 'proton-mcp');
37
+ const browserDir = path.join(configDir, 'browser');
38
+ const hostDir = path.join(browserDir, 'host');
39
+ const launcher = path.join(hostDir, platform === 'win32' ? 'proton-mcp-browser-host.cmd' : 'proton-mcp-browser-host');
40
+ let socket = env.PROTON_MCP_BROWSER_SOCKET?.trim();
41
+ if (!socket) {
42
+ if (platform === 'win32') {
43
+ // Pipe names are global on a machine, so the user is part of the name,
44
+ // with a short hash of it: two names that differ only in a letter a
45
+ // pipe name cannot hold, such as an umlaut, would get the same name
46
+ // otherwise. Node leaves the pipe's permissions at Windows' default,
47
+ // which gives the creator, SYSTEM and administrators full access and
48
+ // everyone else read access; a reader gets the greeting and nothing
49
+ // more, since the secret itself never crosses the pipe.
50
+ const raw = options.user ?? safeUserName();
51
+ const user = raw.replace(/[^A-Za-z0-9_.-]/g, '_');
52
+ const tag = createHash('sha256').update(raw).digest('hex').slice(0, 8);
53
+ socket = `\\\\.\\pipe\\proton-mcp-browser-${user}-${tag}`;
54
+ }
55
+ else {
56
+ socket = path.join(configDir, 'run', 'browser.sock');
57
+ if (Buffer.byteLength(socket) > MAX_SOCKET_PATH) {
58
+ // A fixed /tmp rather than os.tmpdir(): TMPDIR differs between the
59
+ // two processes on macOS. The directory is checked before use, since
60
+ // anyone can create a name in /tmp first.
61
+ socket = path.join('/tmp', `proton-mcp-${options.uid ?? process.getuid?.() ?? 0}`, 'browser.sock');
62
+ }
63
+ }
64
+ }
65
+ const manifestName = `${HOST_NAME}.json`;
66
+ const manifestFile = platform === 'linux'
67
+ ? path.join(home, '.config', 'google-chrome', 'NativeMessagingHosts', manifestName)
68
+ : platform === 'darwin'
69
+ ? path.join(home, 'Library', 'Application Support', 'Google', 'Chrome', 'NativeMessagingHosts', manifestName)
70
+ : path.join(browserDir, manifestName);
71
+ return {
72
+ platform,
73
+ configDir,
74
+ browserDir,
75
+ secretFile: path.join(browserDir, 'secret'),
76
+ hostDir,
77
+ hostScript: path.join(hostDir, 'connector.js'),
78
+ launcher,
79
+ socket,
80
+ manifestFile,
81
+ ...(platform === 'win32' ? { registryKey: `HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\${HOST_NAME}` } : {}),
82
+ };
83
+ }
84
+ function safeUserName() {
85
+ try {
86
+ return userInfo().username;
87
+ }
88
+ catch {
89
+ return process.env.USERNAME ?? process.env.USER ?? 'user';
90
+ }
91
+ }
92
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/browser/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAyBzC;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;AAUlC,oFAAoF;AACpF,MAAM,OAAO,mBAAoB,SAAQ,KAAK;CAAG;AAEjD,MAAM,UAAU,eAAe,CAAC,IAAI,GAAW,eAAe,EAAE;IAC9D,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAA;IAC1E,MAAM,IAAI,mBAAmB,CAC3B,sFAAsF,IAAI,GAAG,CAC9F,CAAA;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAO,GAAgB,EAAE;IACpD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACtC,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,CAAA;IACtC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,CAAA;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAA;IAErH,IAAI,MAAM,GAAG,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,CAAA;IAClD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,uEAAuE;YACvE,oEAAoE;YACpE,oEAAoE;YACpE,qEAAqE;YACrE,qEAAqE;YACrE,oEAAoE;YACpE,wDAAwD;YACxD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,IAAI,YAAY,EAAE,CAAA;YAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;YACjD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YACtE,MAAM,GAAG,mCAAmC,IAAI,IAAI,GAAG,EAAE,CAAA;QAC3D,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,cAAc,CAAC,CAAA;YACpD,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,eAAe,EAAE,CAAC;gBAChD,mEAAmE;gBACnE,qEAAqE;gBACrE,0CAA0C;gBAC1C,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,cAAc,CAAC,CAAA;YACpG,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,SAAS,OAAO,CAAA;IACxC,MAAM,YAAY,GAChB,QAAQ,KAAK,OAAO;QAClB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,sBAAsB,EAAE,YAAY,CAAC;QACnF,CAAC,CAAC,QAAQ,KAAK,QAAQ;YACrB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,EAAE,sBAAsB,EAAE,YAAY,CAAC;YAC7G,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IAE3C,OAAO;QACL,QAAQ;QACR,SAAS;QACT,UAAU;QACV,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;QAC3C,OAAO;QACP,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC;QAC9C,QAAQ;QACR,MAAM;QACN,YAAY;QACZ,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,yDAAyD,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvH,CAAA;AACH,CAAC;AAED,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,OAAO,QAAQ,EAAE,CAAC,QAAQ,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAA;IAC3D,CAAC;AACH,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Sets up the connector Chrome starts for the browser extension (#59):
3
+ *
4
+ * npx -y @rndmjoker/proton-mcp@latest setup-browser
5
+ * npx -y @rndmjoker/proton-mcp@latest setup-browser --remove
6
+ *
7
+ * What it writes, all of it for the current user only:
8
+ *
9
+ * - the secret both ends of the socket prove they know, readable by the user
10
+ * alone, kept when the setup runs again so a running connector keeps working;
11
+ * - a copy of the connector's five files under ~/.config/proton-mcp/browser/host,
12
+ * because an npx cache can be cleared or replaced at any time and Chrome
13
+ * needs a path that stays;
14
+ * - a launcher that starts that copy with the Node this setup runs under,
15
+ * since Chrome's environment may not find Node on its own;
16
+ * - the manifest that tells Chrome which program the extension may start,
17
+ * naming the extension's fixed id as the only one allowed;
18
+ * - on Windows, the registry entry that points Chrome at that manifest.
19
+ *
20
+ * Nothing here needs administrator rights, and nothing outside the user's own
21
+ * directories and, on Windows, the user's own part of the registry is touched.
22
+ */
23
+ import { type BrowserPaths } from './paths.js';
24
+ /** The files the connector needs, copied together because they import each other and nothing else. */
25
+ export declare const HOST_FILES: readonly ['connector.js', 'host.js', 'messages.js', 'paths.js', 'channel.js'];
26
+ export interface SetupOptions {
27
+ paths?: BrowserPaths;
28
+ /** The system to set up for when no paths are given. Only for tests. */
29
+ platform?: string;
30
+ /** The Node the launcher starts the connector with. */
31
+ node?: string;
32
+ /** Where the compiled connector files are. */
33
+ sourceDir?: string;
34
+ remove?: boolean;
35
+ write?: (text: string) => void;
36
+ /** Runs reg.exe on Windows. Replaced in tests. */
37
+ registry?: (args: string[]) => void;
38
+ }
39
+ /** Writes everything, or with remove takes it all away again. Returns the exit code. */
40
+ export declare function setupBrowser(options?: SetupOptions): number;
41
+ /** Reads the manifest back, for the diagnosis and the tests. */
42
+ export declare function readManifest(paths: BrowserPaths): Record<string, unknown> | undefined;