@prmichaelsen/mcp-auth 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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/auth/base-provider.js +173 -0
  4. package/dist/auth/base-provider.js.map +7 -0
  5. package/dist/auth/index.js +11 -0
  6. package/dist/auth/index.js.map +7 -0
  7. package/dist/auth/providers/env-provider.js +71 -0
  8. package/dist/auth/providers/env-provider.js.map +7 -0
  9. package/dist/auth/providers/index.js +11 -0
  10. package/dist/auth/providers/index.js.map +7 -0
  11. package/dist/auth/providers/simple-resolver.js +185 -0
  12. package/dist/auth/providers/simple-resolver.js.map +7 -0
  13. package/dist/auth/types.js +1 -0
  14. package/dist/auth/types.js.map +7 -0
  15. package/dist/index.js +111 -0
  16. package/dist/index.js.map +7 -0
  17. package/dist/server/config.js +1 -0
  18. package/dist/server/config.js.map +7 -0
  19. package/dist/server/decorators.js +149 -0
  20. package/dist/server/decorators.js.map +7 -0
  21. package/dist/server/index.js +25 -0
  22. package/dist/server/index.js.map +7 -0
  23. package/dist/server/mcp-server.js +269 -0
  24. package/dist/server/mcp-server.js.map +7 -0
  25. package/dist/server/tool.js +66 -0
  26. package/dist/server/tool.js.map +7 -0
  27. package/dist/types.js +1 -0
  28. package/dist/types.js.map +7 -0
  29. package/dist/utils/errors.js +143 -0
  30. package/dist/utils/errors.js.map +7 -0
  31. package/dist/utils/index.js +81 -0
  32. package/dist/utils/index.js.map +7 -0
  33. package/dist/utils/logger.js +200 -0
  34. package/dist/utils/logger.js.map +7 -0
  35. package/dist/utils/validation.js +172 -0
  36. package/dist/utils/validation.js.map +7 -0
  37. package/dist/wrapper/config.js +1 -0
  38. package/dist/wrapper/config.js.map +7 -0
  39. package/dist/wrapper/index.js +10 -0
  40. package/dist/wrapper/index.js.map +7 -0
  41. package/dist/wrapper/server-wrapper.js +427 -0
  42. package/dist/wrapper/server-wrapper.js.map +7 -0
  43. package/package.json +93 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 prmichaelsen
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 ADDED
@@ -0,0 +1,195 @@
1
+ # @prmichaelsen/mcp-auth
2
+
3
+ Authentication and multi-tenancy framework for MCP (Model Context Protocol) servers.
4
+
5
+ ## Overview
6
+
7
+ `@prmichaelsen/mcp-auth` provides a pluggable authentication system for MCP servers, enabling:
8
+
9
+ - **Multi-tenancy**: Multiple users with separate resource tokens
10
+ - **Auth-agnostic**: Support for JWT, OAuth, API Keys, or custom auth schemes
11
+ - **Transport-agnostic**: Works with stdio, HTTP, and SSE transports
12
+ - **Type-safe**: Full TypeScript support
13
+ - **Composable**: Middleware for rate limiting, logging, etc.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @prmichaelsen/mcp-auth @modelcontextprotocol/sdk
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### Simple Function-Based Tool
24
+
25
+ ```typescript
26
+ import { withAuth, AuthenticatedMCPServer } from '@prmichaelsen/mcp-auth';
27
+ import { EnvAuthProvider, SimpleTokenResolver } from '@prmichaelsen/mcp-auth/providers/env';
28
+
29
+ // Setup auth provider
30
+ const authProvider = new EnvAuthProvider();
31
+ const tokenResolver = new SimpleTokenResolver({ tokenEnvVar: 'API_TOKEN' });
32
+
33
+ // Create server
34
+ const server = new AuthenticatedMCPServer({
35
+ name: 'my-mcp-server',
36
+ authProvider,
37
+ tokenResolver,
38
+ resourceType: 'myapi',
39
+ transport: { type: 'stdio' }
40
+ });
41
+
42
+ // Register tool with automatic auth
43
+ server.registerTool('get_data', withAuth(async (args, accessToken, userId) => {
44
+ // accessToken and userId are automatically injected
45
+ const client = new MyAPIClient(accessToken);
46
+ return client.getData(args);
47
+ }));
48
+
49
+ await server.start();
50
+ ```
51
+
52
+ ### Class-Based Tool
53
+
54
+ ```typescript
55
+ import { Tool, AuthenticatedTool } from '@prmichaelsen/mcp-auth';
56
+
57
+ class GetDataTool implements Tool {
58
+ name = 'get_data';
59
+ description = 'Fetch data from API';
60
+
61
+ async execute(args, accessToken, userId) {
62
+ const client = new MyAPIClient(accessToken);
63
+ return client.getData(args);
64
+ }
65
+ }
66
+
67
+ server.registerTool(new AuthenticatedTool(new GetDataTool()));
68
+ ```
69
+
70
+ ## Authentication Providers
71
+
72
+ ### Environment Variable (Simple)
73
+
74
+ ```typescript
75
+ import { EnvAuthProvider, SimpleTokenResolver } from '@prmichaelsen/mcp-auth/providers/env';
76
+
77
+ const authProvider = new EnvAuthProvider();
78
+ const tokenResolver = new SimpleTokenResolver({ tokenEnvVar: 'API_TOKEN' });
79
+ ```
80
+
81
+ ### JWT (Multi-tenant)
82
+
83
+ ```typescript
84
+ import { JWTAuthProvider } from '@prmichaelsen/mcp-auth/providers/jwt';
85
+
86
+ const authProvider = new JWTAuthProvider({
87
+ jwtSecret: process.env.JWT_SECRET,
88
+ database: {
89
+ host: 'localhost',
90
+ database: 'users'
91
+ }
92
+ });
93
+ ```
94
+
95
+ ### OAuth 2.0
96
+
97
+ ```typescript
98
+ import { OAuthProvider } from '@prmichaelsen/mcp-auth/providers/oauth';
99
+
100
+ const authProvider = new OAuthProvider({
101
+ authorizationUrl: 'https://auth.example.com/authorize',
102
+ tokenUrl: 'https://auth.example.com/token',
103
+ clientId: process.env.OAUTH_CLIENT_ID,
104
+ clientSecret: process.env.OAUTH_CLIENT_SECRET
105
+ });
106
+ ```
107
+
108
+ ### Custom Provider
109
+
110
+ ```typescript
111
+ import { AuthProvider, AuthResult, RequestContext } from '@prmichaelsen/mcp-auth';
112
+
113
+ class CustomAuthProvider implements AuthProvider {
114
+ async authenticate(context: RequestContext): Promise<AuthResult> {
115
+ // Your custom auth logic
116
+ const apiKey = context.headers?.['x-api-key'];
117
+
118
+ if (!apiKey) {
119
+ return { authenticated: false, error: 'No API key' };
120
+ }
121
+
122
+ // Validate and return user ID
123
+ return {
124
+ authenticated: true,
125
+ userId: 'user-123'
126
+ };
127
+ }
128
+ }
129
+ ```
130
+
131
+ ## Middleware Composition
132
+
133
+ ```typescript
134
+ import { compose, withAuth, withRateLimit, withLogging } from '@prmichaelsen/mcp-auth';
135
+
136
+ const getTool = compose(
137
+ withLogging(),
138
+ withRateLimit({ maxRequests: 100, windowMs: 60000 }),
139
+ withAuth(),
140
+ async (args, accessToken, userId) => {
141
+ // Your tool logic
142
+ }
143
+ );
144
+
145
+ server.registerTool('get_data', getTool);
146
+ ```
147
+
148
+ ## Transports
149
+
150
+ ### Stdio (Local)
151
+
152
+ ```typescript
153
+ const server = new AuthenticatedMCPServer({
154
+ // ...
155
+ transport: { type: 'stdio' }
156
+ });
157
+ ```
158
+
159
+ ### HTTP/SSE (Remote)
160
+
161
+ ```typescript
162
+ const server = new AuthenticatedMCPServer({
163
+ // ...
164
+ transport: {
165
+ type: 'sse',
166
+ port: 3000,
167
+ host: '0.0.0.0',
168
+ basePath: '/mcp'
169
+ }
170
+ });
171
+ ```
172
+
173
+ ## Documentation
174
+
175
+ See the [`agent/`](./agent/) directory for detailed architecture documentation:
176
+
177
+ - [`multi-tenant-architecture.md`](./agent/multi-tenant-architecture.md) - Overall architecture and auth schemes
178
+ - [`lib-structure.md`](./agent/lib-structure.md) - Package structure and design
179
+ - [`tool-patterns.md`](./agent/tool-patterns.md) - Tool registration patterns
180
+
181
+ ## Examples
182
+
183
+ See the [`examples/`](./examples/) directory for complete examples:
184
+
185
+ - `simple-stdio/` - Single-user stdio server
186
+ - `jwt-multi-tenant/` - Multi-tenant JWT server
187
+ - `oauth-server/` - OAuth authentication flow
188
+
189
+ ## License
190
+
191
+ MIT
192
+
193
+ ## Contributing
194
+
195
+ Contributions welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for details.
@@ -0,0 +1,173 @@
1
+ import { createLogger } from "../utils/logger.js";
2
+ class BaseAuthProvider {
3
+ config;
4
+ logger;
5
+ authCache;
6
+ constructor(config = {}) {
7
+ this.config = {
8
+ errorMessages: {
9
+ noAuth: "No authentication credentials provided",
10
+ invalidAuth: "Invalid authentication credentials",
11
+ expiredAuth: "Authentication credentials have expired",
12
+ ...config.errorMessages
13
+ },
14
+ cacheResults: config.cacheResults ?? false,
15
+ cacheTtl: config.cacheTtl ?? 6e4
16
+ // 1 minute default
17
+ };
18
+ this.logger = createLogger({ enabled: true, level: "info" });
19
+ this.authCache = /* @__PURE__ */ new Map();
20
+ }
21
+ /**
22
+ * Authenticate a request
23
+ * Implements caching if enabled
24
+ */
25
+ async authenticate(context) {
26
+ try {
27
+ const cacheKey = this.getCacheKey(context);
28
+ if (this.config.cacheResults && cacheKey) {
29
+ const cached = this.authCache.get(cacheKey);
30
+ if (cached && cached.expiresAt > Date.now()) {
31
+ this.logger.debug("Authentication result retrieved from cache", {
32
+ cacheKey,
33
+ userId: cached.result.userId
34
+ });
35
+ return cached.result;
36
+ }
37
+ }
38
+ const result = await this.doAuthenticate(context);
39
+ if (result.authenticated && this.config.cacheResults && cacheKey) {
40
+ this.authCache.set(cacheKey, {
41
+ result,
42
+ expiresAt: Date.now() + (this.config.cacheTtl ?? 6e4)
43
+ });
44
+ this.logger.debug("Authentication result cached", {
45
+ cacheKey,
46
+ userId: result.userId,
47
+ ttl: this.config.cacheTtl
48
+ });
49
+ }
50
+ if (result.authenticated) {
51
+ this.logger.info("Authentication successful", {
52
+ userId: result.userId,
53
+ transport: context.transport
54
+ });
55
+ } else {
56
+ this.logger.warn("Authentication failed", {
57
+ error: result.error,
58
+ transport: context.transport
59
+ });
60
+ }
61
+ return result;
62
+ } catch (error) {
63
+ this.logger.error("Authentication error", error, {
64
+ transport: context.transport
65
+ });
66
+ return {
67
+ authenticated: false,
68
+ error: error instanceof Error ? error.message : "Authentication failed"
69
+ };
70
+ }
71
+ }
72
+ /**
73
+ * Generate cache key from request context
74
+ * Override this to customize caching behavior
75
+ */
76
+ getCacheKey(context) {
77
+ const authHeader = context.headers?.["authorization"];
78
+ if (typeof authHeader === "string") {
79
+ return authHeader;
80
+ }
81
+ return null;
82
+ }
83
+ /**
84
+ * Extract authorization header from context
85
+ */
86
+ getAuthorizationHeader(context) {
87
+ const authHeader = context.headers?.["authorization"];
88
+ if (typeof authHeader === "string") {
89
+ return authHeader;
90
+ }
91
+ if (Array.isArray(authHeader) && authHeader.length > 0) {
92
+ return authHeader[0];
93
+ }
94
+ return null;
95
+ }
96
+ /**
97
+ * Extract bearer token from authorization header
98
+ */
99
+ extractBearerToken(context) {
100
+ const authHeader = this.getAuthorizationHeader(context);
101
+ if (!authHeader) {
102
+ return null;
103
+ }
104
+ const parts = authHeader.split(" ");
105
+ if (parts.length === 2 && parts[0].toLowerCase() === "bearer") {
106
+ return parts[1];
107
+ }
108
+ return null;
109
+ }
110
+ /**
111
+ * Create authentication failure result
112
+ */
113
+ createFailureResult(error) {
114
+ return {
115
+ authenticated: false,
116
+ error
117
+ };
118
+ }
119
+ /**
120
+ * Create authentication success result
121
+ */
122
+ createSuccessResult(userId, metadata) {
123
+ return {
124
+ authenticated: true,
125
+ userId,
126
+ metadata
127
+ };
128
+ }
129
+ /**
130
+ * Optional: Initialize the provider
131
+ */
132
+ async initialize() {
133
+ this.logger.info("Authentication provider initialized", {
134
+ provider: this.constructor.name,
135
+ cacheEnabled: this.config.cacheResults
136
+ });
137
+ }
138
+ /**
139
+ * Optional: Cleanup resources
140
+ */
141
+ async cleanup() {
142
+ this.authCache.clear();
143
+ this.logger.info("Authentication provider cleaned up", {
144
+ provider: this.constructor.name
145
+ });
146
+ }
147
+ /**
148
+ * Optional: Validate provider configuration
149
+ */
150
+ async validate() {
151
+ return true;
152
+ }
153
+ /**
154
+ * Clear authentication cache
155
+ */
156
+ clearCache() {
157
+ this.authCache.clear();
158
+ this.logger.debug("Authentication cache cleared");
159
+ }
160
+ /**
161
+ * Get cache statistics
162
+ */
163
+ getCacheStats() {
164
+ return {
165
+ size: this.authCache.size,
166
+ keys: Array.from(this.authCache.keys())
167
+ };
168
+ }
169
+ }
170
+ export {
171
+ BaseAuthProvider
172
+ };
173
+ //# sourceMappingURL=base-provider.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/auth/base-provider.ts"],
4
+ "sourcesContent": ["/**\n * Base authentication provider implementation\n * \n * Provides common functionality for authentication providers.\n */\n\nimport type { AuthProvider, AuthProviderConfig } from './types.js';\nimport type { RequestContext, AuthResult } from '../types.js';\nimport { AuthenticationError } from '../utils/errors.js';\nimport { createLogger, type Logger } from '../utils/logger.js';\n\n/**\n * Abstract base class for authentication providers\n * \n * Provides common functionality like caching, logging, and error handling.\n * Extend this class to implement custom authentication logic.\n * \n * @example\n * ```typescript\n * class MyAuthProvider extends BaseAuthProvider {\n * protected async doAuthenticate(context: RequestContext): Promise<AuthResult> {\n * // Your authentication logic here\n * return { authenticated: true, userId: 'user-123' };\n * }\n * }\n * ```\n */\nexport abstract class BaseAuthProvider implements AuthProvider {\n protected config: AuthProviderConfig;\n protected logger: Logger;\n private authCache: Map<string, { result: AuthResult; expiresAt: number }>;\n \n constructor(config: AuthProviderConfig = {}) {\n this.config = {\n errorMessages: {\n noAuth: 'No authentication credentials provided',\n invalidAuth: 'Invalid authentication credentials',\n expiredAuth: 'Authentication credentials have expired',\n ...config.errorMessages\n },\n cacheResults: config.cacheResults ?? false,\n cacheTtl: config.cacheTtl ?? 60000 // 1 minute default\n };\n \n this.logger = createLogger({ enabled: true, level: 'info' });\n this.authCache = new Map();\n }\n \n /**\n * Authenticate a request\n * Implements caching if enabled\n */\n async authenticate(context: RequestContext): Promise<AuthResult> {\n try {\n // Generate cache key from context\n const cacheKey = this.getCacheKey(context);\n \n // Check cache if enabled\n if (this.config.cacheResults && cacheKey) {\n const cached = this.authCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) {\n this.logger.debug('Authentication result retrieved from cache', {\n cacheKey,\n userId: cached.result.userId\n });\n return cached.result;\n }\n }\n \n // Perform authentication\n const result = await this.doAuthenticate(context);\n \n // Cache result if successful and caching is enabled\n if (result.authenticated && this.config.cacheResults && cacheKey) {\n this.authCache.set(cacheKey, {\n result,\n expiresAt: Date.now() + (this.config.cacheTtl ?? 60000)\n });\n \n this.logger.debug('Authentication result cached', {\n cacheKey,\n userId: result.userId,\n ttl: this.config.cacheTtl\n });\n }\n \n // Log result\n if (result.authenticated) {\n this.logger.info('Authentication successful', {\n userId: result.userId,\n transport: context.transport\n });\n } else {\n this.logger.warn('Authentication failed', {\n error: result.error,\n transport: context.transport\n });\n }\n \n return result;\n \n } catch (error) {\n this.logger.error('Authentication error', error as Error, {\n transport: context.transport\n });\n \n return {\n authenticated: false,\n error: error instanceof Error ? error.message : 'Authentication failed'\n };\n }\n }\n \n /**\n * Abstract method to implement authentication logic\n * Override this in your provider implementation\n */\n protected abstract doAuthenticate(context: RequestContext): Promise<AuthResult>;\n \n /**\n * Generate cache key from request context\n * Override this to customize caching behavior\n */\n protected getCacheKey(context: RequestContext): string | null {\n // Default: use authorization header as cache key\n const authHeader = context.headers?.['authorization'];\n if (typeof authHeader === 'string') {\n return authHeader;\n }\n return null;\n }\n \n /**\n * Extract authorization header from context\n */\n protected getAuthorizationHeader(context: RequestContext): string | null {\n const authHeader = context.headers?.['authorization'];\n \n if (typeof authHeader === 'string') {\n return authHeader;\n }\n \n if (Array.isArray(authHeader) && authHeader.length > 0) {\n return authHeader[0];\n }\n \n return null;\n }\n \n /**\n * Extract bearer token from authorization header\n */\n protected extractBearerToken(context: RequestContext): string | null {\n const authHeader = this.getAuthorizationHeader(context);\n \n if (!authHeader) {\n return null;\n }\n \n const parts = authHeader.split(' ');\n if (parts.length === 2 && parts[0].toLowerCase() === 'bearer') {\n return parts[1];\n }\n \n return null;\n }\n \n /**\n * Create authentication failure result\n */\n protected createFailureResult(error: string): AuthResult {\n return {\n authenticated: false,\n error\n };\n }\n \n /**\n * Create authentication success result\n */\n protected createSuccessResult(\n userId: string,\n metadata?: Record<string, unknown>\n ): AuthResult {\n return {\n authenticated: true,\n userId,\n metadata\n };\n }\n \n /**\n * Optional: Initialize the provider\n */\n async initialize(): Promise<void> {\n this.logger.info('Authentication provider initialized', {\n provider: this.constructor.name,\n cacheEnabled: this.config.cacheResults\n });\n }\n \n /**\n * Optional: Cleanup resources\n */\n async cleanup(): Promise<void> {\n // Clear cache\n this.authCache.clear();\n \n this.logger.info('Authentication provider cleaned up', {\n provider: this.constructor.name\n });\n }\n \n /**\n * Optional: Validate provider configuration\n */\n async validate(): Promise<boolean> {\n // Base implementation always returns true\n // Override in subclasses to add validation logic\n return true;\n }\n \n /**\n * Clear authentication cache\n */\n clearCache(): void {\n this.authCache.clear();\n this.logger.debug('Authentication cache cleared');\n }\n \n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.authCache.size,\n keys: Array.from(this.authCache.keys())\n };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseAuthProvider } from "./base-provider.js";
2
+ import {
3
+ EnvAuthProvider,
4
+ SimpleTokenResolver
5
+ } from "./providers/index.js";
6
+ export {
7
+ BaseAuthProvider,
8
+ EnvAuthProvider,
9
+ SimpleTokenResolver
10
+ };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/auth/index.ts"],
4
+ "sourcesContent": ["/**\n * Authentication module exports\n */\n\n// Types\nexport type {\n AuthProvider,\n ResourceTokenResolver,\n AuthenticatedContext,\n AuthProviderConfig,\n TokenResolverConfig\n} from './types.js';\n\n// Base provider\nexport { BaseAuthProvider } from './base-provider.js';\n\n// Providers\nexport {\n EnvAuthProvider,\n type EnvAuthProviderConfig,\n SimpleTokenResolver,\n type SimpleTokenResolverConfig\n} from './providers/index.js';\n"],
5
+ "mappings": "AAcA,SAAS,wBAAwB;AAGjC;AAAA,EACE;AAAA,EAEA;AAAA,OAEK;",
6
+ "names": []
7
+ }
@@ -0,0 +1,71 @@
1
+ import { BaseAuthProvider } from "../base-provider.js";
2
+ class EnvAuthProvider extends BaseAuthProvider {
3
+ envConfig;
4
+ constructor(config = {}) {
5
+ super(config);
6
+ this.envConfig = {
7
+ ...config,
8
+ userIdEnvVar: config.userIdEnvVar ?? "MCP_USER_ID",
9
+ defaultUserId: config.defaultUserId ?? "default-user",
10
+ requireUserId: config.requireUserId ?? false,
11
+ errorMessages: config.errorMessages ?? {},
12
+ cacheResults: config.cacheResults ?? false,
13
+ cacheTtl: config.cacheTtl ?? 6e4
14
+ };
15
+ }
16
+ /**
17
+ * Authenticate request by reading user ID from environment
18
+ */
19
+ async doAuthenticate(context) {
20
+ const userId = process.env[this.envConfig.userIdEnvVar];
21
+ if (!userId) {
22
+ if (this.envConfig.requireUserId) {
23
+ return this.createFailureResult(
24
+ `${this.envConfig.userIdEnvVar} environment variable is required`
25
+ );
26
+ }
27
+ this.logger.debug("Using default user ID", {
28
+ defaultUserId: this.envConfig.defaultUserId
29
+ });
30
+ return this.createSuccessResult(this.envConfig.defaultUserId, {
31
+ source: "default"
32
+ });
33
+ }
34
+ if (userId.trim().length === 0) {
35
+ return this.createFailureResult("User ID cannot be empty");
36
+ }
37
+ this.logger.debug("User ID resolved from environment", {
38
+ envVar: this.envConfig.userIdEnvVar,
39
+ userId
40
+ });
41
+ return this.createSuccessResult(userId, {
42
+ source: "environment",
43
+ envVar: this.envConfig.userIdEnvVar
44
+ });
45
+ }
46
+ /**
47
+ * Validate provider configuration
48
+ */
49
+ async validate() {
50
+ if (this.envConfig.requireUserId) {
51
+ const userId = process.env[this.envConfig.userIdEnvVar];
52
+ if (!userId) {
53
+ this.logger.error("Validation failed: Required environment variable not set", void 0, {
54
+ envVar: this.envConfig.userIdEnvVar
55
+ });
56
+ return false;
57
+ }
58
+ }
59
+ return true;
60
+ }
61
+ /**
62
+ * Get current user ID from environment
63
+ */
64
+ getUserId() {
65
+ return process.env[this.envConfig.userIdEnvVar] ?? this.envConfig.defaultUserId;
66
+ }
67
+ }
68
+ export {
69
+ EnvAuthProvider
70
+ };
71
+ //# sourceMappingURL=env-provider.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/auth/providers/env-provider.ts"],
4
+ "sourcesContent": ["/**\n * Environment variable authentication provider\n * \n * Simple provider for single-user scenarios that reads credentials from environment variables.\n * Useful for local development and stdio mode.\n */\n\nimport { BaseAuthProvider } from '../base-provider.js';\nimport type { AuthProviderConfig } from '../types.js';\nimport type { RequestContext, AuthResult } from '../../types.js';\nimport { MissingCredentialsError } from '../../utils/errors.js';\n\n/**\n * Configuration for EnvAuthProvider\n */\nexport interface EnvAuthProviderConfig extends AuthProviderConfig {\n /**\n * Environment variable name containing the user ID\n * @default 'MCP_USER_ID'\n */\n userIdEnvVar?: string;\n \n /**\n * Default user ID if environment variable is not set\n * @default 'default-user'\n */\n defaultUserId?: string;\n \n /**\n * Whether to require user ID environment variable\n * @default false\n */\n requireUserId?: boolean;\n}\n\n/**\n * Environment variable authentication provider\n * \n * This provider is designed for single-user scenarios where authentication\n * is not required (e.g., local development, stdio mode).\n * \n * It reads the user ID from an environment variable or uses a default value.\n * \n * @example\n * ```typescript\n * const provider = new EnvAuthProvider({\n * userIdEnvVar: 'MY_USER_ID',\n * defaultUserId: 'local-user'\n * });\n * \n * // Or with defaults\n * const provider = new EnvAuthProvider();\n * ```\n */\nexport class EnvAuthProvider extends BaseAuthProvider {\n private envConfig: Required<EnvAuthProviderConfig>;\n \n constructor(config: EnvAuthProviderConfig = {}) {\n super(config);\n \n this.envConfig = {\n ...config,\n userIdEnvVar: config.userIdEnvVar ?? 'MCP_USER_ID',\n defaultUserId: config.defaultUserId ?? 'default-user',\n requireUserId: config.requireUserId ?? false,\n errorMessages: config.errorMessages ?? {},\n cacheResults: config.cacheResults ?? false,\n cacheTtl: config.cacheTtl ?? 60000\n };\n }\n \n /**\n * Authenticate request by reading user ID from environment\n */\n protected async doAuthenticate(context: RequestContext): Promise<AuthResult> {\n // Read user ID from environment variable\n const userId = process.env[this.envConfig.userIdEnvVar];\n \n if (!userId) {\n if (this.envConfig.requireUserId) {\n return this.createFailureResult(\n `${this.envConfig.userIdEnvVar} environment variable is required`\n );\n }\n \n // Use default user ID\n this.logger.debug('Using default user ID', {\n defaultUserId: this.envConfig.defaultUserId\n });\n \n return this.createSuccessResult(this.envConfig.defaultUserId, {\n source: 'default'\n });\n }\n \n // Validate user ID\n if (userId.trim().length === 0) {\n return this.createFailureResult('User ID cannot be empty');\n }\n \n this.logger.debug('User ID resolved from environment', {\n envVar: this.envConfig.userIdEnvVar,\n userId\n });\n \n return this.createSuccessResult(userId, {\n source: 'environment',\n envVar: this.envConfig.userIdEnvVar\n });\n }\n \n /**\n * Validate provider configuration\n */\n async validate(): Promise<boolean> {\n if (this.envConfig.requireUserId) {\n const userId = process.env[this.envConfig.userIdEnvVar];\n if (!userId) {\n this.logger.error('Validation failed: Required environment variable not set', undefined, {\n envVar: this.envConfig.userIdEnvVar\n });\n return false;\n }\n }\n \n return true;\n }\n \n /**\n * Get current user ID from environment\n */\n getUserId(): string {\n return process.env[this.envConfig.userIdEnvVar] ?? this.envConfig.defaultUserId;\n }\n}\n"],
5
+ "mappings": "AAOA,SAAS,wBAAwB;AA+C1B,MAAM,wBAAwB,iBAAiB;AAAA,EAC5C;AAAA,EAER,YAAY,SAAgC,CAAC,GAAG;AAC9C,UAAM,MAAM;AAEZ,SAAK,YAAY;AAAA,MACf,GAAG;AAAA,MACH,cAAc,OAAO,gBAAgB;AAAA,MACrC,eAAe,OAAO,iBAAiB;AAAA,MACvC,eAAe,OAAO,iBAAiB;AAAA,MACvC,eAAe,OAAO,iBAAiB,CAAC;AAAA,MACxC,cAAc,OAAO,gBAAgB;AAAA,MACrC,UAAU,OAAO,YAAY;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,eAAe,SAA8C;AAE3E,UAAM,SAAS,QAAQ,IAAI,KAAK,UAAU,YAAY;AAEtD,QAAI,CAAC,QAAQ;AACX,UAAI,KAAK,UAAU,eAAe;AAChC,eAAO,KAAK;AAAA,UACV,GAAG,KAAK,UAAU,YAAY;AAAA,QAChC;AAAA,MACF;AAGA,WAAK,OAAO,MAAM,yBAAyB;AAAA,QACzC,eAAe,KAAK,UAAU;AAAA,MAChC,CAAC;AAED,aAAO,KAAK,oBAAoB,KAAK,UAAU,eAAe;AAAA,QAC5D,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAGA,QAAI,OAAO,KAAK,EAAE,WAAW,GAAG;AAC9B,aAAO,KAAK,oBAAoB,yBAAyB;AAAA,IAC3D;AAEA,SAAK,OAAO,MAAM,qCAAqC;AAAA,MACrD,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,IACF,CAAC;AAED,WAAO,KAAK,oBAAoB,QAAQ;AAAA,MACtC,QAAQ;AAAA,MACR,QAAQ,KAAK,UAAU;AAAA,IACzB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA6B;AACjC,QAAI,KAAK,UAAU,eAAe;AAChC,YAAM,SAAS,QAAQ,IAAI,KAAK,UAAU,YAAY;AACtD,UAAI,CAAC,QAAQ;AACX,aAAK,OAAO,MAAM,4DAA4D,QAAW;AAAA,UACvF,QAAQ,KAAK,UAAU;AAAA,QACzB,CAAC;AACD,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAoB;AAClB,WAAO,QAAQ,IAAI,KAAK,UAAU,YAAY,KAAK,KAAK,UAAU;AAAA,EACpE;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ import {
2
+ EnvAuthProvider
3
+ } from "./env-provider.js";
4
+ import {
5
+ SimpleTokenResolver
6
+ } from "./simple-resolver.js";
7
+ export {
8
+ EnvAuthProvider,
9
+ SimpleTokenResolver
10
+ };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/auth/providers/index.ts"],
4
+ "sourcesContent": ["/**\n * Authentication providers module exports\n */\n\n// Environment-based provider\nexport { \n EnvAuthProvider,\n type EnvAuthProviderConfig \n} from './env-provider.js';\n\n// Simple token resolver\nexport { \n SimpleTokenResolver,\n type SimpleTokenResolverConfig \n} from './simple-resolver.js';\n"],
5
+ "mappings": "AAKA;AAAA,EACE;AAAA,OAEK;AAGP;AAAA,EACE;AAAA,OAEK;",
6
+ "names": []
7
+ }