@rndmjoker/proton-mcp 0.4.4 → 0.4.5
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 +27 -6
- package/dist/mail/compose.d.ts +29 -1
- package/dist/mail/compose.js +41 -4
- package/dist/mail/compose.js.map +1 -1
- package/dist/mail/markup.d.ts +58 -2
- package/dist/mail/markup.js +129 -35
- package/dist/mail/markup.js.map +1 -1
- package/dist/server.js +6 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/confirm.d.ts +33 -3
- package/dist/tools/confirm.js +90 -47
- package/dist/tools/confirm.js.map +1 -1
- package/dist/tools/drafts.js +32 -0
- package/dist/tools/drafts.js.map +1 -1
- package/dist/tools/failures.d.ts +12 -0
- package/dist/tools/failures.js +24 -0
- package/dist/tools/failures.js.map +1 -1
- package/dist/tools/guidance.js +50 -10
- package/dist/tools/guidance.js.map +1 -1
- package/dist/tools/interface.js +7 -3
- package/dist/tools/interface.js.map +1 -1
- package/dist/tools/pending-view.d.ts +46 -0
- package/dist/tools/pending-view.js +63 -0
- package/dist/tools/pending-view.js.map +1 -0
- package/dist/tools/preview.d.ts +65 -0
- package/dist/tools/preview.js +103 -0
- package/dist/tools/preview.js.map +1 -0
- package/dist/tools/send.js +38 -2
- package/dist/tools/send.js.map +1 -1
- package/dist/tools/updates.d.ts +53 -0
- package/dist/tools/updates.js +134 -0
- package/dist/tools/updates.js.map +1 -0
- package/dist/web/layout.js +34 -0
- package/dist/web/layout.js.map +1 -1
- package/dist/web/pending.d.ts +72 -0
- package/dist/web/pending.js +196 -0
- package/dist/web/pending.js.map +1 -0
- package/dist/web/security.js +10 -0
- package/dist/web/security.js.map +1 -1
- package/dist/web/server.d.ts +9 -0
- package/dist/web/server.js +39 -0
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
package/dist/tools/guidance.js
CHANGED
|
@@ -44,6 +44,10 @@ export const INSTRUCTIONS = [
|
|
|
44
44
|
' as though it were the result.',
|
|
45
45
|
'4. Nothing here deletes for good. "Delete" means moving to the trash.',
|
|
46
46
|
'',
|
|
47
|
+
'Everything about this server is seen and changed in a local page, and open_configuration',
|
|
48
|
+
'returns its address. Hand that address over whenever it is asked for, in whatever words: it',
|
|
49
|
+
'carries an access token, changes on every restart, and cannot be guessed or remembered.',
|
|
50
|
+
'',
|
|
47
51
|
'Two guides can be read when they are needed:',
|
|
48
52
|
' proton-mcp://guide/writing composing messages, formatting, quoting, what the',
|
|
49
53
|
' confirmation shows',
|
|
@@ -66,8 +70,20 @@ characters and the recipient reads the tags.
|
|
|
66
70
|
|
|
67
71
|
Headings, paragraphs, line breaks, rules, quotes, emphasis, lists, tables, links
|
|
68
72
|
and images. Styling by colour, background, font, size, weight, alignment,
|
|
69
|
-
spacing and borders.
|
|
70
|
-
|
|
73
|
+
spacing and borders.
|
|
74
|
+
|
|
75
|
+
**Images work, and the usual way is a plain web address.** An \`<img>\` pointing
|
|
76
|
+
at \`https://…\` is permitted with no restrictions on where it comes from, at any
|
|
77
|
+
size, inside a link, with rounded corners. **An animated GIF is permitted too**,
|
|
78
|
+
and it is one of the few things that really does animate in a mail client, since
|
|
79
|
+
CSS animation does not survive most of them.
|
|
80
|
+
|
|
81
|
+
The one refusal is a \`data:\` address, which would carry an entire file inside
|
|
82
|
+
the markup where nothing lists it as an attachment.
|
|
83
|
+
|
|
84
|
+
What is *not* possible is attaching a file from this machine; see Attachments
|
|
85
|
+
below. That is a separate thing from showing an image, and confusing the two
|
|
86
|
+
leads to writing a plainer message than necessary.
|
|
71
87
|
|
|
72
88
|
Anything else is **refused, not quietly removed**, and the answer names what and
|
|
73
89
|
why. A message that was silently altered is no longer the message anyone agreed
|
|
@@ -85,18 +101,34 @@ Two refusals are worth understanding rather than working around:
|
|
|
85
101
|
|
|
86
102
|
## What the person confirming is shown
|
|
87
103
|
|
|
88
|
-
|
|
104
|
+
Two things, in two places, and knowing which is which explains most of the rules
|
|
105
|
+
above.
|
|
106
|
+
|
|
107
|
+
**In the client**, a short question: who it is from, **every** recipient, the
|
|
108
|
+
subject, one line of counts, and a link. No part of the message itself. It used
|
|
109
|
+
to carry the body and every address, and grew to 74 lines for a message with
|
|
110
|
+
eighteen links, at which point the confirm button sat below the bottom of the
|
|
111
|
+
dialog and nothing could be sent at all. Recipients are the one thing never
|
|
112
|
+
summarised, however many there are.
|
|
89
113
|
|
|
90
|
-
|
|
114
|
+
**In the browser**, everything else:
|
|
115
|
+
|
|
116
|
+
- The message rendered as the recipient will see it, quote included.
|
|
91
117
|
- **Every address in it, in full**, links and images alike, each with the text it
|
|
92
118
|
is shown as. A link's visible text and its target are the same string in plain
|
|
93
119
|
text and two different strings in markup, and that difference is the shape of
|
|
94
120
|
every phishing message ever written.
|
|
95
|
-
- **Every piece of text a recipient can read that the body
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
121
|
+
- **Every piece of text a recipient can read that the body does not show.** An
|
|
122
|
+
image's alt text is the clearest case: it never appears in the converted body,
|
|
123
|
+
and mail clients block remote images by default, so it is frequently what the
|
|
124
|
+
recipient actually reads.
|
|
99
125
|
- Every file carried with the message, with its size.
|
|
126
|
+
- Every property used beyond ordinary formatting, if \`markupLevel\` was
|
|
127
|
+
\`extended\`, with the ones that really hide something marked as such.
|
|
128
|
+
|
|
129
|
+
The answer is given in the client, never in the browser. That page has no
|
|
130
|
+
confirm button: its address reaches you through \`open_configuration\`, so a
|
|
131
|
+
control there would be one you could press yourself.
|
|
100
132
|
|
|
101
133
|
The agreement is bound to that exact message by a fingerprint covering the
|
|
102
134
|
sender, every recipient, the subject, the markup and the contents of each
|
|
@@ -130,8 +162,16 @@ in the thread. If threading matters, use \`send_reply\` rather than
|
|
|
130
162
|
|
|
131
163
|
A message cannot be given a file from this machine. That is a decision that has
|
|
132
164
|
not been made rather than a feature that is missing: which paths a model may
|
|
133
|
-
reach is its own question.
|
|
134
|
-
|
|
165
|
+
reach is its own question.
|
|
166
|
+
|
|
167
|
+
**This does not stop a message from showing images.** An image at a web address
|
|
168
|
+
needs no attachment at all, and that is how almost every formatted message does
|
|
169
|
+
it. Only a file that would travel inside the message is unavailable.
|
|
170
|
+
|
|
171
|
+
\`cid:\` addresses are permitted and refer to a file the message already carries.
|
|
172
|
+
When composing a new message there is none, so a \`cid:\` reference has nothing
|
|
173
|
+
to point at. Where they do work is a forward: the original travels along whole,
|
|
174
|
+
attachments and embedded images included, so nothing is lost there.
|
|
135
175
|
`;
|
|
136
176
|
const BRIDGE_GUIDE = `# How the Bridge behaves
|
|
137
177
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guidance.js","sourceRoot":"","sources":["../../src/tools/guidance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,wFAAwF;IACxF,EAAE;IACF,wFAAwF;IACxF,gBAAgB;IAChB,EAAE;IACF,4FAA4F;IAC5F,0FAA0F;IAC1F,yCAAyC;IACzC,4FAA4F;IAC5F,uFAAuF;IACvF,6DAA6D;IAC7D,oFAAoF;IACpF,2FAA2F;IAC3F,4FAA4F;IAC5F,kCAAkC;IAClC,uEAAuE;IACvE,EAAE;IACF,8CAA8C;IAC9C,kFAAkF;IAClF,mDAAmD;IACnD,yFAAyF;IACzF,8CAA8C;CAC/C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAEZ,MAAM,aAAa,GAAG
|
|
1
|
+
{"version":3,"file":"guidance.js","sourceRoot":"","sources":["../../src/tools/guidance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,wFAAwF;IACxF,EAAE;IACF,wFAAwF;IACxF,gBAAgB;IAChB,EAAE;IACF,4FAA4F;IAC5F,0FAA0F;IAC1F,yCAAyC;IACzC,4FAA4F;IAC5F,uFAAuF;IACvF,6DAA6D;IAC7D,oFAAoF;IACpF,2FAA2F;IAC3F,4FAA4F;IAC5F,kCAAkC;IAClC,uEAAuE;IACvE,EAAE;IACF,0FAA0F;IAC1F,6FAA6F;IAC7F,yFAAyF;IACzF,EAAE;IACF,8CAA8C;IAC9C,kFAAkF;IAClF,mDAAmD;IACnD,yFAAyF;IACzF,8CAA8C;CAC/C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAEZ,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsHrB,CAAA;AAED,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkEpB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,4BAA4B,EAC5B;QACE,KAAK,EAAE,mCAAmC;QAC1C,WAAW,EACT,yFAAyF;YACzF,2FAA2F;YAC3F,4EAA4E;QAC9E,QAAQ,EAAE,eAAe;KAC1B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC,CACnG,CAAA;IAED,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,2BAA2B,EAC3B;QACE,KAAK,EAAE,oCAAoC;QAC3C,WAAW,EACT,qFAAqF;YACrF,0FAA0F;YAC1F,WAAW;QACb,QAAQ,EAAE,eAAe;KAC1B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC,CAClG,CAAA;AACH,CAAC"}
|
package/dist/tools/interface.js
CHANGED
|
@@ -21,9 +21,13 @@ export function registerInterfaceTool(server, info) {
|
|
|
21
21
|
server.registerTool('open_configuration', {
|
|
22
22
|
title: 'Open the configuration interface',
|
|
23
23
|
description: 'Returns the address of the local configuration interface, which runs for as long as this ' +
|
|
24
|
-
'server does
|
|
25
|
-
'
|
|
26
|
-
'
|
|
24
|
+
'server does and is where everything about this server can be seen and changed. Give it ' +
|
|
25
|
+
'to the user whenever they ask for the interface, the panel, the settings, the web page, ' +
|
|
26
|
+
'the address or the link, however they phrase it, and also when they ask where to sign ' +
|
|
27
|
+
'in, where to see what has been sent, where the folders are listed, or when another tool ' +
|
|
28
|
+
'reports that no credentials are available. The address contains an access token and ' +
|
|
29
|
+
'changes every time the server restarts, so it cannot be remembered from an earlier ' +
|
|
30
|
+
'conversation and has to be asked for again.',
|
|
27
31
|
inputSchema: z.object({}),
|
|
28
32
|
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
29
33
|
}, async () => track(async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/tools/interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAGxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAYvC,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,IAAmB;IAC1E,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,kCAAkC;QACzC,WAAW,EACT,2FAA2F;YAC3F,
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/tools/interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAGxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAYvC,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,IAAmB;IAC1E,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,kCAAkC;QACzC,WAAW,EACT,2FAA2F;YAC3F,yFAAyF;YACzF,0FAA0F;YAC1F,wFAAwF;YACxF,0FAA0F;YAC1F,sFAAsF;YACtF,qFAAqF;YACrF,6CAA6C;QAC/C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;KAC1D,EACD,KAAK,IAAI,EAAE,CACT,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACpB,MAAM,OAAO,GAAmB;gBAC9B,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EACF,8EAA8E;4BAC9E,kFAAkF;4BAClF,4EAA4E;4BAC5E,oCAAoC;qBACvC;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAA;YACD,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,MAAM,KAAK,GAAa,CAAC,4BAA4B,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAEtE,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;YAC7B,KAAK,CAAC,IAAI,CACR,gBAAgB,IAAI,CAAC,OAAO,EAAE,GAAG,EACjC,IAAI;gBACF,CAAC,CAAC,4BAA4B,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG;gBAC/D,CAAC,CAAC,6CAA6C,EACjD,EAAE,EACF,iEAAiE,CAClE,CAAA;QACH,CAAC;aAAM,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5C,KAAK,CAAC,IAAI,CACR,uFAAuF,EACvF,qFAAqF,EACrF,qCAAqC,EACrC,EAAE,EACF,oFAAoF,CACrF,CAAA;QACH,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CACR,oFAAoF,EACpF,qFAAqF,EACrF,8BAA8B,EAC9B,EAAE,EACF,uFAAuF,EACvF,6EAA6E,CAC9E,CAAA;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CACR,EAAE,EACF,yFAAyF,CAC1F,CAAA;QAED,MAAM,MAAM,GAAmB,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAA;QACtF,OAAO,MAAM,CAAA;IACf,CAAC,EAAE,oBAAoB,CAAC,CAC3B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning a held message into what the preview page needs.
|
|
3
|
+
*
|
|
4
|
+
* Its own module rather than a method on either side, because it is the one
|
|
5
|
+
* place where the two halves meet: the sending path knows what a Draft is, the
|
|
6
|
+
* interface knows what it can render, and neither should have to know the
|
|
7
|
+
* other. Putting the translation here keeps `src/web` free of mail types and
|
|
8
|
+
* the sending path free of page structure.
|
|
9
|
+
*
|
|
10
|
+
* Everything the confirmation used to say is assembled here instead, from the
|
|
11
|
+
* same functions that said it. Nothing was dropped in the move: the address
|
|
12
|
+
* list is still every address, the hidden text is still every alt text and
|
|
13
|
+
* title, and the quote is still counted rather than listed for the reason
|
|
14
|
+
* written at summariseQuote.
|
|
15
|
+
*/
|
|
16
|
+
/** What the page needs, without the parts the interface fills in itself. */
|
|
17
|
+
export interface PendingView {
|
|
18
|
+
tool: string;
|
|
19
|
+
from: string;
|
|
20
|
+
to: string[];
|
|
21
|
+
cc: string[];
|
|
22
|
+
bcc: string[];
|
|
23
|
+
subject: string;
|
|
24
|
+
html?: string;
|
|
25
|
+
text?: string;
|
|
26
|
+
urls: Array<{
|
|
27
|
+
url: string;
|
|
28
|
+
label: string;
|
|
29
|
+
kind: 'link' | 'image';
|
|
30
|
+
}>;
|
|
31
|
+
hiddenText: string[];
|
|
32
|
+
attachments: string[];
|
|
33
|
+
quoted?: {
|
|
34
|
+
links: number;
|
|
35
|
+
images: number;
|
|
36
|
+
hiddenText: number;
|
|
37
|
+
};
|
|
38
|
+
styleNotes: Array<{
|
|
39
|
+
property: string;
|
|
40
|
+
value: string;
|
|
41
|
+
element: string;
|
|
42
|
+
hides: boolean;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
/** Assembles the view for a message that is waiting, if one is. */
|
|
46
|
+
export declare function pendingView(digest: string): PendingView | undefined;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning a held message into what the preview page needs.
|
|
3
|
+
*
|
|
4
|
+
* Its own module rather than a method on either side, because it is the one
|
|
5
|
+
* place where the two halves meet: the sending path knows what a Draft is, the
|
|
6
|
+
* interface knows what it can render, and neither should have to know the
|
|
7
|
+
* other. Putting the translation here keeps `src/web` free of mail types and
|
|
8
|
+
* the sending path free of page structure.
|
|
9
|
+
*
|
|
10
|
+
* Everything the confirmation used to say is assembled here instead, from the
|
|
11
|
+
* same functions that said it. Nothing was dropped in the move: the address
|
|
12
|
+
* list is still every address, the hidden text is still every alt text and
|
|
13
|
+
* title, and the quote is still counted rather than listed for the reason
|
|
14
|
+
* written at summariseQuote.
|
|
15
|
+
*/
|
|
16
|
+
import { composedBody, describeAttachments, describeUrls, hiddenTextOf, summariseQuote, styleNotesOf, showRecipient, } from '../mail/compose.js';
|
|
17
|
+
import { previewOf } from './preview.js';
|
|
18
|
+
/**
|
|
19
|
+
* The message as it would arrive, quote and all.
|
|
20
|
+
*
|
|
21
|
+
* The preview shows the whole thing rather than only the composed part, which
|
|
22
|
+
* is the opposite of what the confirmation does. Both are right for where they
|
|
23
|
+
* are: the question in the client asks about the part somebody wrote, while
|
|
24
|
+
* this page answers "what does the recipient get", and for a reply that
|
|
25
|
+
* includes the quote.
|
|
26
|
+
*/
|
|
27
|
+
function bodyFor(draft) {
|
|
28
|
+
if (draft.html !== undefined) {
|
|
29
|
+
return { html: `${draft.html}${draft.quotedHtml ?? ''}` };
|
|
30
|
+
}
|
|
31
|
+
return { text: composedBody(draft) };
|
|
32
|
+
}
|
|
33
|
+
/** Assembles the view for a message that is waiting, if one is. */
|
|
34
|
+
export function pendingView(digest) {
|
|
35
|
+
const waiting = previewOf(digest);
|
|
36
|
+
if (!waiting)
|
|
37
|
+
return undefined;
|
|
38
|
+
const { draft, tool } = waiting;
|
|
39
|
+
const quote = summariseQuote(draft);
|
|
40
|
+
return {
|
|
41
|
+
tool,
|
|
42
|
+
from: showRecipient(draft.from),
|
|
43
|
+
to: draft.to.map(showRecipient),
|
|
44
|
+
cc: draft.cc.map(showRecipient),
|
|
45
|
+
bcc: draft.bcc.map(showRecipient),
|
|
46
|
+
subject: draft.subject,
|
|
47
|
+
...bodyFor(draft),
|
|
48
|
+
urls: describeUrls(draft).map((u) => ({ url: u.url, label: u.label, kind: u.kind })),
|
|
49
|
+
hiddenText: hiddenTextOf(draft),
|
|
50
|
+
attachments: describeAttachments(draft),
|
|
51
|
+
styleNotes: styleNotesOf(draft),
|
|
52
|
+
...(quote
|
|
53
|
+
? {
|
|
54
|
+
quoted: {
|
|
55
|
+
links: quote.links,
|
|
56
|
+
images: quote.images,
|
|
57
|
+
hiddenText: quote.hiddenText.length,
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
: {}),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=pending-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-view.js","sourceRoot":"","sources":["../../src/tools/pending-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,aAAa,GAEd,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAmBxC;;;;;;;;GAQG;AACH,SAAS,OAAO,CAAC,KAAY;IAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE,EAAE,CAAA;IAC3D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAA;AACtC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAA;IAE9B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;IAC/B,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IAEnC,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC;QAC/B,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC;QAC/B,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC;QAC/B,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC;QACjC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG,OAAO,CAAC,KAAK,CAAC;QACjB,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACpF,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC;QAC/B,WAAW,EAAE,mBAAmB,CAAC,KAAK,CAAC;QACvC,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC;QAC/B,GAAG,CAAC,KAAK;YACP,CAAC,CAAC;gBACE,MAAM,EAAE;oBACN,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM;iBACpC;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The message a confirmation is about, held while the question is open.
|
|
3
|
+
*
|
|
4
|
+
* The confirmation itself carries no message content any more. It names the
|
|
5
|
+
* sender, the recipients and the subject, and points at a page in the local
|
|
6
|
+
* interface where the message can be read as the recipient will see it. That
|
|
7
|
+
* page needs the composed message, and this is where it waits.
|
|
8
|
+
*
|
|
9
|
+
* ## Why it has to be held at all
|
|
10
|
+
*
|
|
11
|
+
* The sending path builds the draft twice: once to ask, once to send. Nothing
|
|
12
|
+
* is kept between the two rounds except a sealed digest, which is what makes
|
|
13
|
+
* the confirmation impossible to forge. That design is untouched. A preview,
|
|
14
|
+
* though, has to be readable *between* the rounds, from a different process
|
|
15
|
+
* boundary entirely, so the message has to sit somewhere for as long as the
|
|
16
|
+
* question is unanswered.
|
|
17
|
+
*
|
|
18
|
+
* ## The rules that follow from what this holds
|
|
19
|
+
*
|
|
20
|
+
* This is decrypted mail. It is the one thing the project has always refused to
|
|
21
|
+
* put on disk, because doing so would undo Proton's encryption locally. So:
|
|
22
|
+
*
|
|
23
|
+
* - **Memory only.** Nothing here is ever written anywhere.
|
|
24
|
+
* - **Dropped as soon as the answer arrives**, whichever way it went.
|
|
25
|
+
* - **Dropped when it goes stale**, because a client that never answers must
|
|
26
|
+
* not leave a message readable for the life of the process.
|
|
27
|
+
* - **Bounded**, so a caller that asks a thousand times and answers none of
|
|
28
|
+
* them cannot fill memory.
|
|
29
|
+
*
|
|
30
|
+
* Addressed by the digest that already binds the confirmation. That is not a
|
|
31
|
+
* shortcut: it means a preview can only be found by somebody who knows exactly
|
|
32
|
+
* which message was composed, and it makes the preview and the thing being
|
|
33
|
+
* confirmed the same object by construction.
|
|
34
|
+
*/
|
|
35
|
+
import type { Draft } from '../mail/compose.js';
|
|
36
|
+
/** How long an unanswered question keeps its preview readable. */
|
|
37
|
+
export declare const PREVIEW_TTL_MS: number;
|
|
38
|
+
/**
|
|
39
|
+
* How many may wait at once.
|
|
40
|
+
*
|
|
41
|
+
* Low on purpose. A person answers one question at a time; anything beyond a
|
|
42
|
+
* handful means something is asking without waiting for answers, and the
|
|
43
|
+
* oldest are the ones nobody is coming back for.
|
|
44
|
+
*/
|
|
45
|
+
export declare const MAX_PREVIEWS = 8;
|
|
46
|
+
/** For tests only. */
|
|
47
|
+
export declare function _setClock(clock: () => number): void;
|
|
48
|
+
/** For tests only. */
|
|
49
|
+
export declare function _reset(): void;
|
|
50
|
+
/** Holds a message for as long as its question is open. */
|
|
51
|
+
export declare function holdForPreview(digest: string, draft: Draft, tool: string): void;
|
|
52
|
+
/** The message behind a digest, if the question is still open. */
|
|
53
|
+
export declare function previewOf(digest: string): {
|
|
54
|
+
draft: Draft;
|
|
55
|
+
tool: string;
|
|
56
|
+
} | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Forgets a message.
|
|
59
|
+
*
|
|
60
|
+
* Called once the answer is in, whichever way it went. A declined send has no
|
|
61
|
+
* more business being readable than a completed one.
|
|
62
|
+
*/
|
|
63
|
+
export declare function releasePreview(digest: string): void;
|
|
64
|
+
/** How many are waiting. For the interface, which says so rather than guessing. */
|
|
65
|
+
export declare function pendingCount(): number;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The message a confirmation is about, held while the question is open.
|
|
3
|
+
*
|
|
4
|
+
* The confirmation itself carries no message content any more. It names the
|
|
5
|
+
* sender, the recipients and the subject, and points at a page in the local
|
|
6
|
+
* interface where the message can be read as the recipient will see it. That
|
|
7
|
+
* page needs the composed message, and this is where it waits.
|
|
8
|
+
*
|
|
9
|
+
* ## Why it has to be held at all
|
|
10
|
+
*
|
|
11
|
+
* The sending path builds the draft twice: once to ask, once to send. Nothing
|
|
12
|
+
* is kept between the two rounds except a sealed digest, which is what makes
|
|
13
|
+
* the confirmation impossible to forge. That design is untouched. A preview,
|
|
14
|
+
* though, has to be readable *between* the rounds, from a different process
|
|
15
|
+
* boundary entirely, so the message has to sit somewhere for as long as the
|
|
16
|
+
* question is unanswered.
|
|
17
|
+
*
|
|
18
|
+
* ## The rules that follow from what this holds
|
|
19
|
+
*
|
|
20
|
+
* This is decrypted mail. It is the one thing the project has always refused to
|
|
21
|
+
* put on disk, because doing so would undo Proton's encryption locally. So:
|
|
22
|
+
*
|
|
23
|
+
* - **Memory only.** Nothing here is ever written anywhere.
|
|
24
|
+
* - **Dropped as soon as the answer arrives**, whichever way it went.
|
|
25
|
+
* - **Dropped when it goes stale**, because a client that never answers must
|
|
26
|
+
* not leave a message readable for the life of the process.
|
|
27
|
+
* - **Bounded**, so a caller that asks a thousand times and answers none of
|
|
28
|
+
* them cannot fill memory.
|
|
29
|
+
*
|
|
30
|
+
* Addressed by the digest that already binds the confirmation. That is not a
|
|
31
|
+
* shortcut: it means a preview can only be found by somebody who knows exactly
|
|
32
|
+
* which message was composed, and it makes the preview and the thing being
|
|
33
|
+
* confirmed the same object by construction.
|
|
34
|
+
*/
|
|
35
|
+
/** How long an unanswered question keeps its preview readable. */
|
|
36
|
+
export const PREVIEW_TTL_MS = 15 * 60 * 1000;
|
|
37
|
+
/**
|
|
38
|
+
* How many may wait at once.
|
|
39
|
+
*
|
|
40
|
+
* Low on purpose. A person answers one question at a time; anything beyond a
|
|
41
|
+
* handful means something is asking without waiting for answers, and the
|
|
42
|
+
* oldest are the ones nobody is coming back for.
|
|
43
|
+
*/
|
|
44
|
+
export const MAX_PREVIEWS = 8;
|
|
45
|
+
const held = new Map();
|
|
46
|
+
/**
|
|
47
|
+
* The clock, replaceable for tests.
|
|
48
|
+
*
|
|
49
|
+
* A test for expiry that waits fifteen minutes is a test nobody runs.
|
|
50
|
+
*/
|
|
51
|
+
let now = () => Date.now();
|
|
52
|
+
/** For tests only. */
|
|
53
|
+
export function _setClock(clock) {
|
|
54
|
+
now = clock;
|
|
55
|
+
}
|
|
56
|
+
/** For tests only. */
|
|
57
|
+
export function _reset() {
|
|
58
|
+
held.clear();
|
|
59
|
+
now = () => Date.now();
|
|
60
|
+
}
|
|
61
|
+
function dropStale() {
|
|
62
|
+
const cutoff = now() - PREVIEW_TTL_MS;
|
|
63
|
+
for (const [digest, entry] of held) {
|
|
64
|
+
if (entry.at < cutoff)
|
|
65
|
+
held.delete(digest);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Holds a message for as long as its question is open. */
|
|
69
|
+
export function holdForPreview(digest, draft, tool) {
|
|
70
|
+
dropStale();
|
|
71
|
+
// Oldest first, since a Map keeps insertion order. The one nobody answered
|
|
72
|
+
// longest ago is the one least likely to be answered now.
|
|
73
|
+
while (held.size >= MAX_PREVIEWS) {
|
|
74
|
+
const oldest = held.keys().next();
|
|
75
|
+
if (oldest.done)
|
|
76
|
+
break;
|
|
77
|
+
held.delete(oldest.value);
|
|
78
|
+
}
|
|
79
|
+
held.set(digest, { draft, tool, at: now() });
|
|
80
|
+
}
|
|
81
|
+
/** The message behind a digest, if the question is still open. */
|
|
82
|
+
export function previewOf(digest) {
|
|
83
|
+
dropStale();
|
|
84
|
+
const entry = held.get(digest);
|
|
85
|
+
if (!entry)
|
|
86
|
+
return undefined;
|
|
87
|
+
return { draft: entry.draft, tool: entry.tool };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Forgets a message.
|
|
91
|
+
*
|
|
92
|
+
* Called once the answer is in, whichever way it went. A declined send has no
|
|
93
|
+
* more business being readable than a completed one.
|
|
94
|
+
*/
|
|
95
|
+
export function releasePreview(digest) {
|
|
96
|
+
held.delete(digest);
|
|
97
|
+
}
|
|
98
|
+
/** How many are waiting. For the interface, which says so rather than guessing. */
|
|
99
|
+
export function pendingCount() {
|
|
100
|
+
dropStale();
|
|
101
|
+
return held.size;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/tools/preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAIH,kEAAkE;AAClE,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAE5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA;AAS7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAgB,CAAA;AAEpC;;;;GAIG;AACH,IAAI,GAAG,GAAiB,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAA;AAExC,sBAAsB;AACtB,MAAM,UAAU,SAAS,CAAC,KAAmB;IAC3C,GAAG,GAAG,KAAK,CAAA;AACb,CAAC;AAED,sBAAsB;AACtB,MAAM,UAAU,MAAM;IACpB,IAAI,CAAC,KAAK,EAAE,CAAA;IACZ,GAAG,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAA;AACxB,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,MAAM,GAAG,GAAG,EAAE,GAAG,cAAc,CAAA;IACrC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC,EAAE,GAAG,MAAM;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,KAAY,EAAE,IAAY;IACvE,SAAS,EAAE,CAAA;IACX,2EAA2E;IAC3E,0DAA0D;IAC1D,OAAO,IAAI,CAAC,IAAI,IAAI,YAAY,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;QACjC,IAAI,MAAM,CAAC,IAAI;YAAE,MAAK;QACtB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;AAC9C,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,SAAS,EAAE,CAAA;IACX,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAA;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;AACrB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,YAAY;IAC1B,SAAS,EAAE,CAAA;IACX,OAAO,IAAI,CAAC,IAAI,CAAA;AAClB,CAAC"}
|
package/dist/tools/send.js
CHANGED
|
@@ -19,6 +19,8 @@ import { sendMessage } from '../mail/send.js';
|
|
|
19
19
|
import { buildReplyDraft, buildForwardDraft, readDraftForSending, DRAFTS, } from '../mail/drafts.js';
|
|
20
20
|
import { describeRecipients, mintMessageId, parseRecipient, parseRecipients, MARKUP_NOTE, PLAIN_TEXT_NOTE, UTF8_NOTE, } from '../mail/compose.js';
|
|
21
21
|
import { clientCanConfirm, confirmationAnswer, confirmationRequest, digestOf, pendingSend, refuse, } from './confirm.js';
|
|
22
|
+
import { holdForPreview, releasePreview } from './preview.js';
|
|
23
|
+
import { previewUrl } from './failures.js';
|
|
22
24
|
import { describeFailure, withSignIn } from './failures.js';
|
|
23
25
|
import { track } from '../in-flight.js';
|
|
24
26
|
const ok = (text) => ({ content: [{ type: 'text', text }] });
|
|
@@ -86,10 +88,18 @@ async function confirmed(deps, ctx, tool, what, build) {
|
|
|
86
88
|
if (!clientCanConfirm(ctx))
|
|
87
89
|
return refuse.noElicitation();
|
|
88
90
|
const state = await deps.codec.mint({ tool, digest }, ctx);
|
|
89
|
-
|
|
91
|
+
// Held so the interface can show the message while the question is open.
|
|
92
|
+
// Memory only, and dropped the moment an answer arrives either way.
|
|
93
|
+
holdForPreview(digest, draft, tool);
|
|
94
|
+
return confirmationRequest(draft, what, state, previewUrl(digest));
|
|
90
95
|
}
|
|
91
96
|
// Second round. The seal has already been verified by the SDK, so what is
|
|
92
97
|
// left is whether it says the same thing this call is asking for.
|
|
98
|
+
//
|
|
99
|
+
// The preview is released before any of those checks, and before the send.
|
|
100
|
+
// A refused confirmation has no more business staying readable than a
|
|
101
|
+
// completed one, and an early return must not leave decrypted mail behind.
|
|
102
|
+
releasePreview(digest);
|
|
93
103
|
if (pending.tool !== tool)
|
|
94
104
|
return refuse.wrongTool();
|
|
95
105
|
if (pending.digest !== digest)
|
|
@@ -124,6 +134,14 @@ export function registerSendTools(server, deps) {
|
|
|
124
134
|
'links and images, with colour, font, alignment, spacing and borders. Images may ' +
|
|
125
135
|
'point at a full address; anything outside the permitted set is refused with a ' +
|
|
126
136
|
'reason rather than removed.'),
|
|
137
|
+
markupLevel: z
|
|
138
|
+
.enum(['standard', 'extended'])
|
|
139
|
+
.default('standard')
|
|
140
|
+
.describe('How much markup is permitted. "standard" covers ordinary formatted mail. ' +
|
|
141
|
+
'"extended" permits every CSS property, including ones that can hide content, and ' +
|
|
142
|
+
'makes the confirmation carry a warning telling the person to open the preview. ' +
|
|
143
|
+
'Prefer "standard"; reach for "extended" only when asked for something that needs ' +
|
|
144
|
+
'it, such as a button, which requires display:inline-block.'),
|
|
127
145
|
}),
|
|
128
146
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
129
147
|
}, async (input, ctx) => track(() => withSignIn(ctx, async () => {
|
|
@@ -145,7 +163,9 @@ export function registerSendTools(server, deps) {
|
|
|
145
163
|
// read `text` and get something true.
|
|
146
164
|
text: input.html !== undefined ? htmlToText(input.html) : input.text,
|
|
147
165
|
messageId: mintMessageId(from.address),
|
|
148
|
-
...(input.html !== undefined
|
|
166
|
+
...(input.html !== undefined
|
|
167
|
+
? { html: input.html, markupLevel: input.markupLevel }
|
|
168
|
+
: {}),
|
|
149
169
|
};
|
|
150
170
|
});
|
|
151
171
|
}
|
|
@@ -173,6 +193,14 @@ export function registerSendTools(server, deps) {
|
|
|
173
193
|
'below it either way. The quote is always built from the original\'s text, never ' +
|
|
174
194
|
'from its own markup, so a message full of markup this server would not send can ' +
|
|
175
195
|
'still be replied to or forwarded.'),
|
|
196
|
+
markupLevel: z
|
|
197
|
+
.enum(['standard', 'extended'])
|
|
198
|
+
.default('standard')
|
|
199
|
+
.describe('How much markup is permitted. "standard" covers ordinary formatted mail. ' +
|
|
200
|
+
'"extended" permits every CSS property, including ones that can hide content, and ' +
|
|
201
|
+
'makes the confirmation carry a warning telling the person to open the preview. ' +
|
|
202
|
+
'Prefer "standard"; reach for "extended" only when asked for something that needs ' +
|
|
203
|
+
'it, such as a button, which requires display:inline-block.'),
|
|
176
204
|
mailbox: z.string().optional().describe('The mailbox the original is in, if known.'),
|
|
177
205
|
}),
|
|
178
206
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
@@ -203,6 +231,14 @@ export function registerSendTools(server, deps) {
|
|
|
203
231
|
'below it either way. The quote is always built from the original\'s text, never ' +
|
|
204
232
|
'from its own markup, so a message full of markup this server would not send can ' +
|
|
205
233
|
'still be replied to or forwarded.'),
|
|
234
|
+
markupLevel: z
|
|
235
|
+
.enum(['standard', 'extended'])
|
|
236
|
+
.default('standard')
|
|
237
|
+
.describe('How much markup is permitted. "standard" covers ordinary formatted mail. ' +
|
|
238
|
+
'"extended" permits every CSS property, including ones that can hide content, and ' +
|
|
239
|
+
'makes the confirmation carry a warning telling the person to open the preview. ' +
|
|
240
|
+
'Prefer "standard"; reach for "extended" only when asked for something that needs ' +
|
|
241
|
+
'it, such as a button, which requires display:inline-block.'),
|
|
206
242
|
mailbox: z.string().optional().describe('The mailbox the original is in, if known.'),
|
|
207
243
|
}),
|
|
208
244
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
package/dist/tools/send.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/tools/send.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/tools/send.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: check_for_updates
|
|
3
|
+
*
|
|
4
|
+
* Asks the npm registry which version is current and compares it with the one
|
|
5
|
+
* running.
|
|
6
|
+
*
|
|
7
|
+
* ## The reason this file has a long comment
|
|
8
|
+
*
|
|
9
|
+
* Everything else in this server talks to `127.0.0.1` and nothing else. That is
|
|
10
|
+
* not an accident of implementation, it is the property the readme leads with:
|
|
11
|
+
* your mail is decrypted on your machine and nothing leaves it. This tool is the
|
|
12
|
+
* single exception, and an exception to a claim like that has to be small,
|
|
13
|
+
* visible and voluntary or it should not exist.
|
|
14
|
+
*
|
|
15
|
+
* So:
|
|
16
|
+
*
|
|
17
|
+
* - **It runs only when called.** No check at startup, no timer, nothing in the
|
|
18
|
+
* background. A server that phones out on its own schedule is a different
|
|
19
|
+
* thing from one that answers a question.
|
|
20
|
+
* - **One address, and it is in the source.** `registry.npmjs.org`, over TLS,
|
|
21
|
+
* for one package name.
|
|
22
|
+
* - **It sends nothing about you.** A GET for a public package. The registry
|
|
23
|
+
* learns an IP asked about proton-mcp, which is what installing it already
|
|
24
|
+
* tells them.
|
|
25
|
+
* - **It installs nothing.** A server that replaces its own code is exactly what
|
|
26
|
+
* you do not want from something holding a mailbox. It says what to run.
|
|
27
|
+
* - **Failure is an answer.** Offline, a proxy, a registry that is down: the
|
|
28
|
+
* reply says it could not look, not that anything is broken.
|
|
29
|
+
*
|
|
30
|
+
* The tool description states the outgoing connection, so a model can tell the
|
|
31
|
+
* user before calling rather than after.
|
|
32
|
+
*/
|
|
33
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
34
|
+
/** The package this server is published as. */
|
|
35
|
+
export declare const PACKAGE = "@rndmjoker/proton-mcp";
|
|
36
|
+
/** Long enough for a slow connection, short enough not to hold a tool call. */
|
|
37
|
+
export declare const LOOKUP_TIMEOUT_MS = 5000;
|
|
38
|
+
/** Compares two version strings. Returns true when `latest` is newer. */
|
|
39
|
+
export declare function isNewer(latest: string, running: string): boolean;
|
|
40
|
+
export interface UpdateCheck {
|
|
41
|
+
latest?: string;
|
|
42
|
+
/** Set when the registry could not be asked. Not an error, an answer. */
|
|
43
|
+
unreachable?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Asks the registry for the version on the `latest` tag.
|
|
47
|
+
*
|
|
48
|
+
* Deliberately not `npm view`: spawning a package manager from a mail server to
|
|
49
|
+
* answer a question is a lot of machinery, and it would inherit whatever
|
|
50
|
+
* registry and proxy configuration happens to be around. One request, one URL.
|
|
51
|
+
*/
|
|
52
|
+
export declare function latestVersion(fetchImpl?: typeof fetch, timeoutMs?: number): Promise<UpdateCheck>;
|
|
53
|
+
export declare function registerUpdateTool(server: McpServer, version: string): void;
|