mcp-twake-mail 0.1.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.
Files changed (114) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +332 -0
  3. package/build/auth/index.d.ts +3 -0
  4. package/build/auth/index.js +4 -0
  5. package/build/auth/index.js.map +1 -0
  6. package/build/auth/oidc-flow.d.ts +47 -0
  7. package/build/auth/oidc-flow.js +146 -0
  8. package/build/auth/oidc-flow.js.map +1 -0
  9. package/build/auth/token-refresh.d.ts +56 -0
  10. package/build/auth/token-refresh.js +132 -0
  11. package/build/auth/token-refresh.js.map +1 -0
  12. package/build/auth/token-store.d.ts +33 -0
  13. package/build/auth/token-store.js +63 -0
  14. package/build/auth/token-store.js.map +1 -0
  15. package/build/cli/commands/auth.d.ts +5 -0
  16. package/build/cli/commands/auth.js +49 -0
  17. package/build/cli/commands/auth.js.map +1 -0
  18. package/build/cli/commands/check.d.ts +4 -0
  19. package/build/cli/commands/check.js +125 -0
  20. package/build/cli/commands/check.js.map +1 -0
  21. package/build/cli/commands/setup.d.ts +4 -0
  22. package/build/cli/commands/setup.js +172 -0
  23. package/build/cli/commands/setup.js.map +1 -0
  24. package/build/cli/index.d.ts +15 -0
  25. package/build/cli/index.js +56 -0
  26. package/build/cli/index.js.map +1 -0
  27. package/build/cli/prompts/setup-wizard.d.ts +38 -0
  28. package/build/cli/prompts/setup-wizard.js +121 -0
  29. package/build/cli/prompts/setup-wizard.js.map +1 -0
  30. package/build/config/__tests__/logger.test.d.ts +1 -0
  31. package/build/config/__tests__/logger.test.js +28 -0
  32. package/build/config/__tests__/logger.test.js.map +1 -0
  33. package/build/config/__tests__/schema.test.d.ts +1 -0
  34. package/build/config/__tests__/schema.test.js +101 -0
  35. package/build/config/__tests__/schema.test.js.map +1 -0
  36. package/build/config/logger.d.ts +3 -0
  37. package/build/config/logger.js +9 -0
  38. package/build/config/logger.js.map +1 -0
  39. package/build/config/schema.d.ts +28 -0
  40. package/build/config/schema.js +81 -0
  41. package/build/config/schema.js.map +1 -0
  42. package/build/errors.d.ts +34 -0
  43. package/build/errors.js +154 -0
  44. package/build/errors.js.map +1 -0
  45. package/build/errors.test.d.ts +1 -0
  46. package/build/errors.test.js +234 -0
  47. package/build/errors.test.js.map +1 -0
  48. package/build/index.d.ts +2 -0
  49. package/build/index.js +12 -0
  50. package/build/index.js.map +1 -0
  51. package/build/jmap/client.d.ts +96 -0
  52. package/build/jmap/client.js +267 -0
  53. package/build/jmap/client.js.map +1 -0
  54. package/build/mcp/server.d.ts +24 -0
  55. package/build/mcp/server.js +68 -0
  56. package/build/mcp/server.js.map +1 -0
  57. package/build/mcp/tools/attachment.d.ts +30 -0
  58. package/build/mcp/tools/attachment.js +246 -0
  59. package/build/mcp/tools/attachment.js.map +1 -0
  60. package/build/mcp/tools/attachment.test.d.ts +1 -0
  61. package/build/mcp/tools/attachment.test.js +457 -0
  62. package/build/mcp/tools/attachment.test.js.map +1 -0
  63. package/build/mcp/tools/email-operations.d.ts +10 -0
  64. package/build/mcp/tools/email-operations.js +828 -0
  65. package/build/mcp/tools/email-operations.js.map +1 -0
  66. package/build/mcp/tools/email-operations.test.d.ts +1 -0
  67. package/build/mcp/tools/email-operations.test.js +453 -0
  68. package/build/mcp/tools/email-operations.test.js.map +1 -0
  69. package/build/mcp/tools/email-sending.d.ts +10 -0
  70. package/build/mcp/tools/email-sending.js +682 -0
  71. package/build/mcp/tools/email-sending.js.map +1 -0
  72. package/build/mcp/tools/email.d.ts +10 -0
  73. package/build/mcp/tools/email.js +365 -0
  74. package/build/mcp/tools/email.js.map +1 -0
  75. package/build/mcp/tools/email.test.d.ts +1 -0
  76. package/build/mcp/tools/email.test.js +332 -0
  77. package/build/mcp/tools/email.test.js.map +1 -0
  78. package/build/mcp/tools/index.d.ts +14 -0
  79. package/build/mcp/tools/index.js +29 -0
  80. package/build/mcp/tools/index.js.map +1 -0
  81. package/build/mcp/tools/mailbox.d.ts +10 -0
  82. package/build/mcp/tools/mailbox.js +195 -0
  83. package/build/mcp/tools/mailbox.js.map +1 -0
  84. package/build/mcp/tools/mailbox.test.d.ts +1 -0
  85. package/build/mcp/tools/mailbox.test.js +231 -0
  86. package/build/mcp/tools/mailbox.test.js.map +1 -0
  87. package/build/mcp/tools/thread.d.ts +10 -0
  88. package/build/mcp/tools/thread.js +282 -0
  89. package/build/mcp/tools/thread.js.map +1 -0
  90. package/build/mcp/tools/thread.test.d.ts +1 -0
  91. package/build/mcp/tools/thread.test.js +384 -0
  92. package/build/mcp/tools/thread.test.js.map +1 -0
  93. package/build/transformers/__tests__/email.test.d.ts +1 -0
  94. package/build/transformers/__tests__/email.test.js +438 -0
  95. package/build/transformers/__tests__/email.test.js.map +1 -0
  96. package/build/transformers/__tests__/mailbox.test.d.ts +1 -0
  97. package/build/transformers/__tests__/mailbox.test.js +222 -0
  98. package/build/transformers/__tests__/mailbox.test.js.map +1 -0
  99. package/build/transformers/email.d.ts +76 -0
  100. package/build/transformers/email.js +138 -0
  101. package/build/transformers/email.js.map +1 -0
  102. package/build/transformers/index.d.ts +5 -0
  103. package/build/transformers/index.js +6 -0
  104. package/build/transformers/index.js.map +1 -0
  105. package/build/transformers/mailbox.d.ts +43 -0
  106. package/build/transformers/mailbox.js +70 -0
  107. package/build/transformers/mailbox.js.map +1 -0
  108. package/build/types/dto.d.ts +91 -0
  109. package/build/types/dto.js +9 -0
  110. package/build/types/dto.js.map +1 -0
  111. package/build/types/jmap.d.ts +110 -0
  112. package/build/types/jmap.js +5 -0
  113. package/build/types/jmap.js.map +1 -0
  114. package/package.json +71 -0
@@ -0,0 +1,154 @@
1
+ import { ZodError } from 'zod';
2
+ export class JMAPError extends Error {
3
+ type;
4
+ fix;
5
+ constructor(message, type, fix) {
6
+ super(message);
7
+ this.name = 'JMAPError';
8
+ this.type = type;
9
+ this.fix = fix;
10
+ }
11
+ /**
12
+ * Create a JMAPError for HTTP-level errors (4xx, 5xx responses)
13
+ */
14
+ static httpError(status, statusText) {
15
+ const message = `HTTP ${status}: ${statusText}`;
16
+ if (status === 401) {
17
+ return new JMAPError(message, 'unauthorized', 'Check your credentials. For basic auth: verify JMAP_USERNAME and JMAP_PASSWORD. For bearer: verify JMAP_TOKEN is valid.');
18
+ }
19
+ if (status === 403) {
20
+ return new JMAPError(message, 'forbidden', 'You do not have permission to access this resource. Check your account permissions.');
21
+ }
22
+ if (status === 404) {
23
+ return new JMAPError(message, 'notFound', 'The JMAP endpoint was not found. Verify JMAP_SESSION_URL is correct.');
24
+ }
25
+ if (status >= 500) {
26
+ return new JMAPError(message, 'serverError', 'The JMAP server encountered an error. Try again later or contact the server administrator.');
27
+ }
28
+ return new JMAPError(message, 'httpError', 'An HTTP error occurred. Check the server URL and try again.');
29
+ }
30
+ /**
31
+ * Create a JMAPError for JMAP method-level errors
32
+ */
33
+ static methodError(type, description) {
34
+ const message = description || `JMAP method error: ${type}`;
35
+ const fixes = {
36
+ stateMismatch: 'The state is stale. Refetch the data and try again.',
37
+ cannotCalculateChanges: 'State is too old. Perform a full sync instead of incremental.',
38
+ notFound: 'The requested item was not found. It may have been deleted.',
39
+ forbidden: 'You do not have permission for this operation.',
40
+ accountNotFound: 'The account ID is invalid. Refetch the session.',
41
+ noMailAccount: 'The server does not have a mail account. Check the JMAP server configuration.',
42
+ unknownCapability: 'The server does not support the requested capability.',
43
+ invalidArguments: 'The request arguments are invalid. Check the request parameters.',
44
+ };
45
+ const fix = fixes[type] || 'A JMAP error occurred. Check the error details and try again.';
46
+ return new JMAPError(message, type, fix);
47
+ }
48
+ /**
49
+ * Create a JMAPError for timeout errors
50
+ */
51
+ static timeout(operation) {
52
+ return new JMAPError(`${operation} timed out`, 'timeout', 'The operation took too long. Check your network connection and try again. If the issue persists, increase JMAP_REQUEST_TIMEOUT.');
53
+ }
54
+ /**
55
+ * Create a JMAPError for expired access token
56
+ */
57
+ static tokenExpired(refreshAvailable) {
58
+ if (refreshAvailable) {
59
+ return new JMAPError('Access token expired. Will attempt automatic refresh.', 'tokenExpired', 'The access token has expired. Automatic refresh will be attempted.');
60
+ }
61
+ return new JMAPError('Access token expired and no refresh token available. Re-authenticate using: npx mcp-twake-mail auth', 'tokenExpired', 'Your session has expired. Re-authenticate using: npx mcp-twake-mail auth');
62
+ }
63
+ /**
64
+ * Create a JMAPError for failed token refresh
65
+ */
66
+ static refreshFailed(reason) {
67
+ const message = reason ? `Token refresh failed: ${reason}` : 'Token refresh failed';
68
+ return new JMAPError(message, 'refreshFailed', 'Your session has expired. Re-authenticate using: npx mcp-twake-mail auth');
69
+ }
70
+ /**
71
+ * Create a JMAPError for OIDC flow errors
72
+ */
73
+ static oidcFlowError(stage, details) {
74
+ const message = details
75
+ ? `OIDC authentication failed at ${stage}: ${details}`
76
+ : `OIDC authentication failed at ${stage}`;
77
+ return new JMAPError(message, 'oidcError', 'Check your OIDC provider configuration. Verify JMAP_OIDC_ISSUER is correct and the provider supports PKCE.');
78
+ }
79
+ /**
80
+ * Create a JMAPError for missing stored tokens
81
+ */
82
+ static noStoredTokens() {
83
+ return new JMAPError('No stored authentication tokens found', 'noStoredTokens', 'Authenticate first using: npx mcp-twake-mail auth');
84
+ }
85
+ }
86
+ export function formatStartupError(error, sessionUrl) {
87
+ // Handle Zod validation errors
88
+ if (error instanceof ZodError) {
89
+ const issues = error.issues.map((issue) => {
90
+ const field = issue.path.join('.');
91
+ return ` ${field}: ${issue.message}`;
92
+ });
93
+ return [
94
+ 'Configuration validation failed:',
95
+ ...issues,
96
+ '',
97
+ 'Fix: Check your environment variables.',
98
+ 'For basic auth: JMAP_SESSION_URL, JMAP_USERNAME, JMAP_PASSWORD',
99
+ 'For bearer auth: JMAP_SESSION_URL, JMAP_AUTH_METHOD=bearer, JMAP_TOKEN',
100
+ 'For OIDC auth: JMAP_SESSION_URL, JMAP_AUTH_METHOD=oidc, JMAP_OIDC_ISSUER, JMAP_OIDC_CLIENT_ID',
101
+ ].join('\n');
102
+ }
103
+ const message = error.message.toLowerCase();
104
+ // Token expiration errors
105
+ if (message.includes('token') && message.includes('expired')) {
106
+ return [
107
+ 'Authentication token has expired.',
108
+ '',
109
+ 'Fix: Re-authenticate using: npx mcp-twake-mail auth',
110
+ ].join('\n');
111
+ }
112
+ // OIDC/OAuth errors
113
+ if (message.includes('oidc') || message.includes('oauth')) {
114
+ return [
115
+ 'OIDC authentication error.',
116
+ '',
117
+ 'Fix: Check your OIDC configuration:',
118
+ '- Verify JMAP_OIDC_ISSUER is correct and accessible',
119
+ '- Verify JMAP_OIDC_CLIENT_ID is valid',
120
+ '- Ensure the OIDC provider supports PKCE',
121
+ '',
122
+ 'Try re-authenticating: npx mcp-twake-mail auth',
123
+ ].join('\n');
124
+ }
125
+ // Authentication failures
126
+ if (message.includes('401') || message.includes('unauthorized')) {
127
+ return [
128
+ 'Authentication failed for JMAP server.',
129
+ '',
130
+ 'Fix: Verify your credentials are correct.',
131
+ 'If using basic auth: check JMAP_USERNAME and JMAP_PASSWORD.',
132
+ 'If using bearer: check JMAP_TOKEN is valid and not expired.',
133
+ 'If using OIDC: try re-authenticating with npx mcp-twake-mail auth',
134
+ ].join('\n');
135
+ }
136
+ // Timeout errors
137
+ if (message.includes('timeout')) {
138
+ const urlContext = sessionUrl ? ` ${sessionUrl}` : '';
139
+ return [
140
+ `Connection to${urlContext} timed out.`,
141
+ '',
142
+ 'Fix: Check the JMAP server is running and accessible.',
143
+ 'Try accessing the session URL in a browser to verify it responds.',
144
+ ].join('\n');
145
+ }
146
+ // Fallback
147
+ return [
148
+ `Unexpected error: ${error.message}`,
149
+ '',
150
+ 'Fix: Check your configuration and try again.',
151
+ 'Verify JMAP_SESSION_URL and authentication settings.',
152
+ ].join('\n');
153
+ }
154
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAE/B,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,IAAI,CAAS;IACb,GAAG,CAAS;IAEZ,YAAY,OAAe,EAAE,IAAY,EAAE,GAAW;QACpD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,MAAc,EAAE,UAAkB;QACjD,MAAM,OAAO,GAAG,QAAQ,MAAM,KAAK,UAAU,EAAE,CAAC;QAEhD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,IAAI,SAAS,CAClB,OAAO,EACP,cAAc,EACd,yHAAyH,CAC1H,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,IAAI,SAAS,CAClB,OAAO,EACP,WAAW,EACX,qFAAqF,CACtF,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,IAAI,SAAS,CAClB,OAAO,EACP,UAAU,EACV,sEAAsE,CACvE,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAClB,OAAO,IAAI,SAAS,CAClB,OAAO,EACP,aAAa,EACb,4FAA4F,CAC7F,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,SAAS,CAClB,OAAO,EACP,WAAW,EACX,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAY,EAAE,WAAoB;QACnD,MAAM,OAAO,GAAG,WAAW,IAAI,sBAAsB,IAAI,EAAE,CAAC;QAE5D,MAAM,KAAK,GAA2B;YACpC,aAAa,EAAE,qDAAqD;YACpE,sBAAsB,EAAE,+DAA+D;YACvF,QAAQ,EAAE,6DAA6D;YACvE,SAAS,EAAE,gDAAgD;YAC3D,eAAe,EAAE,iDAAiD;YAClE,aAAa,EAAE,+EAA+E;YAC9F,iBAAiB,EAAE,uDAAuD;YAC1E,gBAAgB,EAAE,kEAAkE;SACrF,CAAC;QAEF,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,+DAA+D,CAAC;QAE3F,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,SAAiB;QAC9B,OAAO,IAAI,SAAS,CAClB,GAAG,SAAS,YAAY,EACxB,SAAS,EACT,iIAAiI,CAClI,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,gBAAyB;QAC3C,IAAI,gBAAgB,EAAE,CAAC;YACrB,OAAO,IAAI,SAAS,CAClB,uDAAuD,EACvD,cAAc,EACd,oEAAoE,CACrE,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,SAAS,CAClB,qGAAqG,EACrG,cAAc,EACd,0EAA0E,CAC3E,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAe;QAClC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,yBAAyB,MAAM,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC;QACpF,OAAO,IAAI,SAAS,CAClB,OAAO,EACP,eAAe,EACf,0EAA0E,CAC3E,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAa,EAAE,OAAgB;QAClD,MAAM,OAAO,GAAG,OAAO;YACrB,CAAC,CAAC,iCAAiC,KAAK,KAAK,OAAO,EAAE;YACtD,CAAC,CAAC,iCAAiC,KAAK,EAAE,CAAC;QAC7C,OAAO,IAAI,SAAS,CAClB,OAAO,EACP,WAAW,EACX,4GAA4G,CAC7G,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,cAAc;QACnB,OAAO,IAAI,SAAS,CAClB,uCAAuC,EACvC,gBAAgB,EAChB,mDAAmD,CACpD,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAY,EAAE,UAAmB;IAClE,+BAA+B;IAC/B,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACxC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnC,OAAO,KAAK,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC;QACH,OAAO;YACL,kCAAkC;YAClC,GAAG,MAAM;YACT,EAAE;YACF,wCAAwC;YACxC,gEAAgE;YAChE,wEAAwE;YACxE,+FAA+F;SAChG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAE5C,0BAA0B;IAC1B,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7D,OAAO;YACL,mCAAmC;YACnC,EAAE;YACF,qDAAqD;SACtD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,oBAAoB;IACpB,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1D,OAAO;YACL,4BAA4B;YAC5B,EAAE;YACF,qCAAqC;YACrC,qDAAqD;YACrD,uCAAuC;YACvC,0CAA0C;YAC1C,EAAE;YACF,gDAAgD;SACjD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,0BAA0B;IAC1B,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAChE,OAAO;YACL,wCAAwC;YACxC,EAAE;YACF,2CAA2C;YAC3C,6DAA6D;YAC7D,6DAA6D;YAC7D,mEAAmE;SACpE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,iBAAiB;IACjB,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,OAAO;YACL,gBAAgB,UAAU,aAAa;YACvC,EAAE;YACF,uDAAuD;YACvD,mEAAmE;SACpE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,WAAW;IACX,OAAO;QACL,qBAAqB,KAAK,CAAC,OAAO,EAAE;QACpC,EAAE;QACF,8CAA8C;QAC9C,sDAAsD;KACvD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Tests for JMAPError class and formatStartupError function.
3
+ */
4
+ import { describe, it, expect } from 'vitest';
5
+ import { JMAPError, formatStartupError } from './errors.js';
6
+ import { z } from 'zod';
7
+ describe('JMAPError', () => {
8
+ describe('constructor', () => {
9
+ it('creates error with message, type, and fix', () => {
10
+ const error = new JMAPError('Test error', 'testType', 'Fix: do something');
11
+ expect(error.message).toBe('Test error');
12
+ expect(error.name).toBe('JMAPError');
13
+ expect(error.type).toBe('testType');
14
+ expect(error.fix).toBe('Fix: do something');
15
+ });
16
+ });
17
+ describe('httpError', () => {
18
+ it('creates 401 unauthorized error', () => {
19
+ const error = JMAPError.httpError(401, 'Unauthorized');
20
+ expect(error.message).toBe('HTTP 401: Unauthorized');
21
+ expect(error.type).toBe('unauthorized');
22
+ expect(error.fix).toContain('credentials');
23
+ });
24
+ it('creates 403 forbidden error', () => {
25
+ const error = JMAPError.httpError(403, 'Forbidden');
26
+ expect(error.message).toBe('HTTP 403: Forbidden');
27
+ expect(error.type).toBe('forbidden');
28
+ expect(error.fix).toContain('permission');
29
+ });
30
+ it('creates 404 not found error', () => {
31
+ const error = JMAPError.httpError(404, 'Not Found');
32
+ expect(error.message).toBe('HTTP 404: Not Found');
33
+ expect(error.type).toBe('notFound');
34
+ expect(error.fix).toContain('JMAP_SESSION_URL');
35
+ });
36
+ it('creates server error for 5xx status', () => {
37
+ const error = JMAPError.httpError(500, 'Internal Server Error');
38
+ expect(error.message).toBe('HTTP 500: Internal Server Error');
39
+ expect(error.type).toBe('serverError');
40
+ expect(error.fix).toContain('server');
41
+ });
42
+ it('creates generic http error for other status codes', () => {
43
+ const error = JMAPError.httpError(418, "I'm a teapot");
44
+ expect(error.message).toBe("HTTP 418: I'm a teapot");
45
+ expect(error.type).toBe('httpError');
46
+ expect(error.fix).toContain('HTTP error');
47
+ });
48
+ });
49
+ describe('methodError', () => {
50
+ it('creates error with description', () => {
51
+ const error = JMAPError.methodError('notFound', 'Email not found');
52
+ expect(error.message).toBe('Email not found');
53
+ expect(error.type).toBe('notFound');
54
+ expect(error.fix).toContain('not found');
55
+ });
56
+ it('creates error without description', () => {
57
+ const error = JMAPError.methodError('forbidden');
58
+ expect(error.message).toBe('JMAP method error: forbidden');
59
+ expect(error.type).toBe('forbidden');
60
+ expect(error.fix).toContain('permission');
61
+ });
62
+ it('handles stateMismatch error type', () => {
63
+ const error = JMAPError.methodError('stateMismatch');
64
+ expect(error.type).toBe('stateMismatch');
65
+ expect(error.fix).toContain('Refetch');
66
+ });
67
+ it('handles cannotCalculateChanges error type', () => {
68
+ const error = JMAPError.methodError('cannotCalculateChanges');
69
+ expect(error.type).toBe('cannotCalculateChanges');
70
+ expect(error.fix).toContain('full sync');
71
+ });
72
+ it('handles accountNotFound error type', () => {
73
+ const error = JMAPError.methodError('accountNotFound');
74
+ expect(error.type).toBe('accountNotFound');
75
+ expect(error.fix).toContain('Refetch the session');
76
+ });
77
+ it('handles unknownCapability error type', () => {
78
+ const error = JMAPError.methodError('unknownCapability');
79
+ expect(error.type).toBe('unknownCapability');
80
+ expect(error.fix).toContain('capability');
81
+ });
82
+ it('handles invalidArguments error type', () => {
83
+ const error = JMAPError.methodError('invalidArguments');
84
+ expect(error.type).toBe('invalidArguments');
85
+ expect(error.fix).toContain('arguments');
86
+ });
87
+ it('handles noMailAccount error type', () => {
88
+ const error = JMAPError.methodError('noMailAccount');
89
+ expect(error.type).toBe('noMailAccount');
90
+ expect(error.fix).toContain('mail account');
91
+ });
92
+ it('handles unknown error types with generic fix', () => {
93
+ const error = JMAPError.methodError('unknownType');
94
+ expect(error.type).toBe('unknownType');
95
+ expect(error.fix).toContain('JMAP error');
96
+ });
97
+ });
98
+ describe('timeout', () => {
99
+ it('creates timeout error with operation name', () => {
100
+ const error = JMAPError.timeout('fetchSession');
101
+ expect(error.message).toBe('fetchSession timed out');
102
+ expect(error.type).toBe('timeout');
103
+ expect(error.fix).toContain('JMAP_REQUEST_TIMEOUT');
104
+ });
105
+ });
106
+ describe('tokenExpired', () => {
107
+ it('creates error with refresh available', () => {
108
+ const error = JMAPError.tokenExpired(true);
109
+ expect(error.message).toContain('automatic refresh');
110
+ expect(error.type).toBe('tokenExpired');
111
+ expect(error.fix).toContain('Automatic');
112
+ });
113
+ it('creates error without refresh available', () => {
114
+ const error = JMAPError.tokenExpired(false);
115
+ expect(error.message).toContain('Re-authenticate');
116
+ expect(error.type).toBe('tokenExpired');
117
+ expect(error.fix).toContain('Re-authenticate');
118
+ });
119
+ });
120
+ describe('refreshFailed', () => {
121
+ it('creates error with reason', () => {
122
+ const error = JMAPError.refreshFailed('Invalid refresh token');
123
+ expect(error.message).toBe('Token refresh failed: Invalid refresh token');
124
+ expect(error.type).toBe('refreshFailed');
125
+ expect(error.fix).toContain('Re-authenticate');
126
+ });
127
+ it('creates error without reason', () => {
128
+ const error = JMAPError.refreshFailed();
129
+ expect(error.message).toBe('Token refresh failed');
130
+ expect(error.type).toBe('refreshFailed');
131
+ });
132
+ });
133
+ describe('oidcFlowError', () => {
134
+ it('creates error with details', () => {
135
+ const error = JMAPError.oidcFlowError('discovery', 'Issuer not found');
136
+ expect(error.message).toBe('OIDC authentication failed at discovery: Issuer not found');
137
+ expect(error.type).toBe('oidcError');
138
+ expect(error.fix).toContain('OIDC');
139
+ });
140
+ it('creates error without details', () => {
141
+ const error = JMAPError.oidcFlowError('token_exchange');
142
+ expect(error.message).toBe('OIDC authentication failed at token_exchange');
143
+ expect(error.type).toBe('oidcError');
144
+ });
145
+ });
146
+ describe('noStoredTokens', () => {
147
+ it('creates error for missing tokens', () => {
148
+ const error = JMAPError.noStoredTokens();
149
+ expect(error.message).toContain('No stored');
150
+ expect(error.type).toBe('noStoredTokens');
151
+ expect(error.fix).toContain('npx mcp-twake-mail auth');
152
+ });
153
+ });
154
+ });
155
+ describe('formatStartupError', () => {
156
+ describe('Zod validation errors', () => {
157
+ it('formats ZodError with field details', () => {
158
+ const schema = z.object({
159
+ JMAP_SESSION_URL: z.string().url(),
160
+ JMAP_USERNAME: z.string().min(1),
161
+ });
162
+ try {
163
+ schema.parse({ JMAP_SESSION_URL: 'invalid', JMAP_USERNAME: '' });
164
+ }
165
+ catch (error) {
166
+ const formatted = formatStartupError(error);
167
+ expect(formatted).toContain('Configuration validation failed');
168
+ expect(formatted).toContain('JMAP_SESSION_URL');
169
+ expect(formatted).toContain('JMAP_USERNAME');
170
+ expect(formatted).toContain('environment variables');
171
+ }
172
+ });
173
+ });
174
+ describe('token expiration errors', () => {
175
+ it('formats token expired error', () => {
176
+ const error = new Error('Access token has expired');
177
+ const formatted = formatStartupError(error);
178
+ expect(formatted).toContain('Authentication token has expired');
179
+ expect(formatted).toContain('npx mcp-twake-mail auth');
180
+ });
181
+ });
182
+ describe('OIDC/OAuth errors', () => {
183
+ it('formats OIDC error', () => {
184
+ const error = new Error('OIDC discovery failed');
185
+ const formatted = formatStartupError(error);
186
+ expect(formatted).toContain('OIDC authentication error');
187
+ expect(formatted).toContain('JMAP_OIDC_ISSUER');
188
+ expect(formatted).toContain('JMAP_OIDC_CLIENT_ID');
189
+ });
190
+ it('formats OAuth error', () => {
191
+ const error = new Error('OAuth token exchange failed');
192
+ const formatted = formatStartupError(error);
193
+ expect(formatted).toContain('OIDC authentication error');
194
+ });
195
+ });
196
+ describe('authentication failures', () => {
197
+ it('formats 401 error', () => {
198
+ const error = new Error('HTTP 401 Unauthorized');
199
+ const formatted = formatStartupError(error);
200
+ expect(formatted).toContain('Authentication failed');
201
+ expect(formatted).toContain('JMAP_USERNAME');
202
+ expect(formatted).toContain('JMAP_PASSWORD');
203
+ });
204
+ it('formats unauthorized error', () => {
205
+ const error = new Error('Request unauthorized');
206
+ const formatted = formatStartupError(error);
207
+ expect(formatted).toContain('Authentication failed');
208
+ });
209
+ });
210
+ describe('timeout errors', () => {
211
+ it('formats timeout error', () => {
212
+ const error = new Error('Connection timeout');
213
+ const formatted = formatStartupError(error, 'https://jmap.example.com/.well-known/jmap');
214
+ expect(formatted).toContain('timed out');
215
+ expect(formatted).toContain('https://jmap.example.com/.well-known/jmap');
216
+ });
217
+ it('formats timeout error without URL', () => {
218
+ const error = new Error('Request timeout');
219
+ const formatted = formatStartupError(error);
220
+ expect(formatted).toContain('timed out');
221
+ expect(formatted).toContain('JMAP server');
222
+ });
223
+ });
224
+ describe('fallback errors', () => {
225
+ it('formats unknown errors with generic message', () => {
226
+ const error = new Error('Something went wrong');
227
+ const formatted = formatStartupError(error);
228
+ expect(formatted).toContain('Unexpected error');
229
+ expect(formatted).toContain('Something went wrong');
230
+ expect(formatted).toContain('configuration');
231
+ });
232
+ });
233
+ });
234
+ //# sourceMappingURL=errors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../src/errors.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/build/index.js ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Entry point for mcp-twake-mail.
4
+ * Routes to CLI commands or MCP server based on arguments.
5
+ */
6
+ import { runCLI } from './cli/index.js';
7
+ runCLI().catch((error) => {
8
+ // Log to stderr (NEVER stdout - may be reserved for MCP JSON-RPC)
9
+ process.stderr.write(`Fatal error: ${error instanceof Error ? error.message : String(error)}\n`);
10
+ process.exit(1);
11
+ });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACvB,kEAAkE;IAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * JMAP client with session management, authentication, and request handling.
3
+ * Implements JMAP Core (RFC 8620) patterns.
4
+ */
5
+ import type { Config } from '../config/schema.js';
6
+ import type { Logger } from '../config/logger.js';
7
+ import type { JMAPCapabilities, JMAPMethodCall, JMAPMethodResponse, JMAPResponse, JMAPErrorResponse } from '../types/jmap.js';
8
+ /** Extracted session data from JMAP session response */
9
+ export interface JMAPSession {
10
+ apiUrl: string;
11
+ downloadUrl: string;
12
+ accountId: string;
13
+ capabilities: JMAPCapabilities;
14
+ state: string;
15
+ }
16
+ /**
17
+ * JMAP client for interacting with JMAP mail servers.
18
+ * Handles authentication, session management, and request batching.
19
+ */
20
+ export declare class JMAPClient {
21
+ private session;
22
+ private readonly config;
23
+ private readonly logger;
24
+ private readonly stateTracker;
25
+ private readonly tokenRefresher;
26
+ constructor(config: Config, logger: Logger);
27
+ /**
28
+ * Generate authentication headers based on configured auth method.
29
+ * For OIDC, automatically refreshes tokens if needed via TokenRefresher.
30
+ * @returns Headers object with Authorization and Content-Type
31
+ */
32
+ private getAuthHeaders;
33
+ /**
34
+ * Fetch JMAP session from the server.
35
+ * Discovers apiUrl, accountId, and capabilities.
36
+ * @returns JMAPSession with extracted session data
37
+ * @throws JMAPError if session fetch fails or no mail account found
38
+ */
39
+ fetchSession(): Promise<JMAPSession>;
40
+ /**
41
+ * Get the current session.
42
+ * @returns JMAPSession
43
+ * @throws JMAPError if session not initialized
44
+ */
45
+ getSession(): JMAPSession;
46
+ /**
47
+ * Make a batched JMAP request with multiple method calls.
48
+ * @param methodCalls Array of method calls to execute
49
+ * @param using Optional array of capability URIs (defaults to core + mail)
50
+ * @returns JMAPResponse with method responses
51
+ * @throws JMAPError on HTTP errors or timeouts
52
+ */
53
+ request(methodCalls: JMAPMethodCall[], using?: string[]): Promise<JMAPResponse>;
54
+ /**
55
+ * Parse a method response and extract success/error status.
56
+ * @param response The method response tuple
57
+ * @returns Object with success flag and data or error
58
+ */
59
+ parseMethodResponse(response: JMAPMethodResponse): {
60
+ success: boolean;
61
+ data?: Record<string, unknown>;
62
+ error?: JMAPErrorResponse;
63
+ };
64
+ /**
65
+ * Extract state from method response and update tracker.
66
+ * @param response The method response tuple
67
+ */
68
+ private extractAndUpdateState;
69
+ /**
70
+ * Update tracked state for an object type.
71
+ * @param type Object type (e.g., 'Email', 'Mailbox')
72
+ * @param state New state string
73
+ */
74
+ updateState(type: string, state: string): void;
75
+ /**
76
+ * Get tracked state for an object type.
77
+ * @param type Object type (e.g., 'Email', 'Mailbox')
78
+ * @returns State string or undefined if not tracked
79
+ */
80
+ getState(type: string): string | undefined;
81
+ /**
82
+ * Clear tracked state.
83
+ * @param type Optional object type to clear. If not provided, clears all state.
84
+ */
85
+ clearState(type?: string): void;
86
+ /**
87
+ * Download a blob (attachment) from the JMAP server.
88
+ * Uses the downloadUrl template from the session.
89
+ * @param blobId The blob ID to download
90
+ * @param name Optional filename for the download
91
+ * @param type Optional MIME type
92
+ * @returns ArrayBuffer containing the blob data
93
+ * @throws JMAPError if download fails
94
+ */
95
+ downloadBlob(blobId: string, name?: string, type?: string): Promise<ArrayBuffer>;
96
+ }