@leanmcp/auth 0.4.3 → 0.4.4

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 (3) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +397 -396
  3. package/package.json +121 -121
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 LeanMCP Contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 LeanMCP Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,396 +1,397 @@
1
- <p align="center">
2
- <img
3
- src="https://raw.githubusercontent.com/LeanMCP/leanmcp-sdk/refs/heads/main/assets/logo.png"
4
- alt="LeanMCP Logo"
5
- width="400"
6
- />
7
- </p>
8
-
9
- <p align="center">
10
- <strong>@leanmcp/auth</strong><br/>
11
- Token-based authentication decorators and multi-provider support for MCP tools.
12
- </p>
13
-
14
- <p align="center">
15
- <a href="https://www.npmjs.com/package/@leanmcp/auth">
16
- <img src="https://img.shields.io/npm/v/@leanmcp/auth" alt="npm version" />
17
- </a>
18
- <a href="https://www.npmjs.com/package/@leanmcp/auth">
19
- <img src="https://img.shields.io/npm/dm/@leanmcp/auth" alt="npm downloads" />
20
- </a>
21
- <a href="https://docs.leanmcp.com/sdk/auth">
22
- <img src="https://img.shields.io/badge/Docs-leanmcp-0A66C2?" />
23
- </a>
24
- <a href="https://discord.com/invite/DsRcA3GwPy">
25
- <img src="https://img.shields.io/badge/Discord-Join-5865F2?logo=discord&logoColor=white" />
26
- </a>
27
- <a href="https://x.com/LeanMcp">
28
- <img src="https://img.shields.io/badge/@LeanMCP-f5f5f5?logo=x&logoColor=000000" />
29
- </a>
30
- </p>
31
-
32
- ## Features
33
-
34
- - **@Authenticated Decorator** — Protect tools, prompts, and resources with a simple decorator
35
- - **Multi-Provider Support** — AWS Cognito, Clerk, Auth0, and LeanMCP providers
36
- - **Automatic authUser** — Decoded user info injected as global `authUser` variable
37
- - **Concurrency Safe** — Uses AsyncLocalStorage for request-isolated context
38
- - **Method or Class-Level** — Apply to individual methods or entire services
39
- - **OAuth & Session Modes** — Support for both session-based and OAuth refresh token flows
40
-
41
- ## Installation
42
-
43
- ```bash
44
- npm install @leanmcp/auth @leanmcp/core
45
- ```
46
-
47
- ### Provider Dependencies
48
-
49
- **AWS Cognito:**
50
- ```bash
51
- npm install @aws-sdk/client-cognito-identity-provider axios jsonwebtoken jwk-to-pem
52
- ```
53
-
54
- **Clerk:**
55
- ```bash
56
- npm install axios jsonwebtoken jwk-to-pem
57
- ```
58
-
59
- **Auth0:**
60
- ```bash
61
- npm install axios jsonwebtoken jwk-to-pem
62
- ```
63
-
64
- ## Quick Start
65
-
66
- ### 1. Initialize Auth Provider
67
-
68
- ```typescript
69
- import { AuthProvider } from "@leanmcp/auth";
70
-
71
- const authProvider = new AuthProvider('cognito', {
72
- region: 'us-east-1',
73
- userPoolId: 'us-east-1_XXXXXXXXX',
74
- clientId: 'your-client-id'
75
- });
76
-
77
- await authProvider.init();
78
- ```
79
-
80
- ### 2. Protect Methods with @Authenticated
81
-
82
- ```typescript
83
- import { Tool } from "@leanmcp/core";
84
- import { Authenticated } from "@leanmcp/auth";
85
-
86
- export class SentimentService {
87
- @Tool({ description: 'Analyze sentiment (requires auth)' })
88
- @Authenticated(authProvider)
89
- async analyzeSentiment(input: { text: string }) {
90
- // authUser is automatically available with user info
91
- console.log('User ID:', authUser.sub);
92
- console.log('Email:', authUser.email);
93
-
94
- return {
95
- sentiment: 'positive',
96
- score: 0.8,
97
- analyzedBy: authUser.sub
98
- };
99
- }
100
-
101
- // Public method - no authentication
102
- @Tool({ description: 'Get categories (public)' })
103
- async getCategories() {
104
- return { categories: ['positive', 'negative', 'neutral'] };
105
- }
106
- }
107
- ```
108
-
109
- ### 3. Protect Entire Service
110
-
111
- ```typescript
112
- // All methods in this class require authentication
113
- @Authenticated(authProvider)
114
- export class SecureService {
115
- @Tool({ description: 'Protected tool' })
116
- async protectedTool(input: { data: string }) {
117
- // authUser is available in all methods
118
- return { data: input.data, userId: authUser.sub };
119
- }
120
- }
121
- ```
122
-
123
- ---
124
-
125
- ## The authUser Variable
126
-
127
- When using `@Authenticated`, a global `authUser` variable is automatically injected containing the decoded JWT payload:
128
-
129
- ```typescript
130
- @Tool({ description: 'Create post' })
131
- @Authenticated(authProvider)
132
- async createPost(input: { title: string, content: string }) {
133
- return {
134
- id: generateId(),
135
- title: input.title,
136
- content: input.content,
137
- authorId: authUser.sub,
138
- authorEmail: authUser.email
139
- };
140
- }
141
- ```
142
-
143
- ### Provider-Specific User Data
144
-
145
- **AWS Cognito:**
146
- ```typescript
147
- {
148
- sub: 'user-uuid',
149
- email: 'user@example.com',
150
- email_verified: true,
151
- 'cognito:username': 'username',
152
- 'cognito:groups': ['admin', 'users']
153
- }
154
- ```
155
-
156
- **Clerk:**
157
- ```typescript
158
- {
159
- sub: 'user_2abc123xyz',
160
- userId: 'user_2abc123xyz',
161
- email: 'user@example.com',
162
- firstName: 'John',
163
- lastName: 'Doe',
164
- imageUrl: 'https://img.clerk.com/...'
165
- }
166
- ```
167
-
168
- **Auth0:**
169
- ```typescript
170
- {
171
- sub: 'auth0|507f1f77bcf86cd799439011',
172
- email: 'user@example.com',
173
- email_verified: true,
174
- name: 'John Doe',
175
- picture: 'https://s.gravatar.com/avatar/...'
176
- }
177
- ```
178
-
179
- ### Controlling User Fetch
180
-
181
- ```typescript
182
- // Fetch user info (default)
183
- @Authenticated(authProvider, { getUser: true })
184
- async withUserInfo(input: any) {
185
- console.log(authUser); // User data available
186
- }
187
-
188
- // Only verify token, skip user fetch (faster)
189
- @Authenticated(authProvider, { getUser: false })
190
- async tokenOnlyValidation(input: any) {
191
- // authUser is undefined
192
- }
193
- ```
194
-
195
- ---
196
-
197
- ## Supported Providers
198
-
199
- ### AWS Cognito
200
-
201
- ```typescript
202
- const authProvider = new AuthProvider('cognito', {
203
- region: 'us-east-1',
204
- userPoolId: 'us-east-1_XXXXXXXXX',
205
- clientId: 'your-client-id'
206
- });
207
- await authProvider.init();
208
- ```
209
-
210
- **Environment Variables:**
211
- ```bash
212
- AWS_REGION=us-east-1
213
- COGNITO_USER_POOL_ID=us-east-1_XXXXXXXXX
214
- COGNITO_CLIENT_ID=your-client-id
215
- ```
216
-
217
- ### Clerk
218
-
219
- ```typescript
220
- // Session Mode (default)
221
- const authProvider = new AuthProvider('clerk', {
222
- frontendApi: 'your-frontend-api.clerk.accounts.dev',
223
- secretKey: 'sk_test_...'
224
- });
225
-
226
- // OAuth Mode (with refresh tokens)
227
- const authProvider = new AuthProvider('clerk', {
228
- frontendApi: 'your-frontend-api.clerk.accounts.dev',
229
- secretKey: 'sk_test_...',
230
- clientId: 'your-oauth-client-id',
231
- clientSecret: 'your-oauth-client-secret',
232
- redirectUri: 'https://yourapp.com/callback'
233
- });
234
-
235
- await authProvider.init();
236
- ```
237
-
238
- ### Auth0
239
-
240
- ```typescript
241
- const authProvider = new AuthProvider('auth0', {
242
- domain: 'your-tenant.auth0.com',
243
- clientId: 'your-client-id',
244
- clientSecret: 'your-client-secret',
245
- audience: 'https://your-api-identifier'
246
- });
247
- await authProvider.init();
248
- ```
249
-
250
- ### LeanMCP
251
-
252
- For LeanMCP platform deployments with user secrets support:
253
-
254
- ```typescript
255
- const authProvider = new AuthProvider('leanmcp', {
256
- apiKey: 'your-leanmcp-api-key'
257
- });
258
- await authProvider.init();
259
- ```
260
-
261
- ---
262
-
263
- ## Client Usage
264
-
265
- Authentication tokens are passed via the `_meta` field following MCP protocol standards:
266
-
267
- ```typescript
268
- await mcpClient.callTool({
269
- name: "analyzeSentiment",
270
- arguments: { text: "Hello world" },
271
- _meta: {
272
- authorization: {
273
- type: "bearer",
274
- token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
275
- }
276
- }
277
- });
278
- ```
279
-
280
- ---
281
-
282
- ## Error Handling
283
-
284
- ```typescript
285
- import { AuthenticationError } from "@leanmcp/auth";
286
-
287
- try {
288
- await service.protectedMethod({ text: "test" });
289
- } catch (error) {
290
- if (error instanceof AuthenticationError) {
291
- switch (error.code) {
292
- case 'MISSING_TOKEN':
293
- console.log('No token provided');
294
- break;
295
- case 'INVALID_TOKEN':
296
- console.log('Token is invalid or expired');
297
- break;
298
- case 'VERIFICATION_FAILED':
299
- console.log('Verification failed:', error.message);
300
- break;
301
- }
302
- }
303
- }
304
- ```
305
-
306
- ---
307
-
308
- ## API Reference
309
-
310
- ### AuthProvider
311
-
312
- ```typescript
313
- class AuthProvider {
314
- constructor(provider: string, config: any);
315
- async init(config?: any): Promise<void>;
316
- async verifyToken(token: string): Promise<boolean>;
317
- async refreshToken(refreshToken: string): Promise<any>;
318
- async getUser(token: string): Promise<any>;
319
- getProviderType(): string;
320
- }
321
- ```
322
-
323
- ### @Authenticated Decorator
324
-
325
- ```typescript
326
- function Authenticated(
327
- authProvider: AuthProvider,
328
- options?: AuthenticatedOptions
329
- ): ClassDecorator | MethodDecorator;
330
-
331
- interface AuthenticatedOptions {
332
- getUser?: boolean; // Default: true
333
- projectId?: string; // For LeanMCP user secrets
334
- }
335
- ```
336
-
337
- ### AuthenticationError
338
-
339
- ```typescript
340
- class AuthenticationError extends Error {
341
- code: 'MISSING_TOKEN' | 'INVALID_TOKEN' | 'VERIFICATION_FAILED';
342
- constructor(message: string, code: string);
343
- }
344
- ```
345
-
346
- ### Helper Functions
347
-
348
- ```typescript
349
- // Check if authentication is required
350
- function isAuthenticationRequired(target: any): boolean;
351
-
352
- // Get auth provider for method/class
353
- function getAuthProvider(target: any): AuthProviderBase | undefined;
354
-
355
- // Get current authenticated user
356
- function getAuthUser(): any;
357
- ```
358
-
359
- ---
360
-
361
- ## Best Practices
362
-
363
- ### Security
364
- - Always use HTTPS in production
365
- - Store tokens securely (keychain, encrypted storage)
366
- - Implement token refresh before expiration
367
- - Add rate limiting to protect against brute force
368
-
369
- ### Configuration
370
- - Use environment variables for credentials
371
- - Never hardcode secrets in code
372
- - Use `_meta` for auth, not business arguments
373
-
374
- ### Performance
375
- - Use `getUser: false` when you only need token validation
376
- - JWKS keys are cached automatically for performance
377
-
378
- ---
379
-
380
- ## Documentation
381
-
382
- - [Full Documentation](https://docs.leanmcp.com/sdk/auth)
383
-
384
- ## Related Packages
385
-
386
- - [@leanmcp/core](https://www.npmjs.com/package/@leanmcp/core) — Core decorators and server functionality
387
- - [@leanmcp/env-injection](https://www.npmjs.com/package/@leanmcp/env-injection) — Environment variable injection for user secrets
388
-
389
- ## Links
390
-
391
- - [GitHub Repository](https://github.com/LeanMCP/leanmcp-sdk)
392
- - [NPM Package](https://www.npmjs.com/package/@leanmcp/auth)
393
-
394
- ## License
395
-
396
- MIT
1
+ <p align="center">
2
+ <img
3
+ src="https://raw.githubusercontent.com/LeanMCP/leanmcp-sdk/refs/heads/main/assets/logo.png"
4
+ alt="LeanMCP Logo"
5
+ width="400"
6
+ />
7
+ </p>
8
+
9
+ <p align="center">
10
+ <strong>@leanmcp/auth</strong><br/>
11
+ Token-based authentication decorators and multi-provider support for MCP tools.
12
+ </p>
13
+
14
+ <p align="center">
15
+ <a href="https://www.npmjs.com/package/@leanmcp/auth">
16
+ <img src="https://img.shields.io/npm/v/@leanmcp/auth" alt="npm version" />
17
+ </a>
18
+ <a href="https://www.npmjs.com/package/@leanmcp/auth">
19
+ <img src="https://img.shields.io/npm/dm/@leanmcp/auth" alt="npm downloads" />
20
+ </a>
21
+ <a href="https://docs.leanmcp.com/sdk/auth">
22
+ <img src="https://img.shields.io/badge/Docs-leanmcp-0A66C2?" />
23
+ </a>
24
+ <a href="https://discord.com/invite/DsRcA3GwPy">
25
+ <img src="https://img.shields.io/badge/Discord-Join-5865F2?logo=discord&logoColor=white" />
26
+ </a>
27
+ <a href="https://x.com/LeanMcp">
28
+ <img src="https://img.shields.io/badge/@LeanMCP-f5f5f5?logo=x&logoColor=000000" />
29
+ </a>
30
+ <a href="https://deepwiki.com/LeanMCP/leanmcp-sdk"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
31
+ </p>
32
+
33
+ ## Features
34
+
35
+ - **@Authenticated Decorator** — Protect tools, prompts, and resources with a simple decorator
36
+ - **Multi-Provider Support** — AWS Cognito, Clerk, Auth0, and LeanMCP providers
37
+ - **Automatic authUser** — Decoded user info injected as global `authUser` variable
38
+ - **Concurrency Safe** — Uses AsyncLocalStorage for request-isolated context
39
+ - **Method or Class-Level** — Apply to individual methods or entire services
40
+ - **OAuth & Session Modes** — Support for both session-based and OAuth refresh token flows
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ npm install @leanmcp/auth @leanmcp/core
46
+ ```
47
+
48
+ ### Provider Dependencies
49
+
50
+ **AWS Cognito:**
51
+ ```bash
52
+ npm install @aws-sdk/client-cognito-identity-provider axios jsonwebtoken jwk-to-pem
53
+ ```
54
+
55
+ **Clerk:**
56
+ ```bash
57
+ npm install axios jsonwebtoken jwk-to-pem
58
+ ```
59
+
60
+ **Auth0:**
61
+ ```bash
62
+ npm install axios jsonwebtoken jwk-to-pem
63
+ ```
64
+
65
+ ## Quick Start
66
+
67
+ ### 1. Initialize Auth Provider
68
+
69
+ ```typescript
70
+ import { AuthProvider } from "@leanmcp/auth";
71
+
72
+ const authProvider = new AuthProvider('cognito', {
73
+ region: 'us-east-1',
74
+ userPoolId: 'us-east-1_XXXXXXXXX',
75
+ clientId: 'your-client-id'
76
+ });
77
+
78
+ await authProvider.init();
79
+ ```
80
+
81
+ ### 2. Protect Methods with @Authenticated
82
+
83
+ ```typescript
84
+ import { Tool } from "@leanmcp/core";
85
+ import { Authenticated } from "@leanmcp/auth";
86
+
87
+ export class SentimentService {
88
+ @Tool({ description: 'Analyze sentiment (requires auth)' })
89
+ @Authenticated(authProvider)
90
+ async analyzeSentiment(input: { text: string }) {
91
+ // authUser is automatically available with user info
92
+ console.log('User ID:', authUser.sub);
93
+ console.log('Email:', authUser.email);
94
+
95
+ return {
96
+ sentiment: 'positive',
97
+ score: 0.8,
98
+ analyzedBy: authUser.sub
99
+ };
100
+ }
101
+
102
+ // Public method - no authentication
103
+ @Tool({ description: 'Get categories (public)' })
104
+ async getCategories() {
105
+ return { categories: ['positive', 'negative', 'neutral'] };
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### 3. Protect Entire Service
111
+
112
+ ```typescript
113
+ // All methods in this class require authentication
114
+ @Authenticated(authProvider)
115
+ export class SecureService {
116
+ @Tool({ description: 'Protected tool' })
117
+ async protectedTool(input: { data: string }) {
118
+ // authUser is available in all methods
119
+ return { data: input.data, userId: authUser.sub };
120
+ }
121
+ }
122
+ ```
123
+
124
+ ---
125
+
126
+ ## The authUser Variable
127
+
128
+ When using `@Authenticated`, a global `authUser` variable is automatically injected containing the decoded JWT payload:
129
+
130
+ ```typescript
131
+ @Tool({ description: 'Create post' })
132
+ @Authenticated(authProvider)
133
+ async createPost(input: { title: string, content: string }) {
134
+ return {
135
+ id: generateId(),
136
+ title: input.title,
137
+ content: input.content,
138
+ authorId: authUser.sub,
139
+ authorEmail: authUser.email
140
+ };
141
+ }
142
+ ```
143
+
144
+ ### Provider-Specific User Data
145
+
146
+ **AWS Cognito:**
147
+ ```typescript
148
+ {
149
+ sub: 'user-uuid',
150
+ email: 'user@example.com',
151
+ email_verified: true,
152
+ 'cognito:username': 'username',
153
+ 'cognito:groups': ['admin', 'users']
154
+ }
155
+ ```
156
+
157
+ **Clerk:**
158
+ ```typescript
159
+ {
160
+ sub: 'user_2abc123xyz',
161
+ userId: 'user_2abc123xyz',
162
+ email: 'user@example.com',
163
+ firstName: 'John',
164
+ lastName: 'Doe',
165
+ imageUrl: 'https://img.clerk.com/...'
166
+ }
167
+ ```
168
+
169
+ **Auth0:**
170
+ ```typescript
171
+ {
172
+ sub: 'auth0|507f1f77bcf86cd799439011',
173
+ email: 'user@example.com',
174
+ email_verified: true,
175
+ name: 'John Doe',
176
+ picture: 'https://s.gravatar.com/avatar/...'
177
+ }
178
+ ```
179
+
180
+ ### Controlling User Fetch
181
+
182
+ ```typescript
183
+ // Fetch user info (default)
184
+ @Authenticated(authProvider, { getUser: true })
185
+ async withUserInfo(input: any) {
186
+ console.log(authUser); // User data available
187
+ }
188
+
189
+ // Only verify token, skip user fetch (faster)
190
+ @Authenticated(authProvider, { getUser: false })
191
+ async tokenOnlyValidation(input: any) {
192
+ // authUser is undefined
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Supported Providers
199
+
200
+ ### AWS Cognito
201
+
202
+ ```typescript
203
+ const authProvider = new AuthProvider('cognito', {
204
+ region: 'us-east-1',
205
+ userPoolId: 'us-east-1_XXXXXXXXX',
206
+ clientId: 'your-client-id'
207
+ });
208
+ await authProvider.init();
209
+ ```
210
+
211
+ **Environment Variables:**
212
+ ```bash
213
+ AWS_REGION=us-east-1
214
+ COGNITO_USER_POOL_ID=us-east-1_XXXXXXXXX
215
+ COGNITO_CLIENT_ID=your-client-id
216
+ ```
217
+
218
+ ### Clerk
219
+
220
+ ```typescript
221
+ // Session Mode (default)
222
+ const authProvider = new AuthProvider('clerk', {
223
+ frontendApi: 'your-frontend-api.clerk.accounts.dev',
224
+ secretKey: 'sk_test_...'
225
+ });
226
+
227
+ // OAuth Mode (with refresh tokens)
228
+ const authProvider = new AuthProvider('clerk', {
229
+ frontendApi: 'your-frontend-api.clerk.accounts.dev',
230
+ secretKey: 'sk_test_...',
231
+ clientId: 'your-oauth-client-id',
232
+ clientSecret: 'your-oauth-client-secret',
233
+ redirectUri: 'https://yourapp.com/callback'
234
+ });
235
+
236
+ await authProvider.init();
237
+ ```
238
+
239
+ ### Auth0
240
+
241
+ ```typescript
242
+ const authProvider = new AuthProvider('auth0', {
243
+ domain: 'your-tenant.auth0.com',
244
+ clientId: 'your-client-id',
245
+ clientSecret: 'your-client-secret',
246
+ audience: 'https://your-api-identifier'
247
+ });
248
+ await authProvider.init();
249
+ ```
250
+
251
+ ### LeanMCP
252
+
253
+ For LeanMCP platform deployments with user secrets support:
254
+
255
+ ```typescript
256
+ const authProvider = new AuthProvider('leanmcp', {
257
+ apiKey: 'your-leanmcp-api-key'
258
+ });
259
+ await authProvider.init();
260
+ ```
261
+
262
+ ---
263
+
264
+ ## Client Usage
265
+
266
+ Authentication tokens are passed via the `_meta` field following MCP protocol standards:
267
+
268
+ ```typescript
269
+ await mcpClient.callTool({
270
+ name: "analyzeSentiment",
271
+ arguments: { text: "Hello world" },
272
+ _meta: {
273
+ authorization: {
274
+ type: "bearer",
275
+ token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
276
+ }
277
+ }
278
+ });
279
+ ```
280
+
281
+ ---
282
+
283
+ ## Error Handling
284
+
285
+ ```typescript
286
+ import { AuthenticationError } from "@leanmcp/auth";
287
+
288
+ try {
289
+ await service.protectedMethod({ text: "test" });
290
+ } catch (error) {
291
+ if (error instanceof AuthenticationError) {
292
+ switch (error.code) {
293
+ case 'MISSING_TOKEN':
294
+ console.log('No token provided');
295
+ break;
296
+ case 'INVALID_TOKEN':
297
+ console.log('Token is invalid or expired');
298
+ break;
299
+ case 'VERIFICATION_FAILED':
300
+ console.log('Verification failed:', error.message);
301
+ break;
302
+ }
303
+ }
304
+ }
305
+ ```
306
+
307
+ ---
308
+
309
+ ## API Reference
310
+
311
+ ### AuthProvider
312
+
313
+ ```typescript
314
+ class AuthProvider {
315
+ constructor(provider: string, config: any);
316
+ async init(config?: any): Promise<void>;
317
+ async verifyToken(token: string): Promise<boolean>;
318
+ async refreshToken(refreshToken: string): Promise<any>;
319
+ async getUser(token: string): Promise<any>;
320
+ getProviderType(): string;
321
+ }
322
+ ```
323
+
324
+ ### @Authenticated Decorator
325
+
326
+ ```typescript
327
+ function Authenticated(
328
+ authProvider: AuthProvider,
329
+ options?: AuthenticatedOptions
330
+ ): ClassDecorator | MethodDecorator;
331
+
332
+ interface AuthenticatedOptions {
333
+ getUser?: boolean; // Default: true
334
+ projectId?: string; // For LeanMCP user secrets
335
+ }
336
+ ```
337
+
338
+ ### AuthenticationError
339
+
340
+ ```typescript
341
+ class AuthenticationError extends Error {
342
+ code: 'MISSING_TOKEN' | 'INVALID_TOKEN' | 'VERIFICATION_FAILED';
343
+ constructor(message: string, code: string);
344
+ }
345
+ ```
346
+
347
+ ### Helper Functions
348
+
349
+ ```typescript
350
+ // Check if authentication is required
351
+ function isAuthenticationRequired(target: any): boolean;
352
+
353
+ // Get auth provider for method/class
354
+ function getAuthProvider(target: any): AuthProviderBase | undefined;
355
+
356
+ // Get current authenticated user
357
+ function getAuthUser(): any;
358
+ ```
359
+
360
+ ---
361
+
362
+ ## Best Practices
363
+
364
+ ### Security
365
+ - Always use HTTPS in production
366
+ - Store tokens securely (keychain, encrypted storage)
367
+ - Implement token refresh before expiration
368
+ - Add rate limiting to protect against brute force
369
+
370
+ ### Configuration
371
+ - Use environment variables for credentials
372
+ - Never hardcode secrets in code
373
+ - Use `_meta` for auth, not business arguments
374
+
375
+ ### Performance
376
+ - Use `getUser: false` when you only need token validation
377
+ - JWKS keys are cached automatically for performance
378
+
379
+ ---
380
+
381
+ ## Documentation
382
+
383
+ - [Full Documentation](https://docs.leanmcp.com/sdk/auth)
384
+
385
+ ## Related Packages
386
+
387
+ - [@leanmcp/core](https://www.npmjs.com/package/@leanmcp/core) — Core decorators and server functionality
388
+ - [@leanmcp/env-injection](https://www.npmjs.com/package/@leanmcp/env-injection) — Environment variable injection for user secrets
389
+
390
+ ## Links
391
+
392
+ - [GitHub Repository](https://github.com/LeanMCP/leanmcp-sdk)
393
+ - [NPM Package](https://www.npmjs.com/package/@leanmcp/auth)
394
+
395
+ ## License
396
+
397
+ MIT
package/package.json CHANGED
@@ -1,121 +1,121 @@
1
- {
2
- "name": "@leanmcp/auth",
3
- "version": "0.4.3",
4
- "description": "Authentication and identity module with OAuth 2.1 client, token storage, and multiple providers",
5
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "require": "./dist/index.js",
12
- "import": "./dist/index.mjs"
13
- },
14
- "./client": {
15
- "types": "./dist/client/index.d.ts",
16
- "require": "./dist/client/index.js",
17
- "import": "./dist/client/index.mjs"
18
- },
19
- "./storage": {
20
- "types": "./dist/storage/index.d.ts",
21
- "require": "./dist/storage/index.js",
22
- "import": "./dist/storage/index.mjs"
23
- },
24
- "./proxy": {
25
- "types": "./dist/proxy/index.d.ts",
26
- "require": "./dist/proxy/index.js",
27
- "import": "./dist/proxy/index.mjs"
28
- },
29
- "./server": {
30
- "types": "./dist/server/index.d.ts",
31
- "require": "./dist/server/index.js",
32
- "import": "./dist/server/index.mjs"
33
- }
34
- },
35
- "files": [
36
- "dist",
37
- "README.md",
38
- "LICENSE"
39
- ],
40
- "scripts": {
41
- "build": "tsup src/index.ts src/client/index.ts src/storage/index.ts src/proxy/index.ts src/server/index.ts --format esm,cjs --dts",
42
- "dev": "tsup src/index.ts src/client/index.ts src/storage/index.ts src/proxy/index.ts src/server/index.ts --format esm,cjs --dts --watch",
43
- "test": "jest --passWithNoTests",
44
- "test:watch": "jest --watch"
45
- },
46
- "dependencies": {
47
- "@leanmcp/core": "^0.3.0",
48
- "reflect-metadata": "^0.2.1"
49
- },
50
- "devDependencies": {
51
- "@leanmcp/env-injection": "^0.1.0",
52
- "@types/jest": "^29.5.0",
53
- "@types/jsonwebtoken": "^9.0.10",
54
- "@types/jwk-to-pem": "^2.0.3",
55
- "@types/node": "^20.0.0",
56
- "dotenv": "^17.2.3",
57
- "jest": "^29.7.0",
58
- "ts-jest": "^29.1.0",
59
- "express": "^5.0.0"
60
- },
61
- "peerDependencies": {
62
- "@aws-sdk/client-cognito-identity-provider": "^3.0.0",
63
- "@leanmcp/env-injection": "^0.1.0",
64
- "axios": "^1.0.0",
65
- "jsonwebtoken": "^9.0.0",
66
- "jwk-to-pem": "^2.0.0",
67
- "keytar": "^7.0.0",
68
- "open": "^10.0.0",
69
- "express": "^5.0.0"
70
- },
71
- "peerDependenciesMeta": {
72
- "@aws-sdk/client-cognito-identity-provider": {
73
- "optional": true
74
- },
75
- "@leanmcp/env-injection": {
76
- "optional": true
77
- },
78
- "axios": {
79
- "optional": true
80
- },
81
- "jsonwebtoken": {
82
- "optional": true
83
- },
84
- "jwk-to-pem": {
85
- "optional": true
86
- },
87
- "keytar": {
88
- "optional": true
89
- },
90
- "open": {
91
- "optional": true
92
- }
93
- },
94
- "repository": {
95
- "type": "git",
96
- "url": "git+https://github.com/LeanMCP/leanmcp-sdk.git",
97
- "directory": "packages/auth"
98
- },
99
- "homepage": "https://github.com/LeanMCP/leanmcp-sdk#readme",
100
- "bugs": {
101
- "url": "https://github.com/LeanMCP/leanmcp-sdk/issues"
102
- },
103
- "keywords": [
104
- "mcp",
105
- "model-context-protocol",
106
- "typescript",
107
- "decorators",
108
- "authentication",
109
- "auth",
110
- "cognito",
111
- "jwt",
112
- "oauth",
113
- "pkce",
114
- "oauth2"
115
- ],
116
- "author": "LeanMCP <admin@leanmcp.com>",
117
- "license": "MIT",
118
- "publishConfig": {
119
- "access": "public"
120
- }
121
- }
1
+ {
2
+ "name": "@leanmcp/auth",
3
+ "version": "0.4.4",
4
+ "description": "Authentication and identity module with OAuth 2.1 client, token storage, and multiple providers",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "require": "./dist/index.js",
12
+ "import": "./dist/index.mjs"
13
+ },
14
+ "./client": {
15
+ "types": "./dist/client/index.d.ts",
16
+ "require": "./dist/client/index.js",
17
+ "import": "./dist/client/index.mjs"
18
+ },
19
+ "./storage": {
20
+ "types": "./dist/storage/index.d.ts",
21
+ "require": "./dist/storage/index.js",
22
+ "import": "./dist/storage/index.mjs"
23
+ },
24
+ "./proxy": {
25
+ "types": "./dist/proxy/index.d.ts",
26
+ "require": "./dist/proxy/index.js",
27
+ "import": "./dist/proxy/index.mjs"
28
+ },
29
+ "./server": {
30
+ "types": "./dist/server/index.d.ts",
31
+ "require": "./dist/server/index.js",
32
+ "import": "./dist/server/index.mjs"
33
+ }
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsup src/index.ts src/client/index.ts src/storage/index.ts src/proxy/index.ts src/server/index.ts --format esm,cjs --dts",
42
+ "dev": "tsup src/index.ts src/client/index.ts src/storage/index.ts src/proxy/index.ts src/server/index.ts --format esm,cjs --dts --watch",
43
+ "test": "jest --passWithNoTests",
44
+ "test:watch": "jest --watch"
45
+ },
46
+ "dependencies": {
47
+ "@leanmcp/core": "^0.3.0",
48
+ "reflect-metadata": "^0.2.1"
49
+ },
50
+ "devDependencies": {
51
+ "@leanmcp/env-injection": "^0.1.0",
52
+ "@types/jest": "^29.5.0",
53
+ "@types/jsonwebtoken": "^9.0.10",
54
+ "@types/jwk-to-pem": "^2.0.3",
55
+ "@types/node": "^20.0.0",
56
+ "dotenv": "^17.2.3",
57
+ "jest": "^29.7.0",
58
+ "ts-jest": "^29.1.0",
59
+ "express": "^5.0.0"
60
+ },
61
+ "peerDependencies": {
62
+ "@aws-sdk/client-cognito-identity-provider": "^3.0.0",
63
+ "@leanmcp/env-injection": "^0.1.0",
64
+ "axios": "^1.0.0",
65
+ "jsonwebtoken": "^9.0.0",
66
+ "jwk-to-pem": "^2.0.0",
67
+ "keytar": "^7.0.0",
68
+ "open": "^10.0.0",
69
+ "express": "^5.0.0"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "@aws-sdk/client-cognito-identity-provider": {
73
+ "optional": true
74
+ },
75
+ "@leanmcp/env-injection": {
76
+ "optional": true
77
+ },
78
+ "axios": {
79
+ "optional": true
80
+ },
81
+ "jsonwebtoken": {
82
+ "optional": true
83
+ },
84
+ "jwk-to-pem": {
85
+ "optional": true
86
+ },
87
+ "keytar": {
88
+ "optional": true
89
+ },
90
+ "open": {
91
+ "optional": true
92
+ }
93
+ },
94
+ "repository": {
95
+ "type": "git",
96
+ "url": "git+https://github.com/LeanMCP/leanmcp-sdk.git",
97
+ "directory": "packages/auth"
98
+ },
99
+ "homepage": "https://github.com/LeanMCP/leanmcp-sdk#readme",
100
+ "bugs": {
101
+ "url": "https://github.com/LeanMCP/leanmcp-sdk/issues"
102
+ },
103
+ "keywords": [
104
+ "mcp",
105
+ "model-context-protocol",
106
+ "typescript",
107
+ "decorators",
108
+ "authentication",
109
+ "auth",
110
+ "cognito",
111
+ "jwt",
112
+ "oauth",
113
+ "pkce",
114
+ "oauth2"
115
+ ],
116
+ "author": "LeanMCP <admin@leanmcp.com>",
117
+ "license": "MIT",
118
+ "publishConfig": {
119
+ "access": "public"
120
+ }
121
+ }