awslabs.openapi-mcp-server 0.1.1__py3-none-any.whl

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 (38) hide show
  1. awslabs/__init__.py +16 -0
  2. awslabs/openapi_mcp_server/__init__.py +69 -0
  3. awslabs/openapi_mcp_server/api/__init__.py +18 -0
  4. awslabs/openapi_mcp_server/api/config.py +200 -0
  5. awslabs/openapi_mcp_server/auth/__init__.py +27 -0
  6. awslabs/openapi_mcp_server/auth/api_key_auth.py +185 -0
  7. awslabs/openapi_mcp_server/auth/auth_cache.py +190 -0
  8. awslabs/openapi_mcp_server/auth/auth_errors.py +206 -0
  9. awslabs/openapi_mcp_server/auth/auth_factory.py +146 -0
  10. awslabs/openapi_mcp_server/auth/auth_protocol.py +63 -0
  11. awslabs/openapi_mcp_server/auth/auth_provider.py +160 -0
  12. awslabs/openapi_mcp_server/auth/base_auth.py +218 -0
  13. awslabs/openapi_mcp_server/auth/basic_auth.py +171 -0
  14. awslabs/openapi_mcp_server/auth/bearer_auth.py +108 -0
  15. awslabs/openapi_mcp_server/auth/cognito_auth.py +538 -0
  16. awslabs/openapi_mcp_server/auth/register.py +100 -0
  17. awslabs/openapi_mcp_server/patch/__init__.py +17 -0
  18. awslabs/openapi_mcp_server/prompts/__init__.py +18 -0
  19. awslabs/openapi_mcp_server/prompts/generators/__init__.py +22 -0
  20. awslabs/openapi_mcp_server/prompts/generators/operation_prompts.py +642 -0
  21. awslabs/openapi_mcp_server/prompts/generators/workflow_prompts.py +257 -0
  22. awslabs/openapi_mcp_server/prompts/models.py +70 -0
  23. awslabs/openapi_mcp_server/prompts/prompt_manager.py +150 -0
  24. awslabs/openapi_mcp_server/server.py +511 -0
  25. awslabs/openapi_mcp_server/utils/__init__.py +18 -0
  26. awslabs/openapi_mcp_server/utils/cache_provider.py +249 -0
  27. awslabs/openapi_mcp_server/utils/config.py +35 -0
  28. awslabs/openapi_mcp_server/utils/error_handler.py +349 -0
  29. awslabs/openapi_mcp_server/utils/http_client.py +263 -0
  30. awslabs/openapi_mcp_server/utils/metrics_provider.py +503 -0
  31. awslabs/openapi_mcp_server/utils/openapi.py +217 -0
  32. awslabs/openapi_mcp_server/utils/openapi_validator.py +253 -0
  33. awslabs_openapi_mcp_server-0.1.1.dist-info/METADATA +418 -0
  34. awslabs_openapi_mcp_server-0.1.1.dist-info/RECORD +38 -0
  35. awslabs_openapi_mcp_server-0.1.1.dist-info/WHEEL +4 -0
  36. awslabs_openapi_mcp_server-0.1.1.dist-info/entry_points.txt +2 -0
  37. awslabs_openapi_mcp_server-0.1.1.dist-info/licenses/LICENSE +175 -0
  38. awslabs_openapi_mcp_server-0.1.1.dist-info/licenses/NOTICE +2 -0
@@ -0,0 +1,538 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Cognito User Pool authentication provider."""
15
+
16
+ import boto3
17
+ import threading
18
+ import time
19
+ from awslabs.openapi_mcp_server import logger
20
+ from awslabs.openapi_mcp_server.api.config import Config
21
+ from awslabs.openapi_mcp_server.auth.auth_errors import (
22
+ ConfigurationError,
23
+ ExpiredTokenError,
24
+ InvalidCredentialsError,
25
+ MissingCredentialsError,
26
+ NetworkError,
27
+ )
28
+ from awslabs.openapi_mcp_server.auth.bearer_auth import BearerAuthProvider
29
+ from typing import Dict, Optional
30
+
31
+
32
+ class CognitoAuthProvider(BearerAuthProvider):
33
+ """Cognito User Pool authentication provider.
34
+
35
+ This provider obtains ID tokens from AWS Cognito User Pools
36
+ and delegates to BearerAuthProvider for adding Authorization headers
37
+ to all HTTP requests.
38
+ """
39
+
40
+ def __init__(self, config: Config):
41
+ """Initialize with configuration.
42
+
43
+ Args:
44
+ config: Application configuration
45
+
46
+ """
47
+ # Store Cognito-specific configuration
48
+ self._client_id = config.auth_cognito_client_id
49
+ self._username = config.auth_cognito_username
50
+ self._password = config.auth_cognito_password
51
+ self._user_pool_id = config.auth_cognito_user_pool_id
52
+ self._region = config.auth_cognito_region
53
+
54
+ # Add debug log early in initialization
55
+ logger.debug(
56
+ f'Cognito auth configuration: Username={self._username}, ClientID={self._client_id}, '
57
+ f'Password={"SET" if self._password else "NOT SET"}, UserPoolID={self._user_pool_id or "NOT SET"}'
58
+ )
59
+
60
+ # Token management
61
+ self._token_expires_at = 0
62
+ self._refresh_token_value = None
63
+ self._token_lock = threading.RLock() # For thread safety
64
+
65
+ # Get initial token before parent initialization
66
+ try:
67
+ # Only try to get token if we have the minimum required credentials
68
+ if self._client_id and self._username and self._password:
69
+ token = self._get_cognito_token()
70
+ if token:
71
+ # Set token in config for parent class to use
72
+ config.auth_token = token
73
+ else:
74
+ logger.warning(
75
+ 'Missing required Cognito credentials, skipping initial token acquisition'
76
+ )
77
+ except Exception as e:
78
+ logger.warning(f'Failed to get initial Cognito token: {e}')
79
+ # We'll let the parent validation handle this error
80
+
81
+ # Call parent initializer which will validate and initialize auth
82
+ # This will set self._token from config.auth_token
83
+ super().__init__(config)
84
+
85
+ def _validate_config(self) -> bool:
86
+ """Validate the configuration.
87
+
88
+ Returns:
89
+ bool: True if all required parameters are provided, False otherwise
90
+
91
+ Raises:
92
+ MissingCredentialsError: If required parameters are missing
93
+ ConfigurationError: If configuration is invalid
94
+
95
+ """
96
+ # Validate required parameters
97
+ if not self._client_id:
98
+ raise MissingCredentialsError(
99
+ 'Cognito authentication requires a client ID',
100
+ {
101
+ 'help': 'Provide client ID using --auth-cognito-client-id command line argument or AUTH_COGNITO_CLIENT_ID environment variable'
102
+ },
103
+ )
104
+
105
+ if not self._username:
106
+ raise MissingCredentialsError(
107
+ 'Cognito authentication requires a username',
108
+ {
109
+ 'help': 'Provide username using --auth-cognito-username command line argument or AUTH_COGNITO_USERNAME environment variable'
110
+ },
111
+ )
112
+
113
+ if not self._password:
114
+ raise MissingCredentialsError(
115
+ 'Cognito authentication requires a password',
116
+ {
117
+ 'help': 'Provide password using --auth-cognito-password command line argument or AUTH_COGNITO_PASSWORD environment variable'
118
+ },
119
+ )
120
+
121
+ # Let parent class validate the token
122
+ return super()._validate_config()
123
+
124
+ def _log_validation_error(self) -> None:
125
+ """Log validation error messages."""
126
+ logger.error('Cognito authentication requires client ID, username, and password.')
127
+ logger.error(
128
+ 'Please provide client ID using --auth-cognito-client-id, username using --auth-cognito-username, '
129
+ 'and password using --auth-cognito-password command line arguments or corresponding environment variables.'
130
+ )
131
+
132
+ def get_auth_headers(self) -> Dict[str, str]:
133
+ """Get authentication headers with auto-refresh.
134
+
135
+ Returns:
136
+ Dict[str, str]: Authentication headers
137
+
138
+ """
139
+ # Check if token needs refreshing and refresh if necessary
140
+ self._check_and_refresh_token_if_needed()
141
+
142
+ # Delegate to parent class for header generation
143
+ return super().get_auth_headers()
144
+
145
+ def _check_and_refresh_token_if_needed(self) -> None:
146
+ """Check if token needs refreshing and refresh if necessary."""
147
+ with self._token_lock:
148
+ if self._is_token_expired_or_expiring_soon():
149
+ self._refresh_token()
150
+
151
+ def _is_token_expired_or_expiring_soon(self) -> bool:
152
+ """Check if token is expired or will expire soon.
153
+
154
+ Returns:
155
+ bool: True if token is expired or will expire soon, False otherwise
156
+
157
+ """
158
+ # Add buffer time (5 minutes) to refresh before actual expiration
159
+ buffer_seconds = 300
160
+ return time.time() + buffer_seconds >= self._token_expires_at
161
+
162
+ def _refresh_token(self) -> None:
163
+ """Refresh the token if possible, or re-authenticate.
164
+
165
+ Logs at INFO level when token is refreshed.
166
+ """
167
+ try:
168
+ old_token = self._token
169
+ new_token = None
170
+
171
+ # Try using refresh token if available
172
+ if self._refresh_token_value:
173
+ logger.debug(f'Attempting to refresh Cognito token for user: {self._username}')
174
+ new_token = self._refresh_cognito_token()
175
+
176
+ # If refresh failed or no refresh token available, re-authenticate
177
+ if not new_token:
178
+ logger.debug(f'Re-authenticating Cognito user: {self._username}')
179
+ new_token = self._get_cognito_token()
180
+
181
+ # Update token if we got a new one
182
+ if new_token and new_token != old_token:
183
+ self._token = new_token
184
+ logger.info(f'Cognito token refreshed for user: {self._username}')
185
+
186
+ # Force parent class to regenerate auth headers with new token
187
+ self._initialize_auth()
188
+ else:
189
+ logger.debug('Token refresh did not result in a new token')
190
+
191
+ except Exception as e:
192
+ logger.error(f'Failed to refresh token: {e}')
193
+ raise ExpiredTokenError('Token refresh failed', {'error': str(e)})
194
+
195
+ def _get_cognito_token(self) -> Optional[str]:
196
+ """Get a new token from Cognito using username/password.
197
+
198
+ Returns:
199
+ str: Cognito ID token or None if authentication fails
200
+
201
+ Raises:
202
+ AuthenticationError: If authentication fails
203
+
204
+ """
205
+ client = boto3.client('cognito-idp', region_name=self._region)
206
+
207
+ try:
208
+ logger.debug(f'Authenticating with Cognito for user: {self._username}')
209
+
210
+ # Log parameters for debugging (without sensitive info)
211
+ logger.debug(f'Initiating auth with ClientId: {self._client_id}')
212
+ logger.debug('AuthFlow: USER_PASSWORD_AUTH')
213
+ logger.debug(f'USERNAME parameter provided: {self._username}')
214
+ logger.debug(
215
+ f'PASSWORD parameter provided: {"*" * (len(self._password) if self._password else 0)}'
216
+ )
217
+
218
+ # Add clear confirmation of required variables
219
+ logger.debug(
220
+ f'Cognito auth configuration: Username={self._username}, ClientID={self._client_id}, Password={"SET" if self._password else "NOT SET"}'
221
+ )
222
+
223
+ # Try with different parameter formats
224
+ # Format 1: Standard format
225
+ auth_params = {'USERNAME': self._username, 'PASSWORD': self._password}
226
+
227
+ # Add user pool ID if provided (some configurations might require this)
228
+ if self._user_pool_id:
229
+ logger.debug(f'User pool ID provided: {self._user_pool_id}')
230
+ # Some Cognito configurations might use this format
231
+ auth_params['UserPoolId'] = self._user_pool_id
232
+
233
+ # Try with USER_PASSWORD_AUTH flow first
234
+ try:
235
+ logger.debug('Trying USER_PASSWORD_AUTH flow')
236
+ response = client.initiate_auth(
237
+ ClientId=self._client_id,
238
+ AuthFlow='USER_PASSWORD_AUTH',
239
+ AuthParameters=auth_params,
240
+ )
241
+ except client.exceptions.InvalidParameterException:
242
+ # If USER_PASSWORD_AUTH fails, try ADMIN_USER_PASSWORD_AUTH flow
243
+ # This requires user pool ID
244
+ if self._user_pool_id:
245
+ logger.debug('USER_PASSWORD_AUTH failed, trying ADMIN_USER_PASSWORD_AUTH flow')
246
+ logger.debug(f'Using user pool ID: {self._user_pool_id}')
247
+
248
+ # ADMIN_USER_PASSWORD_AUTH requires admin credentials
249
+ # This will use the AWS credentials from the environment
250
+ response = client.admin_initiate_auth(
251
+ UserPoolId=self._user_pool_id,
252
+ ClientId=self._client_id,
253
+ AuthFlow='ADMIN_USER_PASSWORD_AUTH',
254
+ AuthParameters={'USERNAME': self._username, 'PASSWORD': self._password},
255
+ )
256
+ else:
257
+ # Re-raise the original exception if we can't try ADMIN_USER_PASSWORD_AUTH
258
+ logger.error(
259
+ 'USER_PASSWORD_AUTH failed and no user pool ID provided for ADMIN_USER_PASSWORD_AUTH'
260
+ )
261
+ raise
262
+
263
+ auth_result = response.get('AuthenticationResult', {})
264
+
265
+ # Store the refresh token
266
+ self._refresh_token_value = auth_result.get('RefreshToken')
267
+
268
+ # Extract token expiry from ID token
269
+ id_token = auth_result.get('IdToken')
270
+ if id_token:
271
+ self._token_expires_at = self._extract_token_expiry(id_token)
272
+
273
+ # Get the ID token
274
+ id_token = auth_result.get('IdToken')
275
+ if id_token:
276
+ # Extract token expiry
277
+ self._token_expires_at = self._extract_token_expiry(id_token)
278
+
279
+ # Log token acquisition at INFO level
280
+ logger.info(f'Obtained new Cognito ID token for user: {self._username}')
281
+
282
+ # Log token length for debugging
283
+ token_length = len(id_token) if id_token else 0
284
+ logger.debug(f'Token length: {token_length} characters')
285
+
286
+ return id_token
287
+ else:
288
+ logger.error('No ID token found in authentication result')
289
+ return None
290
+
291
+ except client.exceptions.NotAuthorizedException as e:
292
+ logger.error(f'Authentication failed: {e}')
293
+ logger.error('Please check your Cognito credentials (client ID, username, password)')
294
+ logger.error(
295
+ 'Make sure the user exists in the Cognito User Pool and the password is correct'
296
+ )
297
+ raise InvalidCredentialsError(
298
+ 'Invalid Cognito credentials',
299
+ {
300
+ 'error': str(e),
301
+ 'help': 'Check your Cognito credentials and ensure the user exists in the User Pool',
302
+ },
303
+ )
304
+ except client.exceptions.UserNotConfirmedException as e:
305
+ logger.error(f'User not confirmed: {e}')
306
+ logger.error('The user exists but has not been confirmed in the Cognito User Pool')
307
+ logger.error(
308
+ 'Please confirm the user in the AWS Console or use the AWS CLI to confirm the user'
309
+ )
310
+ raise ConfigurationError(
311
+ 'User not confirmed',
312
+ {
313
+ 'error': str(e),
314
+ 'help': 'Confirm the user in the AWS Console or use the AWS CLI',
315
+ },
316
+ )
317
+ except client.exceptions.InvalidParameterException as e:
318
+ logger.error(f'Invalid parameter: {e}')
319
+ # Check if the error message contains information about which parameter is missing
320
+ error_msg = str(e)
321
+ if 'Missing required parameter' in error_msg:
322
+ logger.error('Missing required parameter for Cognito authentication')
323
+ logger.error(f'Client ID: {self._client_id}')
324
+ logger.error(f'Username provided: {bool(self._username)}')
325
+ logger.error(f'Password provided: {bool(self._password)}')
326
+ logger.error(f'User Pool ID provided: {bool(self._user_pool_id)}')
327
+
328
+ # Check specific parameters
329
+ if not self._client_id:
330
+ raise MissingCredentialsError(
331
+ 'Missing Cognito client ID',
332
+ {
333
+ 'error': error_msg,
334
+ 'help': 'Provide client ID using --auth-cognito-client-id or AUTH_COGNITO_CLIENT_ID',
335
+ },
336
+ )
337
+ elif not self._username:
338
+ raise MissingCredentialsError(
339
+ 'Missing Cognito username',
340
+ {
341
+ 'error': error_msg,
342
+ 'help': 'Provide username using --auth-cognito-username or AUTH_COGNITO_USERNAME',
343
+ },
344
+ )
345
+ elif not self._password:
346
+ raise MissingCredentialsError(
347
+ 'Missing Cognito password',
348
+ {
349
+ 'error': error_msg,
350
+ 'help': 'Provide password using --auth-cognito-password or AUTH_COGNITO_PASSWORD',
351
+ },
352
+ )
353
+ elif not self._user_pool_id:
354
+ logger.error('User Pool ID might be required for this Cognito configuration')
355
+ raise ConfigurationError(
356
+ 'Missing User Pool ID for Cognito authentication',
357
+ {
358
+ 'error': error_msg,
359
+ 'help': 'Provide User Pool ID using --auth-cognito-user-pool-id or AUTH_COGNITO_USER_POOL_ID',
360
+ },
361
+ )
362
+ else:
363
+ raise ConfigurationError(
364
+ 'Missing required parameter for Cognito authentication',
365
+ {
366
+ 'error': error_msg,
367
+ 'help': 'Check the error message for details on which parameter is missing',
368
+ },
369
+ )
370
+ else:
371
+ raise ConfigurationError(
372
+ f'Invalid parameter for Cognito authentication: {error_msg}',
373
+ {
374
+ 'error': error_msg,
375
+ 'help': 'Check the error message for details on which parameter is invalid',
376
+ },
377
+ )
378
+ except client.exceptions.ResourceNotFoundException as e:
379
+ logger.error(f'Resource not found: {e}')
380
+ logger.error('The specified Cognito User Pool or Client ID does not exist')
381
+ raise ConfigurationError(
382
+ 'Cognito resource not found',
383
+ {'error': str(e), 'help': 'Check your User Pool ID and Client ID'},
384
+ )
385
+ except Exception as e:
386
+ logger.error(f'Cognito authentication error: {e}')
387
+ logger.error(
388
+ 'This could be due to network issues, AWS credentials, or Cognito configuration'
389
+ )
390
+ raise NetworkError(
391
+ 'Cognito authentication failed',
392
+ {'error': str(e), 'help': 'Check your network connection and AWS credentials'},
393
+ )
394
+
395
+ def _refresh_cognito_token(self) -> Optional[str]:
396
+ """Refresh the Cognito token using the refresh token.
397
+
398
+ Returns:
399
+ str: New Cognito ID token or None if refresh fails
400
+
401
+ Raises:
402
+ AuthenticationError: If token refresh fails
403
+
404
+ """
405
+ client = boto3.client('cognito-idp', region_name=self._region)
406
+
407
+ try:
408
+ logger.debug(f'Refreshing token for user: {self._username}')
409
+
410
+ # Try with standard REFRESH_TOKEN_AUTH flow first
411
+ try:
412
+ logger.debug('Trying REFRESH_TOKEN_AUTH flow')
413
+ response = client.initiate_auth(
414
+ ClientId=self._client_id,
415
+ AuthFlow='REFRESH_TOKEN_AUTH',
416
+ AuthParameters={'REFRESH_TOKEN': self._refresh_token_value},
417
+ )
418
+ except client.exceptions.InvalidParameterException:
419
+ # If REFRESH_TOKEN_AUTH fails, try ADMIN_REFRESH_TOKEN_AUTH flow
420
+ # This requires user pool ID
421
+ if self._user_pool_id:
422
+ logger.debug('REFRESH_TOKEN_AUTH failed, trying ADMIN_REFRESH_TOKEN_AUTH flow')
423
+ logger.debug(f'Using user pool ID: {self._user_pool_id}')
424
+
425
+ # ADMIN_REFRESH_TOKEN_AUTH requires admin credentials
426
+ # This will use the AWS credentials from the environment
427
+ response = client.admin_initiate_auth(
428
+ UserPoolId=self._user_pool_id,
429
+ ClientId=self._client_id,
430
+ AuthFlow='REFRESH_TOKEN',
431
+ AuthParameters={'REFRESH_TOKEN': self._refresh_token_value},
432
+ )
433
+ else:
434
+ # Re-raise the original exception if we can't try ADMIN_REFRESH_TOKEN_AUTH
435
+ logger.error(
436
+ 'REFRESH_TOKEN_AUTH failed and no user pool ID provided for ADMIN_REFRESH_TOKEN_AUTH'
437
+ )
438
+ raise
439
+
440
+ auth_result = response.get('AuthenticationResult', {})
441
+
442
+ # Extract token expiry from ID token
443
+ id_token = auth_result.get('IdToken')
444
+ if id_token:
445
+ self._token_expires_at = self._extract_token_expiry(id_token)
446
+
447
+ # Get the ID token
448
+ id_token = auth_result.get('IdToken')
449
+ if id_token:
450
+ # Extract token expiry
451
+ self._token_expires_at = self._extract_token_expiry(id_token)
452
+
453
+ # Log token refresh at INFO level
454
+ logger.info(f'Successfully refreshed Cognito ID token for user: {self._username}')
455
+
456
+ # Log token length for debugging
457
+ token_length = len(id_token) if id_token else 0
458
+ logger.debug(f'Token length: {token_length} characters')
459
+
460
+ return id_token
461
+ else:
462
+ logger.error('No ID token found in refresh result')
463
+ return None
464
+
465
+ except client.exceptions.NotAuthorizedException:
466
+ logger.warning('Refresh token expired, falling back to re-authentication')
467
+ return None # Will trigger a full re-authentication
468
+ except Exception as e:
469
+ logger.error(f'Token refresh error: {e}')
470
+ return None # Will trigger a full re-authentication
471
+
472
+ def _extract_token_expiry(self, token: str) -> int:
473
+ """Extract expiry timestamp from token.
474
+
475
+ Args:
476
+ token: JWT token
477
+
478
+ Returns:
479
+ int: Expiry timestamp
480
+
481
+ """
482
+ try:
483
+ # Parse the JWT token without using the decode function
484
+ # JWT tokens are in the format: header.payload.signature
485
+ # We only need the payload part to extract the expiry
486
+ parts = token.split('.')
487
+ if len(parts) != 3:
488
+ raise ValueError('Invalid JWT token format')
489
+
490
+ # The payload is base64url encoded
491
+ # Add padding if needed
492
+ payload = parts[1]
493
+ padding = '=' * ((4 - len(payload) % 4) % 4) # Fix padding calculation
494
+
495
+ # Replace URL-safe characters and decode
496
+ payload = payload.replace('-', '+').replace('_', '/') + padding
497
+
498
+ try:
499
+ import base64
500
+
501
+ decoded_payload = base64.b64decode(payload).decode('utf-8')
502
+ import json
503
+
504
+ payload_data = json.loads(decoded_payload)
505
+ exp_time = payload_data.get('exp', 0)
506
+
507
+ # Log the expiry duration at INFO level
508
+ if exp_time > 0:
509
+ current_time = int(time.time())
510
+ duration_seconds = exp_time - current_time
511
+ duration_minutes = duration_seconds / 60
512
+ duration_hours = duration_minutes / 60
513
+
514
+ if duration_seconds > 0:
515
+ logger.info(
516
+ f'Token expires in {duration_hours:.2f} hours ({duration_minutes:.0f} minutes)'
517
+ )
518
+ else:
519
+ logger.info(f'Token is already expired by {-duration_seconds} seconds')
520
+
521
+ return exp_time
522
+ except Exception as e:
523
+ logger.warning(f'Failed to decode payload: {e}')
524
+ raise
525
+ except Exception as e:
526
+ logger.warning(f'Failed to extract token expiry: {e}')
527
+ # Default to 1 hour from now if extraction fails
528
+ return int(time.time()) + 3600
529
+
530
+ @property
531
+ def provider_name(self) -> str:
532
+ """Get the name of the authentication provider.
533
+
534
+ Returns:
535
+ str: Name of the authentication provider
536
+
537
+ """
538
+ return 'cognito'
@@ -0,0 +1,100 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Register authentication providers."""
15
+
16
+ import os
17
+ from awslabs.openapi_mcp_server import logger
18
+ from awslabs.openapi_mcp_server.auth.auth_factory import register_auth_provider
19
+
20
+
21
+ def register_auth_providers() -> None:
22
+ """Register authentication providers based on configuration.
23
+
24
+ This function registers only the authentication provider that is specified
25
+ by the AUTH_TYPE environment variable or command-line argument.
26
+ If no auth type is specified, it registers all available providers.
27
+ """
28
+ # Get the auth type from environment variable
29
+ auth_type = os.environ.get('AUTH_TYPE', '').lower()
30
+
31
+ # If no auth type is specified in the environment, register all providers
32
+ if not auth_type:
33
+ logger.debug('No auth type specified in environment, registering all providers')
34
+ register_all_providers()
35
+ else:
36
+ # Register only the specified provider
37
+ register_provider_by_type(auth_type)
38
+
39
+
40
+ def register_provider_by_type(auth_type: str) -> None:
41
+ """Register a specific authentication provider by type.
42
+
43
+ Args:
44
+ auth_type: The type of authentication provider to register
45
+
46
+ """
47
+ if auth_type == 'bearer':
48
+ from awslabs.openapi_mcp_server.auth.bearer_auth import BearerAuthProvider
49
+
50
+ register_auth_provider('bearer', BearerAuthProvider)
51
+ logger.info('Registered Bearer authentication provider')
52
+ elif auth_type == 'basic':
53
+ from awslabs.openapi_mcp_server.auth.basic_auth import BasicAuthProvider
54
+
55
+ register_auth_provider('basic', BasicAuthProvider)
56
+ logger.info('Registered Basic authentication provider')
57
+ elif auth_type == 'api_key':
58
+ from awslabs.openapi_mcp_server.auth.api_key_auth import ApiKeyAuthProvider
59
+
60
+ register_auth_provider('api_key', ApiKeyAuthProvider)
61
+ logger.info('Registered Api_Key authentication provider')
62
+ elif auth_type == 'cognito':
63
+ from awslabs.openapi_mcp_server.auth.cognito_auth import CognitoAuthProvider
64
+
65
+ register_auth_provider('cognito', CognitoAuthProvider)
66
+ logger.info('Registered Cognito authentication provider')
67
+ else:
68
+ logger.warning(f'Unknown auth type: {auth_type}, registering all providers')
69
+ register_all_providers()
70
+
71
+
72
+ def register_all_providers() -> None:
73
+ """Register all available authentication providers."""
74
+ # Import all provider classes
75
+ from awslabs.openapi_mcp_server.auth.api_key_auth import ApiKeyAuthProvider
76
+ from awslabs.openapi_mcp_server.auth.basic_auth import BasicAuthProvider
77
+ from awslabs.openapi_mcp_server.auth.bearer_auth import BearerAuthProvider
78
+
79
+ # Register the standard providers
80
+ register_auth_provider('bearer', BearerAuthProvider)
81
+ logger.info('Registered Bearer authentication provider')
82
+
83
+ register_auth_provider('basic', BasicAuthProvider)
84
+ logger.info('Registered Basic authentication provider')
85
+
86
+ register_auth_provider('api_key', ApiKeyAuthProvider)
87
+ logger.info('Registered Api_Key authentication provider')
88
+
89
+ # Only register Cognito if it's available
90
+ try:
91
+ from awslabs.openapi_mcp_server.auth.cognito_auth import CognitoAuthProvider
92
+
93
+ register_auth_provider('cognito', CognitoAuthProvider)
94
+ logger.info('Registered Cognito authentication provider')
95
+ except ImportError:
96
+ logger.debug('Cognito authentication provider not available')
97
+
98
+
99
+ # Don't register providers automatically when this module is imported
100
+ # This will be done explicitly in server.py
@@ -0,0 +1,17 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Patch module for OpenAPI MCP Server."""
15
+
16
+ # This package contains patches to improve the functionality of the OpenAPI MCP Server
17
+ # and other third-party libraries it depends on.
@@ -0,0 +1,18 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """MCP prompt generation for OpenAPI specifications."""
15
+
16
+ from awslabs.openapi_mcp_server.prompts.prompt_manager import MCPPromptManager
17
+
18
+ __all__ = ['MCPPromptManager']