mcp-twake-mail 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -48
- package/build/cli/commands/setup.js +54 -12
- package/build/cli/commands/setup.js.map +1 -1
- package/build/cli/prompts/setup-wizard.d.ts +33 -1
- package/build/cli/prompts/setup-wizard.js +134 -2
- package/build/cli/prompts/setup-wizard.js.map +1 -1
- package/build/cli/prompts/setup-wizard.test.d.ts +1 -0
- package/build/cli/prompts/setup-wizard.test.js +161 -0
- package/build/cli/prompts/setup-wizard.test.js.map +1 -0
- package/build/config/schema.d.ts +2 -0
- package/build/config/schema.js +3 -0
- package/build/config/schema.js.map +1 -1
- package/build/discovery/dns-srv.d.ts +18 -0
- package/build/discovery/dns-srv.js +60 -0
- package/build/discovery/dns-srv.js.map +1 -0
- package/build/discovery/dns-srv.test.d.ts +4 -0
- package/build/discovery/dns-srv.test.js +79 -0
- package/build/discovery/dns-srv.test.js.map +1 -0
- package/build/discovery/index.d.ts +9 -0
- package/build/discovery/index.js +13 -0
- package/build/discovery/index.js.map +1 -0
- package/build/discovery/oauth-discovery.d.ts +34 -0
- package/build/discovery/oauth-discovery.js +160 -0
- package/build/discovery/oauth-discovery.js.map +1 -0
- package/build/discovery/oauth-discovery.test.d.ts +1 -0
- package/build/discovery/oauth-discovery.test.js +198 -0
- package/build/discovery/oauth-discovery.test.js.map +1 -0
- package/build/discovery/orchestrator.d.ts +31 -0
- package/build/discovery/orchestrator.js +87 -0
- package/build/discovery/orchestrator.js.map +1 -0
- package/build/discovery/orchestrator.test.d.ts +4 -0
- package/build/discovery/orchestrator.test.js +242 -0
- package/build/discovery/orchestrator.test.js.map +1 -0
- package/build/discovery/types.d.ts +18 -0
- package/build/discovery/types.js +15 -0
- package/build/discovery/types.js.map +1 -0
- package/build/discovery/well-known.d.ts +21 -0
- package/build/discovery/well-known.js +52 -0
- package/build/discovery/well-known.js.map +1 -0
- package/build/discovery/well-known.test.d.ts +4 -0
- package/build/discovery/well-known.test.js +120 -0
- package/build/discovery/well-known.test.js.map +1 -0
- package/build/mcp/server.d.ts +5 -3
- package/build/mcp/server.js +11 -5
- package/build/mcp/server.js.map +1 -1
- package/build/mcp/tools/email-sending.d.ts +10 -1
- package/build/mcp/tools/email-sending.js +60 -15
- package/build/mcp/tools/email-sending.js.map +1 -1
- package/build/mcp/tools/index.d.ts +10 -1
- package/build/mcp/tools/index.js +4 -3
- package/build/mcp/tools/index.js.map +1 -1
- package/build/signature/converter.d.ts +2 -0
- package/build/signature/converter.js +23 -0
- package/build/signature/converter.js.map +1 -0
- package/build/signature/converter.test.d.ts +1 -0
- package/build/signature/converter.test.js +84 -0
- package/build/signature/converter.test.js.map +1 -0
- package/build/signature/index.d.ts +2 -0
- package/build/signature/index.js +3 -0
- package/build/signature/index.js.map +1 -0
- package/build/signature/loader.d.ts +6 -0
- package/build/signature/loader.js +31 -0
- package/build/signature/loader.js.map +1 -0
- package/build/signature/loader.test.d.ts +1 -0
- package/build/signature/loader.test.js +85 -0
- package/build/signature/loader.test.js.map +1 -0
- package/docs/auto-discovery.md +210 -0
- package/docs/oidc-configuration.md +261 -0
- package/package.json +3 -1
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# OIDC Configuration Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how to configure mcp-twake-mail for OpenID Connect (OIDC) authentication with your JMAP email server.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
OIDC authentication uses the OAuth 2.0 Authorization Code flow with PKCE (Proof Key for Code Exchange) to securely authenticate users. This is the recommended method for enterprise environments with Single Sign-On (SSO).
|
|
8
|
+
|
|
9
|
+
**Key benefits:**
|
|
10
|
+
- No passwords stored in configuration files
|
|
11
|
+
- Automatic token refresh
|
|
12
|
+
- Enterprise SSO integration
|
|
13
|
+
- Secure PKCE S256 code challenge
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
Before configuring OIDC, you need:
|
|
18
|
+
|
|
19
|
+
1. **OIDC Provider** — An identity provider that supports OpenID Connect:
|
|
20
|
+
- Keycloak
|
|
21
|
+
- Auth0
|
|
22
|
+
- Okta
|
|
23
|
+
- Azure AD
|
|
24
|
+
- Google Workspace
|
|
25
|
+
- Any OIDC-compliant provider
|
|
26
|
+
|
|
27
|
+
2. **Client Registration** — A registered OAuth client with:
|
|
28
|
+
- Client ID
|
|
29
|
+
- Redirect URI: `http://localhost:3000/callback`
|
|
30
|
+
- Authorization Code flow enabled
|
|
31
|
+
- PKCE support (S256)
|
|
32
|
+
|
|
33
|
+
3. **JMAP Server** — Must accept tokens from your OIDC provider
|
|
34
|
+
|
|
35
|
+
## Quick Setup
|
|
36
|
+
|
|
37
|
+
The easiest way to configure OIDC is with the setup wizard:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx mcp-twake-mail setup
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Choose **OIDC** when prompted for authentication method. The wizard will:
|
|
44
|
+
1. Ask for OIDC issuer URL
|
|
45
|
+
2. Ask for client ID
|
|
46
|
+
3. Open your browser for authentication
|
|
47
|
+
4. Store tokens securely
|
|
48
|
+
5. Generate configuration
|
|
49
|
+
|
|
50
|
+
## Configuration Variables
|
|
51
|
+
|
|
52
|
+
| Variable | Required | Description | Example |
|
|
53
|
+
|----------|----------|-------------|---------|
|
|
54
|
+
| `JMAP_SESSION_URL` | Yes | JMAP server session URL | `https://jmap.example.com/jmap/session` |
|
|
55
|
+
| `JMAP_AUTH_METHOD` | Yes | Must be `oidc` | `oidc` |
|
|
56
|
+
| `JMAP_OIDC_ISSUER` | Yes | OIDC provider base URL | `https://sso.example.com` |
|
|
57
|
+
| `JMAP_OIDC_CLIENT_ID` | Yes | OAuth client identifier | `mcp-twake-mail` |
|
|
58
|
+
| `JMAP_OIDC_SCOPE` | No | OAuth scopes to request | `openid profile email offline_access` |
|
|
59
|
+
| `JMAP_OIDC_REDIRECT_URI` | No | OAuth callback URL | `http://localhost:3000/callback` |
|
|
60
|
+
|
|
61
|
+
### Scopes
|
|
62
|
+
|
|
63
|
+
The default scopes are: `openid profile email offline_access`
|
|
64
|
+
|
|
65
|
+
| Scope | Required | Purpose |
|
|
66
|
+
|-------|----------|---------|
|
|
67
|
+
| `openid` | Yes | OpenID Connect authentication |
|
|
68
|
+
| `profile` | Recommended | User profile information |
|
|
69
|
+
| `email` | Recommended | User email address |
|
|
70
|
+
| `offline_access` | Recommended | Refresh token for automatic renewal |
|
|
71
|
+
|
|
72
|
+
**Important:** Include `offline_access` to enable automatic token refresh. Without it, users must re-authenticate when the access token expires.
|
|
73
|
+
|
|
74
|
+
### Redirect URI
|
|
75
|
+
|
|
76
|
+
The default redirect URI is `http://localhost:3000/callback`.
|
|
77
|
+
|
|
78
|
+
You can customize this with `JMAP_OIDC_REDIRECT_URI`, but it must:
|
|
79
|
+
- Match exactly what's registered in your OIDC provider
|
|
80
|
+
- Be accessible on your local machine during authentication
|
|
81
|
+
- Use HTTP for localhost (HTTPS not required)
|
|
82
|
+
|
|
83
|
+
For remote development (e.g., via ngrok), use the full ngrok URL:
|
|
84
|
+
```
|
|
85
|
+
JMAP_OIDC_REDIRECT_URI=https://abc123.ngrok.io/callback
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Claude Desktop Configuration
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"mcpServers": {
|
|
93
|
+
"mcp-twake-mail": {
|
|
94
|
+
"command": "npx",
|
|
95
|
+
"args": ["-y", "mcp-twake-mail"],
|
|
96
|
+
"env": {
|
|
97
|
+
"JMAP_SESSION_URL": "https://jmap.example.com/jmap/session",
|
|
98
|
+
"JMAP_AUTH_METHOD": "oidc",
|
|
99
|
+
"JMAP_OIDC_ISSUER": "https://sso.example.com",
|
|
100
|
+
"JMAP_OIDC_CLIENT_ID": "mcp-twake-mail",
|
|
101
|
+
"JMAP_OIDC_SCOPE": "openid profile email offline_access"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Authentication Flow
|
|
109
|
+
|
|
110
|
+
### Initial Authentication
|
|
111
|
+
|
|
112
|
+
1. **Start mcp-twake-mail** — The MCP server starts
|
|
113
|
+
2. **Check for tokens** — Looks in `~/.mcp-twake-mail/tokens.json`
|
|
114
|
+
3. **If no valid token** — Opens browser for OIDC login
|
|
115
|
+
4. **User authenticates** — In browser with OIDC provider
|
|
116
|
+
5. **Callback received** — Server receives authorization code
|
|
117
|
+
6. **Token exchange** — Code exchanged for access + refresh tokens
|
|
118
|
+
7. **Tokens stored** — Saved securely with 0600 permissions
|
|
119
|
+
8. **JMAP session** — Access token used to authenticate with JMAP
|
|
120
|
+
|
|
121
|
+
### Token Refresh
|
|
122
|
+
|
|
123
|
+
Tokens are automatically refreshed:
|
|
124
|
+
|
|
125
|
+
1. **Before each request** — Token expiry is checked
|
|
126
|
+
2. **60-second buffer** — Refresh happens before expiry
|
|
127
|
+
3. **Refresh grant** — Refresh token exchanged for new access token
|
|
128
|
+
4. **New tokens stored** — Updated in `~/.mcp-twake-mail/tokens.json`
|
|
129
|
+
5. **Transparent to user** — No re-authentication needed
|
|
130
|
+
|
|
131
|
+
### Re-Authentication
|
|
132
|
+
|
|
133
|
+
If refresh fails (e.g., refresh token expired), you can re-authenticate:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx mcp-twake-mail auth
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
This triggers a new browser-based authentication flow.
|
|
140
|
+
|
|
141
|
+
## Token Storage
|
|
142
|
+
|
|
143
|
+
Tokens are stored in `~/.mcp-twake-mail/tokens.json`:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
|
|
148
|
+
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
|
|
149
|
+
"expiresAt": 1706623200000,
|
|
150
|
+
"tokenType": "Bearer"
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Security:**
|
|
155
|
+
- File permissions: `0600` (owner read/write only)
|
|
156
|
+
- Directory permissions: `0700`
|
|
157
|
+
- Never commit to version control
|
|
158
|
+
|
|
159
|
+
## PKCE Flow Details
|
|
160
|
+
|
|
161
|
+
mcp-twake-mail uses PKCE with S256 for security:
|
|
162
|
+
|
|
163
|
+
1. **Code Verifier** — Random 43-128 character string generated
|
|
164
|
+
2. **Code Challenge** — SHA-256 hash of verifier, base64url encoded
|
|
165
|
+
3. **Authorization Request** — Challenge sent to OIDC provider
|
|
166
|
+
4. **Token Request** — Verifier sent to prove possession
|
|
167
|
+
|
|
168
|
+
This prevents authorization code interception attacks.
|
|
169
|
+
|
|
170
|
+
## Provider-Specific Setup
|
|
171
|
+
|
|
172
|
+
### Keycloak
|
|
173
|
+
|
|
174
|
+
1. Create a new client in your realm
|
|
175
|
+
2. Set **Client type** to "OpenID Connect"
|
|
176
|
+
3. Enable **Standard flow** (Authorization Code)
|
|
177
|
+
4. Set **Valid redirect URIs** to `http://localhost:3000/callback`
|
|
178
|
+
5. Under **Capability config**, enable **Client authentication: Off** (public client)
|
|
179
|
+
6. Under **Login settings**, enable **Consent required: Off** (optional)
|
|
180
|
+
|
|
181
|
+
**Issuer URL:** `https://keycloak.example.com/realms/your-realm`
|
|
182
|
+
|
|
183
|
+
### Auth0
|
|
184
|
+
|
|
185
|
+
1. Create a new Application (Regular Web Application)
|
|
186
|
+
2. Set **Allowed Callback URLs** to `http://localhost:3000/callback`
|
|
187
|
+
3. Under **Advanced Settings > Grant Types**, enable "Authorization Code" and "Refresh Token"
|
|
188
|
+
4. Under **Advanced Settings > OAuth**, enable PKCE
|
|
189
|
+
|
|
190
|
+
**Issuer URL:** `https://your-tenant.auth0.com`
|
|
191
|
+
|
|
192
|
+
### Azure AD
|
|
193
|
+
|
|
194
|
+
1. Register a new application
|
|
195
|
+
2. Add **Redirect URI**: `http://localhost:3000/callback` (Web platform)
|
|
196
|
+
3. Under **API permissions**, add `openid`, `profile`, `email`, `offline_access`
|
|
197
|
+
4. Under **Authentication**, enable "Allow public client flows"
|
|
198
|
+
|
|
199
|
+
**Issuer URL:** `https://login.microsoftonline.com/{tenant-id}/v2.0`
|
|
200
|
+
|
|
201
|
+
### Okta
|
|
202
|
+
|
|
203
|
+
1. Create a new App Integration (OIDC - OpenID Connect)
|
|
204
|
+
2. Choose "Native Application" for PKCE support
|
|
205
|
+
3. Set **Sign-in redirect URIs** to `http://localhost:3000/callback`
|
|
206
|
+
4. Under **Assignments**, assign users or groups
|
|
207
|
+
|
|
208
|
+
**Issuer URL:** `https://your-org.okta.com`
|
|
209
|
+
|
|
210
|
+
## Troubleshooting
|
|
211
|
+
|
|
212
|
+
### "Invalid redirect_uri"
|
|
213
|
+
|
|
214
|
+
The redirect URI in your configuration must exactly match what's registered in your OIDC provider. Check for:
|
|
215
|
+
- Trailing slashes
|
|
216
|
+
- HTTP vs HTTPS
|
|
217
|
+
- Port numbers
|
|
218
|
+
- Path case sensitivity
|
|
219
|
+
|
|
220
|
+
### "Token refresh failed"
|
|
221
|
+
|
|
222
|
+
Possible causes:
|
|
223
|
+
1. Refresh token expired (re-authenticate with `npx mcp-twake-mail auth`)
|
|
224
|
+
2. `offline_access` scope not granted
|
|
225
|
+
3. OIDC provider configuration changed
|
|
226
|
+
|
|
227
|
+
### "PKCE validation failed"
|
|
228
|
+
|
|
229
|
+
Your OIDC provider may not support S256 PKCE. Check provider documentation and ensure:
|
|
230
|
+
- PKCE is enabled for the client
|
|
231
|
+
- S256 code challenge method is supported
|
|
232
|
+
|
|
233
|
+
### Browser Doesn't Open
|
|
234
|
+
|
|
235
|
+
If running in a headless environment:
|
|
236
|
+
1. Copy the authorization URL from the console
|
|
237
|
+
2. Open it in a browser on another machine
|
|
238
|
+
3. After authentication, copy the callback URL
|
|
239
|
+
4. The server will detect the callback automatically
|
|
240
|
+
|
|
241
|
+
### Token File Permissions
|
|
242
|
+
|
|
243
|
+
If you see permission errors:
|
|
244
|
+
```bash
|
|
245
|
+
chmod 600 ~/.mcp-twake-mail/tokens.json
|
|
246
|
+
chmod 700 ~/.mcp-twake-mail
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Security Considerations
|
|
250
|
+
|
|
251
|
+
1. **Never share tokens** — Access and refresh tokens grant full email access
|
|
252
|
+
2. **Secure token storage** — Use encrypted disk if possible
|
|
253
|
+
3. **Minimal scopes** — Only request scopes you need
|
|
254
|
+
4. **Token rotation** — Some providers rotate refresh tokens; mcp-twake-mail handles this
|
|
255
|
+
5. **Revoke on compromise** — If tokens are exposed, revoke them at your OIDC provider
|
|
256
|
+
|
|
257
|
+
## References
|
|
258
|
+
|
|
259
|
+
- [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) — OAuth 2.0 Authorization Framework
|
|
260
|
+
- [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636) — PKCE for OAuth 2.0
|
|
261
|
+
- [OpenID Connect Core](https://openid.net/specs/openid-connect-core-1_0.html) — OIDC Specification
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-twake-mail",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "MCP server for Twake.ai — integrate your sovereign JMAP email server with any MCP-compatible AI assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./build/index.js",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"build",
|
|
12
|
+
"docs",
|
|
12
13
|
"README.md",
|
|
13
14
|
"LICENSE"
|
|
14
15
|
],
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"@inquirer/prompts": "^8.2.0",
|
|
53
54
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
54
55
|
"commander": "^14.0.2",
|
|
56
|
+
"marked": "^17.0.1",
|
|
55
57
|
"oauth-callback": "^2.2.0",
|
|
56
58
|
"open": "^11.0.0",
|
|
57
59
|
"openid-client": "^6.8.1",
|