@atomicmail/mcp 0.1.0 → 0.2.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.
- package/README.md +77 -187
- package/esm/_dnt.polyfills.d.ts +101 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -0
- package/esm/_dnt.polyfills.js +127 -0
- package/esm/lib/agent/auth/agent-auth-http.d.ts +26 -0
- package/esm/lib/agent/auth/agent-auth-http.d.ts.map +1 -0
- package/esm/lib/agent/auth/agent-auth-http.js +76 -0
- package/esm/lib/agent/auth/agent-jwt.d.ts +14 -0
- package/esm/lib/agent/auth/agent-jwt.d.ts.map +1 -0
- package/esm/lib/agent/auth/agent-jwt.js +29 -0
- package/esm/lib/agent/auth/agent-pow.d.ts +5 -0
- package/esm/lib/agent/auth/agent-pow.d.ts.map +1 -0
- package/esm/lib/agent/auth/agent-pow.js +49 -0
- package/esm/lib/agent/jmap/agent-help-content.d.ts +4 -0
- package/esm/lib/agent/jmap/agent-help-content.d.ts.map +1 -0
- package/esm/lib/agent/jmap/agent-help-content.js +244 -0
- package/esm/lib/agent/jmap/agent-jmap.d.ts +49 -0
- package/esm/lib/agent/jmap/agent-jmap.d.ts.map +1 -0
- package/esm/lib/agent/jmap/agent-jmap.js +174 -0
- package/esm/lib/agent/jmap/agent-vars.d.ts +23 -0
- package/esm/lib/agent/jmap/agent-vars.d.ts.map +1 -0
- package/esm/lib/agent/jmap/agent-vars.js +65 -0
- package/esm/{mcp/src/credentials.d.ts → lib/agent/session/agent-credentials-store.d.ts} +3 -2
- package/esm/lib/agent/session/agent-credentials-store.d.ts.map +1 -0
- package/esm/{mcp/src/credentials.js → lib/agent/session/agent-credentials-store.js} +19 -16
- package/esm/lib/agent/session/agent-resolve-config.d.ts +24 -0
- package/esm/lib/agent/session/agent-resolve-config.d.ts.map +1 -0
- package/esm/lib/agent/session/agent-resolve-config.js +70 -0
- package/esm/lib/agent/session/agent-session.d.ts +62 -0
- package/esm/lib/agent/session/agent-session.d.ts.map +1 -0
- package/esm/lib/agent/session/agent-session.js +206 -0
- package/esm/lib/core/consts.d.ts.map +1 -0
- package/esm/lib/core/types.d.ts +2 -0
- package/esm/lib/core/types.d.ts.map +1 -0
- package/esm/lib/core/types.js +1 -0
- package/esm/lib/core/utils.d.ts +10 -0
- package/esm/lib/core/utils.d.ts.map +1 -0
- package/esm/lib/core/utils.js +28 -0
- package/esm/lib/mod.d.ts +14 -0
- package/esm/lib/mod.d.ts.map +1 -0
- package/esm/lib/mod.js +13 -0
- package/esm/lib/network/auth-client.d.ts +57 -0
- package/esm/lib/network/auth-client.d.ts.map +1 -0
- package/esm/lib/network/auth-client.js +188 -0
- package/esm/mcp/main.d.ts +3 -0
- package/esm/mcp/main.d.ts.map +1 -0
- package/esm/mcp/main.js +86 -0
- package/esm/mcp/tools/help.d.ts +3 -0
- package/esm/mcp/tools/help.d.ts.map +1 -0
- package/esm/mcp/tools/help.js +22 -0
- package/esm/mcp/{src/tools → tools}/jmap.d.ts +2 -2
- package/esm/mcp/tools/jmap.d.ts.map +1 -0
- package/esm/mcp/tools/jmap.js +115 -0
- package/esm/mcp/{src/tools → tools}/register.d.ts +2 -2
- package/esm/mcp/tools/register.d.ts.map +1 -0
- package/esm/mcp/tools/register.js +43 -0
- package/package.json +5 -5
- package/presets/list_inbox.json +39 -0
- package/presets/reply.json +75 -0
- package/presets/send_mail.json +42 -0
- package/esm/lib/src/consts.d.ts.map +0 -1
- package/esm/mcp/src/auth-session.d.ts +0 -88
- package/esm/mcp/src/auth-session.d.ts.map +0 -1
- package/esm/mcp/src/auth-session.js +0 -378
- package/esm/mcp/src/credentials.d.ts.map +0 -1
- package/esm/mcp/src/docs-content.d.ts +0 -4
- package/esm/mcp/src/docs-content.d.ts.map +0 -1
- package/esm/mcp/src/docs-content.js +0 -405
- package/esm/mcp/src/main.d.ts +0 -3
- package/esm/mcp/src/main.d.ts.map +0 -1
- package/esm/mcp/src/main.js +0 -116
- package/esm/mcp/src/tools/docs.d.ts +0 -3
- package/esm/mcp/src/tools/docs.d.ts.map +0 -1
- package/esm/mcp/src/tools/docs.js +0 -22
- package/esm/mcp/src/tools/jmap.d.ts.map +0 -1
- package/esm/mcp/src/tools/jmap.js +0 -202
- package/esm/mcp/src/tools/register.d.ts.map +0 -1
- package/esm/mcp/src/tools/register.js +0 -79
- /package/esm/lib/{src → core}/consts.d.ts +0 -0
- /package/esm/lib/{src → core}/consts.js +0 -0
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
// Static documentation strings served by the get_docs tool.
|
|
2
|
-
// Kept in one file so future edits don't require touching tool wiring.
|
|
3
|
-
export const TOPICS = {
|
|
4
|
-
overview: `\
|
|
5
|
-
# AtomicMail — Overview
|
|
6
|
-
|
|
7
|
-
AtomicMail is an email service provider (ESP) designed for AI agents. It
|
|
8
|
-
gives you a programmable mailbox you can manage entirely over JMAP (JSON
|
|
9
|
-
Meta Application Protocol) — no IMAP, no SMTP knowledge needed.
|
|
10
|
-
|
|
11
|
-
## MCP Tools
|
|
12
|
-
|
|
13
|
-
This MCP server exposes four tools:
|
|
14
|
-
|
|
15
|
-
1. **register** — Create a new account (PoW signup). Persists credentials
|
|
16
|
-
to disk; returns the API key once.
|
|
17
|
-
2. **jmap_session** — Fetch the JMAP session object to discover your
|
|
18
|
-
accountId.
|
|
19
|
-
3. **jmap_request** — Send any JMAP method-call batch. Auth is automatic.
|
|
20
|
-
Accepts inline 'methodCalls' or a saved 'opsFile'.
|
|
21
|
-
4. **get_docs** — You're reading this! Pass a topic to drill in.
|
|
22
|
-
|
|
23
|
-
## Typical Workflow
|
|
24
|
-
|
|
25
|
-
1. If you don't have an API key, call \`register\` with a username.
|
|
26
|
-
2. Call \`jmap_session\` to learn your accountId and INBOX id.
|
|
27
|
-
3. Use \`jmap_request\` to read, send, and manage email.
|
|
28
|
-
|
|
29
|
-
Available doc topics: overview, auth, jmap_cheatsheet, tools, installation,
|
|
30
|
-
presets, troubleshooting.`,
|
|
31
|
-
installation: `\
|
|
32
|
-
# AtomicMail MCP — Installation
|
|
33
|
-
|
|
34
|
-
The MCP server ships as a single npm-published binary (built from Deno
|
|
35
|
-
sources via dnt) and runs unchanged on Node, Bun, and Deno.
|
|
36
|
-
|
|
37
|
-
## Quick start
|
|
38
|
-
|
|
39
|
-
The simplest way to use it from any MCP host is via npx:
|
|
40
|
-
|
|
41
|
-
\`\`\`json
|
|
42
|
-
{
|
|
43
|
-
"mcpServers": {
|
|
44
|
-
"atomicmail": {
|
|
45
|
-
"command": "npx",
|
|
46
|
-
"args": ["-y", "@atomicmail/mcp"],
|
|
47
|
-
"env": {
|
|
48
|
-
"ATOMIC_MAIL_AUTH_URL": "https://auth.atomicmail.io",
|
|
49
|
-
"ATOMIC_MAIL_API_URL": "https://api.atomicmail.io"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
\`\`\`
|
|
55
|
-
|
|
56
|
-
Replace \`npx\` with \`bunx\` for Bun, or use \`deno run -A npm:@atomicmail/mcp\`
|
|
57
|
-
for Deno.
|
|
58
|
-
|
|
59
|
-
## Cursor
|
|
60
|
-
|
|
61
|
-
In \`~/.cursor/mcp.json\` (or per-project \`.cursor/mcp.json\`):
|
|
62
|
-
|
|
63
|
-
\`\`\`json
|
|
64
|
-
{
|
|
65
|
-
"mcpServers": {
|
|
66
|
-
"atomicmail": {
|
|
67
|
-
"command": "npx",
|
|
68
|
-
"args": ["-y", "@atomicmail/mcp"],
|
|
69
|
-
"env": {
|
|
70
|
-
"ATOMIC_MAIL_AUTH_URL": "https://auth.atomicmail.io",
|
|
71
|
-
"ATOMIC_MAIL_API_URL": "https://api.atomicmail.io"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
\`\`\`
|
|
77
|
-
|
|
78
|
-
## Claude Desktop
|
|
79
|
-
|
|
80
|
-
In \`claude_desktop_config.json\`:
|
|
81
|
-
|
|
82
|
-
\`\`\`json
|
|
83
|
-
{
|
|
84
|
-
"mcpServers": {
|
|
85
|
-
"atomicmail": {
|
|
86
|
-
"command": "npx",
|
|
87
|
-
"args": ["-y", "@atomicmail/mcp"],
|
|
88
|
-
"env": {
|
|
89
|
-
"ATOMIC_MAIL_AUTH_URL": "https://auth.atomicmail.io",
|
|
90
|
-
"ATOMIC_MAIL_API_URL": "https://api.atomicmail.io"
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
\`\`\`
|
|
96
|
-
|
|
97
|
-
## Sharing credentials with the skill CLI
|
|
98
|
-
|
|
99
|
-
If you already use \`atomic-mail-signup\` from \`@atomic-mail/agent-skill\`,
|
|
100
|
-
the MCP can pick up its credentials.json/session.jwt/capability.jwt with
|
|
101
|
-
zero extra env vars beyond \`ATOMIC_MAIL_CREDENTIALS_DIR\`:
|
|
102
|
-
|
|
103
|
-
\`\`\`json
|
|
104
|
-
{
|
|
105
|
-
"mcpServers": {
|
|
106
|
-
"atomicmail": {
|
|
107
|
-
"command": "npx",
|
|
108
|
-
"args": ["-y", "@atomicmail/mcp"],
|
|
109
|
-
"env": {
|
|
110
|
-
"ATOMIC_MAIL_CREDENTIALS_DIR": "/Users/me/.atomicmail"
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
\`\`\`
|
|
116
|
-
|
|
117
|
-
The MCP defaults the credential directory to \`~/.atomicmail/\` if no env
|
|
118
|
-
var is set, so even \`{}\` may suffice on a machine where you've already
|
|
119
|
-
run \`atomic-mail-signup\`.
|
|
120
|
-
|
|
121
|
-
## From source (development)
|
|
122
|
-
|
|
123
|
-
\`\`\`
|
|
124
|
-
git clone https://github.com/atomic-mail/agentic-mail
|
|
125
|
-
cd services/mcp-server-local
|
|
126
|
-
|
|
127
|
-
# Run directly with Deno
|
|
128
|
-
deno task start
|
|
129
|
-
|
|
130
|
-
# Or build the npm package and run with Node
|
|
131
|
-
deno task build:npm
|
|
132
|
-
node npm/esm/main.js
|
|
133
|
-
\`\`\`
|
|
134
|
-
|
|
135
|
-
See README.md in the package root for more.`,
|
|
136
|
-
auth: `\
|
|
137
|
-
# AtomicMail — Auth Flow
|
|
138
|
-
|
|
139
|
-
Auth is fully automatic inside this MCP server. You don't need to do
|
|
140
|
-
anything unless you're registering for the first time.
|
|
141
|
-
|
|
142
|
-
## How it works internally
|
|
143
|
-
|
|
144
|
-
1. **Challenge** — MCP server requests a challenge from the auth service.
|
|
145
|
-
2. **Proof-of-Work** — MCP server computes a scrypt hash that satisfies the
|
|
146
|
-
difficulty requirement. ~64 attempts on average (< 1 second).
|
|
147
|
-
3. **Session JWT** — Server validates the PoW and returns a session token
|
|
148
|
-
(valid for 4 hours). On signup, it also returns a one-time API key.
|
|
149
|
-
4. **Capability JWT** — Before each JMAP call, the MCP server exchanges the
|
|
150
|
-
session JWT for a short-lived capability token (2 min TTL) that the API
|
|
151
|
-
service accepts.
|
|
152
|
-
|
|
153
|
-
The MCP server decodes JWT \`exp\` claims and rotates session/capability
|
|
154
|
-
JWTs as they approach expiry, persisting the new tokens to disk so a
|
|
155
|
-
restarted process (or a concurrent atomic-mail-jmap CLI invocation) sees
|
|
156
|
-
the latest values.
|
|
157
|
-
|
|
158
|
-
## Credential files
|
|
159
|
-
|
|
160
|
-
All three files live in the credential directory (default
|
|
161
|
-
\`~/.atomicmail/\`, override with \`ATOMIC_MAIL_CREDENTIALS_DIR\`). They are
|
|
162
|
-
written with mode 0600 so other local users cannot read them.
|
|
163
|
-
|
|
164
|
-
credentials.json { apiKey, inboxId, authUrl, apiUrl, scryptSalt }
|
|
165
|
-
session.jwt 4-hour TTL
|
|
166
|
-
capability.jwt 2-minute TTL
|
|
167
|
-
|
|
168
|
-
## Environment Variables
|
|
169
|
-
|
|
170
|
-
| Variable | Required | Description |
|
|
171
|
-
|--------------------------------|----------|-----------------------------------|
|
|
172
|
-
| ATOMIC_MAIL_AUTH_URL | Yes* | Auth service URL |
|
|
173
|
-
| ATOMIC_MAIL_API_URL | Yes* | API/JMAP service URL |
|
|
174
|
-
| ATOMIC_MAIL_SCRYPT_SALT | No | Optional PoW salt override (defaults match auth-service) |
|
|
175
|
-
| ATOMIC_MAIL_API_KEY | No | Existing API key (skip signup) |
|
|
176
|
-
| ATOMIC_MAIL_CREDENTIALS_DIR | No | Override default credential dir |
|
|
177
|
-
|
|
178
|
-
* "Yes" means at least one source — env var OR credentials.json — must
|
|
179
|
-
provide authUrl and apiUrl. Env vars override credentials.json on a per-field
|
|
180
|
-
basis. PoW salt defaults to the built-in deployment constant when unset.`,
|
|
181
|
-
jmap_cheatsheet: `\
|
|
182
|
-
# JMAP Cheatsheet for AtomicMail
|
|
183
|
-
|
|
184
|
-
JMAP (RFC 8620 + RFC 8621) is a JSON-over-HTTP protocol for email. Every
|
|
185
|
-
request is a batch of method calls. AtomicMail supports:
|
|
186
|
-
|
|
187
|
-
## Capabilities (pass in "using")
|
|
188
|
-
- urn:ietf:params:jmap:core
|
|
189
|
-
- urn:ietf:params:jmap:mail
|
|
190
|
-
- urn:ietf:params:jmap:submission
|
|
191
|
-
|
|
192
|
-
## Common Method Calls
|
|
193
|
-
|
|
194
|
-
### List mailboxes
|
|
195
|
-
\`\`\`json
|
|
196
|
-
["Mailbox/get", {"accountId": "ACCOUNT_ID"}, "m0"]
|
|
197
|
-
\`\`\`
|
|
198
|
-
|
|
199
|
-
### List identities (for sending)
|
|
200
|
-
\`\`\`json
|
|
201
|
-
["Identity/get", {"accountId": "ACCOUNT_ID"}, "i0"]
|
|
202
|
-
\`\`\`
|
|
203
|
-
|
|
204
|
-
### Query last 100 emails in INBOX (newest first)
|
|
205
|
-
\`\`\`json
|
|
206
|
-
["Email/query", {
|
|
207
|
-
"accountId": "ACCOUNT_ID",
|
|
208
|
-
"filter": {"inMailbox": "INBOX_ID"},
|
|
209
|
-
"sort": [{"property": "receivedAt", "isAscending": false}],
|
|
210
|
-
"limit": 100
|
|
211
|
-
}, "q0"]
|
|
212
|
-
\`\`\`
|
|
213
|
-
|
|
214
|
-
### Fetch email details (back-reference from query)
|
|
215
|
-
\`\`\`json
|
|
216
|
-
["Email/get", {
|
|
217
|
-
"accountId": "ACCOUNT_ID",
|
|
218
|
-
"#ids": {"resultOf": "q0", "name": "Email/query", "path": "/ids"},
|
|
219
|
-
"properties": ["subject", "from", "to", "receivedAt", "bodyValues"],
|
|
220
|
-
"fetchAllBodyValues": true
|
|
221
|
-
}, "g0"]
|
|
222
|
-
\`\`\`
|
|
223
|
-
|
|
224
|
-
### Send an email (create draft + submit, destroy on success)
|
|
225
|
-
\`\`\`json
|
|
226
|
-
["Email/set", {
|
|
227
|
-
"accountId": "ACCOUNT_ID",
|
|
228
|
-
"create": {
|
|
229
|
-
"draft": {
|
|
230
|
-
"mailboxIds": {"INBOX_ID": true},
|
|
231
|
-
"keywords": {"$draft": true},
|
|
232
|
-
"from": [{"email": "you@atomicmail.io"}],
|
|
233
|
-
"to": [{"email": "recipient@example.com"}],
|
|
234
|
-
"subject": "Hello",
|
|
235
|
-
"bodyValues": {"body": {"value": "Message body", "charset": "utf-8"}},
|
|
236
|
-
"textBody": [{"partId": "body", "type": "text/plain"}]
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}, "c0"],
|
|
240
|
-
["EmailSubmission/set", {
|
|
241
|
-
"accountId": "ACCOUNT_ID",
|
|
242
|
-
"onSuccessDestroyEmail": ["#sub"],
|
|
243
|
-
"create": {
|
|
244
|
-
"sub": {
|
|
245
|
-
"emailId": "#draft",
|
|
246
|
-
"identityId": "IDENTITY_ID",
|
|
247
|
-
"envelope": {
|
|
248
|
-
"mailFrom": {"email": "you@atomicmail.io"},
|
|
249
|
-
"rcptTo": [{"email": "recipient@example.com"}]
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}, "c1"]
|
|
254
|
-
\`\`\`
|
|
255
|
-
|
|
256
|
-
## Tips
|
|
257
|
-
|
|
258
|
-
- Always call \`jmap_session\` first to discover accountId and the INBOX id.
|
|
259
|
-
- Back-references (\`#ids\`, \`#draft\`) chain calls in a single batch.
|
|
260
|
-
- Add \`urn:ietf:params:jmap:submission\` to \`using\` when sending email.
|
|
261
|
-
- Save reusable batches as preset files — see the \`presets\` topic.`,
|
|
262
|
-
tools: `\
|
|
263
|
-
# AtomicMail MCP — Tool Reference
|
|
264
|
-
|
|
265
|
-
## register
|
|
266
|
-
**Input:** { username: string }
|
|
267
|
-
**Returns:** Account info + API key (also persisted to credentials.json).
|
|
268
|
-
Creates a new account. Performs Proof-of-Work automatically. Refuses to
|
|
269
|
-
run if an API key is already configured.
|
|
270
|
-
|
|
271
|
-
## jmap_session
|
|
272
|
-
**Input:** (none)
|
|
273
|
-
**Returns:** JMAP session JSON with accountId, capabilities, and URLs.
|
|
274
|
-
Call this first to discover your accountId and mailbox structure.
|
|
275
|
-
|
|
276
|
-
## jmap_request
|
|
277
|
-
**Input:** { using?: string[], methodCalls?: array, opsFile?: string }
|
|
278
|
-
**Returns:** JMAP response JSON with methodResponses.
|
|
279
|
-
Sends a batch of JMAP method calls. Auth is automatic.
|
|
280
|
-
|
|
281
|
-
• methodCalls — inline JMAP batch.
|
|
282
|
-
• opsFile — path to a saved JSON preset (relative paths resolve
|
|
283
|
-
against the credential directory).
|
|
284
|
-
• using — capability URNs. Defaults to core + mail. Add
|
|
285
|
-
"urn:ietf:params:jmap:submission" when sending.
|
|
286
|
-
|
|
287
|
-
Exactly one of methodCalls or opsFile must be provided.
|
|
288
|
-
|
|
289
|
-
## get_docs
|
|
290
|
-
**Input:** { topic?: string }
|
|
291
|
-
**Returns:** Documentation text.
|
|
292
|
-
Topics: overview, installation, auth, jmap_cheatsheet, tools, presets,
|
|
293
|
-
troubleshooting.`,
|
|
294
|
-
presets: `\
|
|
295
|
-
# AtomicMail MCP — JMAP Presets
|
|
296
|
-
|
|
297
|
-
The \`opsFile\` parameter on \`jmap_request\` lets you save reusable JMAP
|
|
298
|
-
batches as JSON files on disk, then reference them by path. This mirrors
|
|
299
|
-
the \`atomic-mail-jmap --ops-file\` flag from the skill CLI, so the MCP
|
|
300
|
-
server and the skill CLI both consume the same preset format from the
|
|
301
|
-
same directory.
|
|
302
|
-
|
|
303
|
-
## Where presets live
|
|
304
|
-
|
|
305
|
-
Relative paths passed to \`opsFile\` resolve against the credential
|
|
306
|
-
directory (default \`~/.atomicmail/\`, override with
|
|
307
|
-
\`ATOMIC_MAIL_CREDENTIALS_DIR\`). Absolute paths are taken as-is.
|
|
308
|
-
|
|
309
|
-
So \`opsFile: "fetch_last_100.json"\` reads from
|
|
310
|
-
\`~/.atomicmail/fetch_last_100.json\`.
|
|
311
|
-
|
|
312
|
-
## Preset file shape
|
|
313
|
-
|
|
314
|
-
Two equivalent shapes are accepted:
|
|
315
|
-
|
|
316
|
-
1. A bare \`methodCalls\` array:
|
|
317
|
-
|
|
318
|
-
\`\`\`json
|
|
319
|
-
[
|
|
320
|
-
["Email/query", {
|
|
321
|
-
"accountId": "ACC",
|
|
322
|
-
"filter": {"inMailbox": "INBOX"},
|
|
323
|
-
"sort": [{"property": "receivedAt", "isAscending": false}],
|
|
324
|
-
"limit": 100
|
|
325
|
-
}, "q0"]
|
|
326
|
-
]
|
|
327
|
-
\`\`\`
|
|
328
|
-
|
|
329
|
-
2. A full envelope:
|
|
330
|
-
|
|
331
|
-
\`\`\`json
|
|
332
|
-
{
|
|
333
|
-
"using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
|
|
334
|
-
"methodCalls": [
|
|
335
|
-
["Email/query", { "...": "..." }, "q0"]
|
|
336
|
-
]
|
|
337
|
-
}
|
|
338
|
-
\`\`\`
|
|
339
|
-
|
|
340
|
-
If the file already specifies \`using\`, that wins over the inline
|
|
341
|
-
\`using\` parameter; otherwise the request defaults (\`core + mail\`) or
|
|
342
|
-
the explicit \`using\` argument is used.
|
|
343
|
-
|
|
344
|
-
## Suggested presets to keep
|
|
345
|
-
|
|
346
|
-
- \`fetch_last_100.json\` — newest 100 emails in INBOX.
|
|
347
|
-
- \`unread_inbox.json\` — query \`{filter: {inMailbox: ..., notKeyword: "$seen"}}\`.
|
|
348
|
-
- \`my_identities.json\` — \`Identity/get\` for sending.
|
|
349
|
-
- \`mailboxes.json\` — \`Mailbox/get\` to keep a fresh map of folders.
|
|
350
|
-
|
|
351
|
-
A typical agent workflow: bootstrap presets once via \`atomic-mail-signup\`
|
|
352
|
-
+ a few file writes, then drive everything through \`opsFile\` + a small
|
|
353
|
-
amount of inline parameter substitution.`,
|
|
354
|
-
troubleshooting: `\
|
|
355
|
-
# AtomicMail MCP — Troubleshooting
|
|
356
|
-
|
|
357
|
-
## "Missing required configuration: ATOMIC_MAIL_AUTH_URL, ..."
|
|
358
|
-
|
|
359
|
-
The server could not resolve authUrl and apiUrl from either env vars or
|
|
360
|
-
\`credentials.json\` in the credential directory.
|
|
361
|
-
Either set the env vars in your MCP host config, or run
|
|
362
|
-
\`atomic-mail-signup\` once to populate \`credentials.json\`.
|
|
363
|
-
|
|
364
|
-
## "No API key configured — call the 'register' tool"
|
|
365
|
-
|
|
366
|
-
The server started fine but no API key was found. Either:
|
|
367
|
-
- Call the \`register\` tool to create a new account, or
|
|
368
|
-
- Set \`ATOMIC_MAIL_API_KEY\` in your MCP env, or
|
|
369
|
-
- Place an existing \`credentials.json\` (from another machine, or
|
|
370
|
-
from \`atomic-mail-signup\`) into the credential directory.
|
|
371
|
-
|
|
372
|
-
## "auth-service /api/v1/session returned 401"
|
|
373
|
-
|
|
374
|
-
Usually means the API key is invalid for the configured auth service,
|
|
375
|
-
or (if you set \`ATOMIC_MAIL_SCRYPT_SALT\`) the override does not match the
|
|
376
|
-
server build. Verify authUrl and apiUrl match the deployment you signed up at.
|
|
377
|
-
|
|
378
|
-
## "Capability JWT missing inboxId claim"
|
|
379
|
-
|
|
380
|
-
The auth service returned a capability JWT without the inboxId claim. This
|
|
381
|
-
indicates a server bug — please open an issue with the auth-service
|
|
382
|
-
deployment version.
|
|
383
|
-
|
|
384
|
-
## I changed the PoW salt override — what now?
|
|
385
|
-
|
|
386
|
-
The PoW salt is normally fixed per server release. If you set
|
|
387
|
-
\`ATOMIC_MAIL_SCRYPT_SALT\` or stored a custom \`scryptSalt\` in
|
|
388
|
-
credentials.json, it must match the auth-service build you are talking to.
|
|
389
|
-
|
|
390
|
-
## "Could not read opsFile '/path/to/x.json'"
|
|
391
|
-
|
|
392
|
-
The opsFile path could not be opened. Relative paths resolve against the
|
|
393
|
-
credential directory — for absolute control, pass an absolute path. The
|
|
394
|
-
file must contain valid JSON (either a methodCalls array or a full
|
|
395
|
-
envelope). See the \`presets\` topic.`,
|
|
396
|
-
};
|
|
397
|
-
export const TOPIC_LIST = Object.keys(TOPICS);
|
|
398
|
-
export function getDocs(topic) {
|
|
399
|
-
if (!topic) {
|
|
400
|
-
return TOPICS["overview"];
|
|
401
|
-
}
|
|
402
|
-
const key = topic.toLowerCase().replace(/[\s-]/g, "_");
|
|
403
|
-
return (TOPICS[key] ??
|
|
404
|
-
`Unknown topic "${topic}". Available topics: ${TOPIC_LIST.join(", ")}`);
|
|
405
|
-
}
|
package/esm/mcp/src/main.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/mcp/src/main.ts"],"names":[],"mappings":""}
|
package/esm/mcp/src/main.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// AtomicMail MCP server — local stdio proxy with PoW auth and JMAP.
|
|
3
|
-
//
|
|
4
|
-
// Designed to be launched by an MCP-capable agent host (Cursor, Claude
|
|
5
|
-
// Desktop, Continue, Cline, ...) as a child process and communicated with
|
|
6
|
-
// over stdio.
|
|
7
|
-
//
|
|
8
|
-
// CONFIGURATION (priority order):
|
|
9
|
-
// 1. credentials.json + session.jwt + capability.jwt in the credential
|
|
10
|
-
// directory (default: ~/.atomicmail/, override with the env var
|
|
11
|
-
// ATOMIC_MAIL_CREDENTIALS_DIR). This is the SAME on-disk layout
|
|
12
|
-
// produced by the atomic-mail-signup CLI from @atomic-mail/agent-skill.
|
|
13
|
-
// 2. ATOMIC_MAIL_AUTH_URL / ATOMIC_MAIL_API_URL / ATOMIC_MAIL_API_KEY —
|
|
14
|
-
// overlay individual fields on top of (1). Optional: ATOMIC_MAIL_SCRYPT_SALT
|
|
15
|
-
// overrides the built-in PoW salt (normally unnecessary).
|
|
16
|
-
//
|
|
17
|
-
// If auth and API URLs cannot be resolved, the server fails fast on startup.
|
|
18
|
-
//
|
|
19
|
-
// See README.md for installation and MCP host configuration examples.
|
|
20
|
-
import process from "node:process";
|
|
21
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
22
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
23
|
-
import { AuthSession, resolveConfig } from "./auth-session.js";
|
|
24
|
-
import { registerDocsTool } from "./tools/docs.js";
|
|
25
|
-
import { registerJmapTool } from "./tools/jmap.js";
|
|
26
|
-
import { registerRegisterTool } from "./tools/register.js";
|
|
27
|
-
const VERSION = "0.1.0";
|
|
28
|
-
const INSTRUCTIONS = `\
|
|
29
|
-
AtomicMail MCP server — a programmable email inbox for AI agents.
|
|
30
|
-
|
|
31
|
-
WORKFLOW
|
|
32
|
-
1. If you do not yet have an account, call the 'register' tool with a
|
|
33
|
-
desired username. It performs a Proof-of-Work signup and persists
|
|
34
|
-
credentials.json + session.jwt + capability.jwt into the credential
|
|
35
|
-
directory so future invocations skip this step.
|
|
36
|
-
2. Call 'jmap_session' to fetch your accountId, capabilities, and the
|
|
37
|
-
mailbox URL. Cache the accountId — every subsequent JMAP call needs it.
|
|
38
|
-
3. Call 'jmap_request' with one or more JMAP method calls. Auth (session
|
|
39
|
-
+ capability JWT rotation) is fully automatic. You can either pass
|
|
40
|
-
'methodCalls' inline or 'opsFile' (a path to a saved JSON preset).
|
|
41
|
-
4. Call 'get_docs' for in-depth topic guides. Topics include:
|
|
42
|
-
overview, auth, jmap_cheatsheet, tools, installation, presets,
|
|
43
|
-
troubleshooting.
|
|
44
|
-
|
|
45
|
-
CREDENTIAL FILES
|
|
46
|
-
Credentials live in ~/.atomicmail/ by default (override with
|
|
47
|
-
ATOMIC_MAIL_CREDENTIALS_DIR). The same files are produced by the
|
|
48
|
-
atomic-mail-signup CLI from @atomic-mail/agent-skill so you can mix and
|
|
49
|
-
match the two — e.g. bootstrap an account with the CLI, then point the
|
|
50
|
-
MCP at the same directory.
|
|
51
|
-
|
|
52
|
-
credentials.json { apiKey, inboxId, authUrl, apiUrl, scryptSalt }
|
|
53
|
-
session.jwt 4-hour TTL, rotated automatically via PoW.
|
|
54
|
-
capability.jwt 2-minute TTL, rotated automatically via /capability.
|
|
55
|
-
|
|
56
|
-
ENVIRONMENT VARIABLES
|
|
57
|
-
ATOMIC_MAIL_CREDENTIALS_DIR override default credential directory
|
|
58
|
-
ATOMIC_MAIL_AUTH_URL auth-service base URL
|
|
59
|
-
ATOMIC_MAIL_API_URL api-service / JMAP base URL
|
|
60
|
-
ATOMIC_MAIL_SCRYPT_SALT optional PoW salt override (defaults match auth-service)
|
|
61
|
-
ATOMIC_MAIL_API_KEY existing API key (skip signup)
|
|
62
|
-
|
|
63
|
-
SECURITY
|
|
64
|
-
credentials.json contains your apiKey — treat it like a password. Files
|
|
65
|
-
are written with mode 0600.
|
|
66
|
-
|
|
67
|
-
For full reference call get_docs with the relevant topic.`;
|
|
68
|
-
async function main() {
|
|
69
|
-
let config;
|
|
70
|
-
try {
|
|
71
|
-
config = await resolveConfig();
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
console.error("AtomicMail MCP: configuration error:", err instanceof Error ? err.message : err);
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
console.error(`AtomicMail MCP v${VERSION}: credential dir '${config.credentialDir}' ` +
|
|
78
|
-
`(config source: ${config.source}).`);
|
|
79
|
-
if (config.apiKey) {
|
|
80
|
-
console.error(`AtomicMail MCP: API key found${config.inboxId ? ` (inbox ${config.inboxId})` : ""}.`);
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
console.error("AtomicMail MCP: no API key configured — call the 'register' tool to create an account.");
|
|
84
|
-
}
|
|
85
|
-
const session = await AuthSession.create({
|
|
86
|
-
authUrl: config.authUrl,
|
|
87
|
-
apiUrl: config.apiUrl,
|
|
88
|
-
scryptSalt: config.scryptSalt,
|
|
89
|
-
apiKey: config.apiKey,
|
|
90
|
-
inboxId: config.inboxId,
|
|
91
|
-
credentialDir: config.credentialDir,
|
|
92
|
-
files: config.files,
|
|
93
|
-
});
|
|
94
|
-
const server = new McpServer({ name: "atomicmail", version: VERSION }, { instructions: INSTRUCTIONS });
|
|
95
|
-
registerRegisterTool(server, session);
|
|
96
|
-
registerJmapTool(server, session);
|
|
97
|
-
registerDocsTool(server);
|
|
98
|
-
const cleanup = () => {
|
|
99
|
-
session.destroy();
|
|
100
|
-
};
|
|
101
|
-
process.on("SIGINT", () => {
|
|
102
|
-
cleanup();
|
|
103
|
-
process.exit(0);
|
|
104
|
-
});
|
|
105
|
-
process.on("SIGTERM", () => {
|
|
106
|
-
cleanup();
|
|
107
|
-
process.exit(0);
|
|
108
|
-
});
|
|
109
|
-
const transport = new StdioServerTransport();
|
|
110
|
-
await server.connect(transport);
|
|
111
|
-
console.error("AtomicMail MCP: server running on stdio");
|
|
112
|
-
}
|
|
113
|
-
main().catch((err) => {
|
|
114
|
-
console.error("AtomicMail MCP: fatal error:", err);
|
|
115
|
-
process.exit(1);
|
|
116
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../../../src/mcp/src/tools/docs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAGtE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2BxD"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { getDocs, TOPIC_LIST } from "../docs-content.js";
|
|
3
|
-
export function registerDocsTool(server) {
|
|
4
|
-
server.registerTool("get_docs", {
|
|
5
|
-
title: "AtomicMail documentation",
|
|
6
|
-
description: `Get documentation about AtomicMail and this MCP server. ` +
|
|
7
|
-
`Available topics: ${TOPIC_LIST.join(", ")}. ` +
|
|
8
|
-
`Call with no topic for the overview.`,
|
|
9
|
-
inputSchema: z.object({
|
|
10
|
-
topic: z
|
|
11
|
-
.string()
|
|
12
|
-
.optional()
|
|
13
|
-
.describe(`Documentation topic. One of: ${TOPIC_LIST.join(", ")}. Omit for overview.`),
|
|
14
|
-
}),
|
|
15
|
-
annotations: {
|
|
16
|
-
readOnlyHint: true,
|
|
17
|
-
idempotentHint: true,
|
|
18
|
-
},
|
|
19
|
-
}, ({ topic }) => ({
|
|
20
|
-
content: [{ type: "text", text: getDocs(topic) }],
|
|
21
|
-
}));
|
|
22
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jmap.d.ts","sourceRoot":"","sources":["../../../../src/mcp/src/tools/jmap.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2CtD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,WAAW,GACnB,IAAI,CAyMN"}
|