awslabs.openapi-mcp-server 0.1.1__py3-none-any.whl → 0.2.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.
@@ -15,7 +15,7 @@
15
15
  OpenAPI MCP Server - A server that dynamically creates MCP tools and resources from OpenAPI specifications.
16
16
  """
17
17
 
18
- __version__ = '0.1.0'
18
+ __version__ = '0.2.1'
19
19
 
20
20
 
21
21
  import inspect
@@ -42,17 +42,20 @@ class Config:
42
42
  auth_cognito_client_id: str = ''
43
43
  auth_cognito_username: str = ''
44
44
  auth_cognito_password: str = ''
45
+ auth_cognito_client_secret: str = ''
46
+ auth_cognito_domain: str = '' # Required for client credentials flow
47
+ auth_cognito_scopes: str = '' # Optional, comma-separated list of scopes
45
48
  auth_cognito_user_pool_id: str = ''
46
49
  auth_cognito_region: str = 'us-east-1'
47
50
 
48
51
  # Server configuration
49
- port: int = 8000
50
52
  # Default to localhost for security; use SERVER_HOST env var to override when needed (e.g. in Docker)
51
53
  host: str = '127.0.0.1'
54
+ port: int = 8000
52
55
  debug: bool = False
53
56
  transport: str = 'stdio' # stdio only
54
57
  message_timeout: int = 60
55
- version: str = '0.1.0'
58
+ version: str = '0.2.0'
56
59
 
57
60
 
58
61
  def load_config(args: Any = None) -> Config:
@@ -93,11 +96,14 @@ def load_config(args: Any = None) -> Config:
93
96
  'AUTH_COGNITO_CLIENT_ID': (lambda v: setattr(config, 'auth_cognito_client_id', v)),
94
97
  'AUTH_COGNITO_USERNAME': (lambda v: setattr(config, 'auth_cognito_username', v)),
95
98
  'AUTH_COGNITO_PASSWORD': (lambda v: setattr(config, 'auth_cognito_password', v)),
99
+ 'AUTH_COGNITO_CLIENT_SECRET': (lambda v: setattr(config, 'auth_cognito_client_secret', v)),
100
+ 'AUTH_COGNITO_DOMAIN': (lambda v: setattr(config, 'auth_cognito_domain', v)),
101
+ 'AUTH_COGNITO_SCOPES': (lambda v: setattr(config, 'auth_cognito_scopes', v)),
96
102
  'AUTH_COGNITO_USER_POOL_ID': (lambda v: setattr(config, 'auth_cognito_user_pool_id', v)),
97
103
  'AUTH_COGNITO_REGION': (lambda v: setattr(config, 'auth_cognito_region', v)),
98
104
  # Server configuration
99
- 'SERVER_PORT': (lambda v: setattr(config, 'port', int(v))),
100
105
  'SERVER_HOST': (lambda v: setattr(config, 'host', v)),
106
+ 'SERVER_PORT': (lambda v: setattr(config, 'port', int(v))),
101
107
  'SERVER_DEBUG': (lambda v: setattr(config, 'debug', v.lower() == 'true')),
102
108
  'SERVER_TRANSPORT': (lambda v: setattr(config, 'transport', v)),
103
109
  'SERVER_MESSAGE_TIMEOUT': (lambda v: setattr(config, 'message_timeout', int(v))),
@@ -184,6 +190,18 @@ def load_config(args: Any = None) -> Config:
184
190
  logger.debug('Setting Cognito password from arguments')
185
191
  config.auth_cognito_password = args.auth_cognito_password
186
192
 
193
+ if hasattr(args, 'auth_cognito_client_secret') and args.auth_cognito_client_secret:
194
+ logger.debug('Setting Cognito client secret from arguments')
195
+ config.auth_cognito_client_secret = args.auth_cognito_client_secret
196
+
197
+ if hasattr(args, 'auth_cognito_domain') and args.auth_cognito_domain:
198
+ logger.debug('Setting Cognito domain from arguments')
199
+ config.auth_cognito_domain = args.auth_cognito_domain
200
+
201
+ if hasattr(args, 'auth_cognito_scopes') and args.auth_cognito_scopes:
202
+ logger.debug('Setting Cognito scopes from arguments')
203
+ config.auth_cognito_scopes = args.auth_cognito_scopes
204
+
187
205
  if hasattr(args, 'auth_cognito_user_pool_id') and args.auth_cognito_user_pool_id:
188
206
  logger.debug('Setting Cognito user pool ID from arguments')
189
207
  config.auth_cognito_user_pool_id = args.auth_cognito_user_pool_id
@@ -193,8 +211,6 @@ def load_config(args: Any = None) -> Config:
193
211
  config.auth_cognito_region = args.auth_cognito_region
194
212
 
195
213
  # Log final configuration details
196
- logger.info(
197
- f'Configuration loaded: API name={config.api_name}, transport={config.transport}, port={config.port}'
198
- )
214
+ logger.info(f'Configuration loaded: API name={config.api_name}, transport={config.transport}')
199
215
 
200
216
  return config
@@ -32,9 +32,9 @@ from typing import Dict, Optional
32
32
  class CognitoAuthProvider(BearerAuthProvider):
33
33
  """Cognito User Pool authentication provider.
34
34
 
35
- This provider obtains ID tokens from AWS Cognito User Pools
35
+ This provider obtains tokens from AWS Cognito User Pools
36
36
  and delegates to BearerAuthProvider for adding Authorization headers
37
- to all HTTP requests.
37
+ to all HTTP requests. Supports both password and client credentials flows.
38
38
  """
39
39
 
40
40
  def __init__(self, config: Config):
@@ -48,15 +48,35 @@ class CognitoAuthProvider(BearerAuthProvider):
48
48
  self._client_id = config.auth_cognito_client_id
49
49
  self._username = config.auth_cognito_username
50
50
  self._password = config.auth_cognito_password
51
+ self._client_secret = config.auth_cognito_client_secret
52
+ self._domain = config.auth_cognito_domain
53
+ self._scopes = config.auth_cognito_scopes.split(',') if config.auth_cognito_scopes else []
51
54
  self._user_pool_id = config.auth_cognito_user_pool_id
52
55
  self._region = config.auth_cognito_region
53
56
 
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"}'
57
+ # Determine grant type based on provided credentials
58
+ self._grant_type = self._determine_grant_type()
59
+
60
+ # Log grant type selection at INFO level
61
+ logger.info(
62
+ f'Cognito auth using grant type: {self._grant_type} '
63
+ f'({"client_id and client_secret provided" if self._grant_type == "client_credentials" else "username and password provided"})'
58
64
  )
59
65
 
66
+ # Add debug log early in initialization
67
+ if self._grant_type == 'client_credentials':
68
+ logger.debug(
69
+ f'Cognito auth configuration: ClientID={self._client_id}, '
70
+ f'Client Secret={"SET" if self._client_secret else "NOT SET"}, '
71
+ f'Domain={self._domain or "NOT SET"}, '
72
+ f'Region={self._region}'
73
+ )
74
+ else:
75
+ logger.debug(
76
+ f'Cognito auth configuration: Username={self._username}, ClientID={self._client_id}, '
77
+ f'Password={"SET" if self._password else "NOT SET"}, UserPoolID={self._user_pool_id or "NOT SET"}'
78
+ )
79
+
60
80
  # Token management
61
81
  self._token_expires_at = 0
62
82
  self._refresh_token_value = None
@@ -65,7 +85,17 @@ class CognitoAuthProvider(BearerAuthProvider):
65
85
  # Get initial token before parent initialization
66
86
  try:
67
87
  # Only try to get token if we have the minimum required credentials
68
- if self._client_id and self._username and self._password:
88
+ if (
89
+ self._grant_type == 'client_credentials'
90
+ and self._client_id
91
+ and self._client_secret
92
+ and self._domain
93
+ ) or (
94
+ self._grant_type == 'password'
95
+ and self._client_id
96
+ and self._username
97
+ and self._password
98
+ ):
69
99
  token = self._get_cognito_token()
70
100
  if token:
71
101
  # Set token in config for parent class to use
@@ -76,12 +106,28 @@ class CognitoAuthProvider(BearerAuthProvider):
76
106
  )
77
107
  except Exception as e:
78
108
  logger.warning(f'Failed to get initial Cognito token: {e}')
79
- # We'll let the parent validation handle this error
109
+ # Set a placeholder token to avoid parent validation errors
110
+ config.auth_token = 'PENDING_COGNITO_TOKEN'
80
111
 
81
112
  # Call parent initializer which will validate and initialize auth
82
113
  # This will set self._token from config.auth_token
83
114
  super().__init__(config)
84
115
 
116
+ def _determine_grant_type(self) -> str:
117
+ """Determine the grant type based on provided credentials.
118
+
119
+ Returns:
120
+ str: The grant type to use ('client_credentials' or 'password')
121
+
122
+ """
123
+ if self._client_id and self._client_secret and self._domain:
124
+ return 'client_credentials'
125
+ elif self._client_id and self._username and self._password:
126
+ return 'password'
127
+ else:
128
+ # Default to password flow for backward compatibility
129
+ return 'password'
130
+
85
131
  def _validate_config(self) -> bool:
86
132
  """Validate the configuration.
87
133
 
@@ -102,21 +148,38 @@ class CognitoAuthProvider(BearerAuthProvider):
102
148
  },
103
149
  )
104
150
 
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
- )
151
+ # Validate based on grant type
152
+ if self._grant_type == 'client_credentials':
153
+ if not self._client_secret:
154
+ raise MissingCredentialsError(
155
+ 'Client credentials flow requires a client secret',
156
+ {
157
+ 'help': 'Provide client secret using --auth-cognito-client-secret command line argument or AUTH_COGNITO_CLIENT_SECRET environment variable'
158
+ },
159
+ )
160
+ if not self._domain:
161
+ raise MissingCredentialsError(
162
+ 'Client credentials flow requires a domain',
163
+ {
164
+ 'help': 'Provide domain using --auth-cognito-domain command line argument or AUTH_COGNITO_DOMAIN environment variable'
165
+ },
166
+ )
167
+ else: # password grant type
168
+ if not self._username:
169
+ raise MissingCredentialsError(
170
+ 'Password flow requires a username',
171
+ {
172
+ 'help': 'Provide username using --auth-cognito-username command line argument or AUTH_COGNITO_USERNAME environment variable'
173
+ },
174
+ )
112
175
 
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
- )
176
+ if not self._password:
177
+ raise MissingCredentialsError(
178
+ 'Password flow requires a password',
179
+ {
180
+ 'help': 'Provide password using --auth-cognito-password command line argument or AUTH_COGNITO_PASSWORD environment variable'
181
+ },
182
+ )
120
183
 
121
184
  # Let parent class validate the token
122
185
  return super()._validate_config()
@@ -193,10 +256,91 @@ class CognitoAuthProvider(BearerAuthProvider):
193
256
  raise ExpiredTokenError('Token refresh failed', {'error': str(e)})
194
257
 
195
258
  def _get_cognito_token(self) -> Optional[str]:
196
- """Get a new token from Cognito using username/password.
259
+ """Get a new token from Cognito using username/password or client credentials.
260
+
261
+ Returns:
262
+ str: Cognito token or None if authentication fails
263
+
264
+ Raises:
265
+ AuthenticationError: If authentication fails
266
+
267
+ """
268
+ if self._grant_type == 'client_credentials':
269
+ return self._get_token_client_credentials()
270
+ else:
271
+ return self._get_token_password()
272
+
273
+ def _get_token_client_credentials(self) -> Optional[str]:
274
+ """Get a token using the client credentials flow.
275
+
276
+ Returns:
277
+ str: Access token or None if authentication fails
278
+
279
+ Raises:
280
+ AuthenticationError: If authentication fails
281
+
282
+ """
283
+ try:
284
+ # Construct token endpoint using the provided domain
285
+ token_endpoint = (
286
+ f'https://{self._domain}.auth.{self._region}.amazoncognito.com/oauth2/token'
287
+ )
288
+ logger.debug(f'Using token endpoint: {token_endpoint}')
289
+
290
+ # Make the token request
291
+ import base64
292
+ import requests
293
+
294
+ # Create authorization header
295
+ auth_header = base64.b64encode(
296
+ f'{self._client_id}:{self._client_secret}'.encode('utf-8')
297
+ ).decode('utf-8')
298
+
299
+ headers = {
300
+ 'Content-Type': 'application/x-www-form-urlencoded',
301
+ 'Authorization': f'Basic {auth_header}',
302
+ }
303
+
304
+ data = {'grant_type': 'client_credentials'}
305
+ if self._scopes:
306
+ data['scope'] = ' '.join(self._scopes)
307
+ logger.debug(f'Using scopes: {data["scope"]}')
308
+
309
+ logger.debug(f'Making token request to: {token_endpoint}')
310
+ response = requests.post(token_endpoint, headers=headers, data=data)
311
+
312
+ if response.status_code != 200:
313
+ logger.error(f'Token request failed: {response.status_code} {response.text}')
314
+ raise InvalidCredentialsError(
315
+ 'Failed to obtain token with client credentials',
316
+ {
317
+ 'error': response.text,
318
+ 'help': 'Check your client ID, client secret, domain, and region',
319
+ },
320
+ )
321
+
322
+ # Process the response
323
+ token_data = response.json()
324
+ access_token = token_data.get('access_token')
325
+ expires_in = token_data.get('expires_in', 3600)
326
+
327
+ if access_token:
328
+ self._token_expires_at = int(time.time()) + expires_in
329
+ logger.info(f'Successfully obtained access token (expires in {expires_in} seconds)')
330
+ return access_token
331
+ else:
332
+ logger.error('No access token in response')
333
+ return None
334
+
335
+ except Exception as e:
336
+ logger.error(f'Error in client credentials flow: {e}')
337
+ raise
338
+
339
+ def _get_token_password(self) -> Optional[str]:
340
+ """Get a token using the password flow.
197
341
 
198
342
  Returns:
199
- str: Cognito ID token or None if authentication fails
343
+ str: ID token or None if authentication fails
200
344
 
201
345
  Raises:
202
346
  AuthenticationError: If authentication fails
@@ -393,7 +393,6 @@ def main():
393
393
  description='This project is a server that dynamically creates Model Context Protocol (MCP) tools and resources from OpenAPI specifications. It allows Large Language Models (LLMs) to interact with APIs through the Model Context Protocol.'
394
394
  )
395
395
  # Server configuration
396
- parser.add_argument('--port', type=int, help='Port to run the server on')
397
396
  parser.add_argument(
398
397
  '--log-level',
399
398
  choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
@@ -439,6 +438,17 @@ def main():
439
438
  '--auth-cognito-user-pool-id', help='User Pool ID for Cognito authentication'
440
439
  )
441
440
  parser.add_argument('--auth-cognito-region', help='AWS region for Cognito (default: us-east-1)')
441
+ parser.add_argument(
442
+ '--auth-cognito-client-secret',
443
+ help='Client secret for Cognito OAuth 2.0 client credentials flow',
444
+ )
445
+ parser.add_argument(
446
+ '--auth-cognito-domain', help='Domain prefix for Cognito OAuth 2.0 client credentials flow'
447
+ )
448
+ parser.add_argument(
449
+ '--auth-cognito-scopes',
450
+ help='Comma-separated list of scopes for Cognito OAuth 2.0 client credentials flow',
451
+ )
442
452
 
443
453
  args = parser.parse_args()
444
454
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: awslabs.openapi-mcp-server
3
- Version: 0.1.1
3
+ Version: 0.2.1
4
4
  Summary: An AWS Labs Model Context Protocol (MCP) server for OpenAPI
5
5
  Project-URL: Homepage, https://awslabs.github.io/mcp/
6
6
  Project-URL: Documentation, https://awslabs.github.io/mcp/servers/openapi-mcp-server/
@@ -21,40 +21,40 @@ Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Programming Language :: Python :: 3.13
23
23
  Requires-Python: >=3.10
24
- Requires-Dist: bcrypt>=4.0.0
25
- Requires-Dist: boto3>=1.28.0
26
- Requires-Dist: cachetools>=5.3.0
27
- Requires-Dist: fastmcp>=0.1.0
28
- Requires-Dist: httpx>=0.24.1
29
- Requires-Dist: loguru>=0.7.0
30
- Requires-Dist: openapi-spec-validator>=0.6.0
31
- Requires-Dist: prance>=23.6.21.0
32
- Requires-Dist: pydantic>=2.0.0
33
- Requires-Dist: pyyaml>=6.0.0
34
- Requires-Dist: tenacity>=8.2.0
35
- Requires-Dist: typing-extensions>=4.0.0
36
- Requires-Dist: uvicorn>=0.23.0
24
+ Requires-Dist: bcrypt>=4.3.0
25
+ Requires-Dist: boto3>=1.39.3
26
+ Requires-Dist: cachetools>=6.1.0
27
+ Requires-Dist: fastmcp>=2.10.2
28
+ Requires-Dist: httpx>=0.28.1
29
+ Requires-Dist: loguru>=0.7.3
30
+ Requires-Dist: openapi-spec-validator>=0.7.2
31
+ Requires-Dist: prance>=25.4.8.0
32
+ Requires-Dist: pydantic>=2.11.7
33
+ Requires-Dist: pyyaml>=6.0.2
34
+ Requires-Dist: tenacity>=9.1.2
35
+ Requires-Dist: typing-extensions>=4.14.1
36
+ Requires-Dist: uvicorn>=0.35.0
37
37
  Provides-Extra: all
38
38
  Requires-Dist: prometheus-client>=0.17.0; extra == 'all'
39
39
  Requires-Dist: pyyaml>=6.0.0; extra == 'all'
40
40
  Provides-Extra: dev
41
- Requires-Dist: commitizen>=4.4.1; extra == 'dev'
42
- Requires-Dist: lxml>=4.9.0; extra == 'dev'
41
+ Requires-Dist: commitizen>=4.8.3; extra == 'dev'
42
+ Requires-Dist: lxml>=6.0.0; extra == 'dev'
43
43
  Requires-Dist: pre-commit>=4.2.0; extra == 'dev'
44
- Requires-Dist: pyright>=1.1.398; extra == 'dev'
45
- Requires-Dist: pytest-asyncio>=0.21.1; extra == 'dev'
46
- Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
47
- Requires-Dist: pytest>=7.4.0; extra == 'dev'
48
- Requires-Dist: ruff>=0.11.2; extra == 'dev'
44
+ Requires-Dist: pyright>=1.1.402; extra == 'dev'
45
+ Requires-Dist: pytest-asyncio>=1.0.0; extra == 'dev'
46
+ Requires-Dist: pytest-cov>=6.2.1; extra == 'dev'
47
+ Requires-Dist: pytest>=8.4.1; extra == 'dev'
48
+ Requires-Dist: ruff>=0.12.2; extra == 'dev'
49
49
  Provides-Extra: prometheus
50
- Requires-Dist: prometheus-client>=0.17.0; extra == 'prometheus'
50
+ Requires-Dist: prometheus-client>=0.22.1; extra == 'prometheus'
51
51
  Provides-Extra: test
52
- Requires-Dist: pytest-asyncio>=0.21.0; extra == 'test'
53
- Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
54
- Requires-Dist: pytest-mock>=3.10.0; extra == 'test'
55
- Requires-Dist: pytest>=7.0.0; extra == 'test'
52
+ Requires-Dist: pytest-asyncio>=1.0.0; extra == 'test'
53
+ Requires-Dist: pytest-cov>=6.2.1; extra == 'test'
54
+ Requires-Dist: pytest-mock>=3.14.1; extra == 'test'
55
+ Requires-Dist: pytest>=8.4.1; extra == 'test'
56
56
  Provides-Extra: yaml
57
- Requires-Dist: pyyaml>=6.0.0; extra == 'yaml'
57
+ Requires-Dist: pyyaml>=6.0.2; extra == 'yaml'
58
58
  Description-Content-Type: text/markdown
59
59
 
60
60
  # AWS Labs OpenAPI MCP Server
@@ -86,6 +86,10 @@ This project is a server that dynamically creates Model Context Protocol (MCP) t
86
86
 
87
87
  ## Installation
88
88
 
89
+ | Cursor | VS Code |
90
+ |:------:|:-------:|
91
+ | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/en/install-mcp?name=awslabs.openapi-mcp-server&config=eyJjb21tYW5kIjoidXZ4IGF3c2xhYnMub3BlbmFwaS1tY3Atc2VydmVyQGxhdGVzdCIsImVudiI6eyJBUElfTkFNRSI6InlvdXItYXBpLW5hbWUiLCJBUElfQkFTRV9VUkwiOiJodHRwczovL2FwaS5leGFtcGxlLmNvbSIsIkFQSV9TUEVDX1VSTCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tL29wZW5hcGkuanNvbiIsIkxPR19MRVZFTCI6IkVSUk9SIiwiRU5BQkxFX1BST01FVEhFVVMiOiJmYWxzZSIsIkVOQUJMRV9PUEVSQVRJT05fUFJPTVBUUyI6InRydWUiLCJVVklDT1JOX1RJTUVPVVRfR1JBQ0VGVUxfU0hVVERPV04iOiI1LjAiLCJVVklDT1JOX0dSQUNFRlVMX1NIVVRET1dOIjoidHJ1ZSJ9LCJkaXNhYmxlZCI6ZmFsc2UsImF1dG9BcHByb3ZlIjpbXX0%3D) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=OpenAPI%20MCP%20Server&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.openapi-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22API_NAME%22%3A%22your-api-name%22%2C%22API_BASE_URL%22%3A%22https%3A%2F%2Fapi.example.com%22%2C%22API_SPEC_URL%22%3A%22https%3A%2F%2Fapi.example.com%2Fopenapi.json%22%2C%22LOG_LEVEL%22%3A%22ERROR%22%2C%22ENABLE_PROMETHEUS%22%3A%22false%22%2C%22ENABLE_OPERATION_PROMPTS%22%3A%22true%22%2C%22UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN%22%3A%225.0%22%2C%22UVICORN_GRACEFUL_SHUTDOWN%22%3A%22true%22%7D%2C%22disabled%22%3Afalse%2C%22autoApprove%22%3A%5B%5D%7D) |
92
+
89
93
  ### From PyPI
90
94
 
91
95
  ```bash
@@ -174,7 +178,7 @@ awslabs.openapi-mcp-server --api-url https://api.example.com --spec-url https://
174
178
  awslabs.openapi-mcp-server --api-url https://api.example.com --spec-url https://api.example.com/openapi.json --auth-type api_key --auth-api-key YOUR_API_KEY --auth-api-key-name X-API-Key --auth-api-key-in header # pragma: allowlist secret
175
179
  ```
176
180
 
177
- For detailed information about authentication methods, configuration options, and examples, see [AUTHENTICATION.md](AUTHENTICATION.md).
181
+ For detailed information about authentication methods, configuration options, and examples, see [AUTHENTICATION.md](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/AUTHENTICATION.md).
178
182
 
179
183
  ### Local OpenAPI Specification
180
184
 
@@ -259,11 +263,11 @@ export AUTH_API_KEY_IN="header" # Where to place the API key (options: header,
259
263
 
260
264
  The OpenAPI MCP Server includes comprehensive documentation to help you get started and make the most of its features:
261
265
 
262
- - [**AUTHENTICATION.md**](AUTHENTICATION.md): Detailed information about authentication methods, configuration options, and troubleshooting
263
- - [**DEPLOYMENT.md**](DEPLOYMENT.md): Guidelines for deploying the server in various environments, including Docker and AWS
264
- - [**AWS_BEST_PRACTICES.md**](AWS_BEST_PRACTICES.md): AWS best practices implemented in the server for resilience, caching, and efficiency
265
- - [**OBSERVABILITY.md**](OBSERVABILITY.md): Information about metrics, logging, and monitoring capabilities
266
- - [**tests/README.md**](tests/README.md): Overview of the test structure and strategy
266
+ - [**AUTHENTICATION.md**](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/AUTHENTICATION.md): Detailed information about authentication methods, configuration options, and troubleshooting
267
+ - [**DEPLOYMENT.md**](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/DEPLOYMENT.md): Guidelines for deploying the server in various environments, including Docker and AWS
268
+ - [**AWS_BEST_PRACTICES.md**](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/AWS_BEST_PRACTICES.md): AWS best practices implemented in the server for resilience, caching, and efficiency
269
+ - [**OBSERVABILITY.md**](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/OBSERVABILITY.md): Information about metrics, logging, and monitoring capabilities
270
+ - [**tests/README.md**](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/tests/README.md): Overview of the test structure and strategy
267
271
 
268
272
  ## AWS Best Practices
269
273
 
@@ -273,7 +277,7 @@ The OpenAPI MCP Server implements AWS best practices for building resilient, obs
273
277
  - **Resilience**: Patterns to handle transient failures and ensure high availability
274
278
  - **Observability**: Comprehensive monitoring, metrics, and logging features
275
279
 
276
- For detailed information about these features, including implementation details and configuration options, see [AWS_BEST_PRACTICES.md](AWS_BEST_PRACTICES.md).
280
+ For detailed information about these features, including implementation details and configuration options, see [AWS_BEST_PRACTICES.md](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/AWS_BEST_PRACTICES.md).
277
281
 
278
282
  ## Docker Deployment
279
283
 
@@ -299,7 +303,7 @@ docker run -p 8000:8000 \
299
303
  openapi-mcp-server:latest
300
304
  ```
301
305
 
302
- For detailed information about Docker deployment, AWS service integration, and transport considerations, see the [DEPLOYMENT.md](DEPLOYMENT.md) file.
306
+ For detailed information about Docker deployment, AWS service integration, and transport considerations, see the [DEPLOYMENT.md](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/DEPLOYMENT.md) file.
303
307
 
304
308
  ## Testing
305
309
 
@@ -331,7 +335,7 @@ The test suite covers:
331
335
  5. **Metrics**: Tests for metrics collection and reporting
332
336
  6. **OpenAPI Validation**: Tests for OpenAPI specification validation
333
337
 
334
- For more information about the test structure and strategy, see the [tests/README.md](tests/README.md) file.
338
+ For more information about the test structure and strategy, see the [tests/README.md](https://github.com/awslabs/mcp/blob/main/src/openapi-mcp-server/tests/README.md) file.
335
339
 
336
340
  ## Instructions
337
341
 
@@ -1,8 +1,8 @@
1
1
  awslabs/__init__.py,sha256=WuqxdDgUZylWNmVoPKiK7qGsTB_G4UmuXIrJ-VBwDew,731
2
- awslabs/openapi_mcp_server/__init__.py,sha256=i5uLJ1Fb0BEzuqKgn9nHUp18pvRhu_OZiuerlNm-NZ0,2060
3
- awslabs/openapi_mcp_server/server.py,sha256=EmCnLVJOoUAeij76F9jD3XII3N7NnYQRzsVs6avY4Gw,21389
2
+ awslabs/openapi_mcp_server/__init__.py,sha256=0aJ0v_y0NpVNNAL-lNWFXzVQjlGi8q9HrvyU4GsoG30,2060
3
+ awslabs/openapi_mcp_server/server.py,sha256=C_uJoyhCwxe6ohCZZL04HqDCOzUDbJHtPc-dBuX8U18,21746
4
4
  awslabs/openapi_mcp_server/api/__init__.py,sha256=KWcmd1bH1vact1QJBfR0zFX7knWhFrBgaMEe9Tu9qi0,774
5
- awslabs/openapi_mcp_server/api/config.py,sha256=0MptnSFtS37GzQPhbbCwWh9CeYOxAu6tlCKRsUzMwow,8404
5
+ awslabs/openapi_mcp_server/api/config.py,sha256=WT9ELzBOtZkd_DrzrkL_uuVoDibw2k94tU28CvHL32Q,9503
6
6
  awslabs/openapi_mcp_server/auth/__init__.py,sha256=wDFPpe2PmaDVvlYSdzR4saSKthgQmVPr9lwaKe3Z2RE,1109
7
7
  awslabs/openapi_mcp_server/auth/api_key_auth.py,sha256=VfnyTaMkVOpdYDKjjjEuJ3rBOmvWAkQgmoUxNn9_ftM,7107
8
8
  awslabs/openapi_mcp_server/auth/auth_cache.py,sha256=bCLKBD5kMcD0XwoTa3hKD9TG9rZoEYBBzK0rvaaSWZ0,5256
@@ -13,7 +13,7 @@ awslabs/openapi_mcp_server/auth/auth_provider.py,sha256=z9OSkbxxIrOysxN4-L3D7ZLk
13
13
  awslabs/openapi_mcp_server/auth/base_auth.py,sha256=9xkqh4GvQiD4jHH-_rqFa6tVOQaO_hNsEstkq0NzPMI,7021
14
14
  awslabs/openapi_mcp_server/auth/basic_auth.py,sha256=3sdNEZYX3qnkINmpvNKWVqTx31X1eOwbWMvkQkOda2Y,6166
15
15
  awslabs/openapi_mcp_server/auth/bearer_auth.py,sha256=KbX1GVeiI_-XNteM66jyRYilO461qXXg6mO5yyaDoG8,3769
16
- awslabs/openapi_mcp_server/auth/cognito_auth.py,sha256=cBkM805xeIg_1bsNjXj4mlXmfcfQBbfFQ2lnYvPpflU,22736
16
+ awslabs/openapi_mcp_server/auth/cognito_auth.py,sha256=mKuQpKyKoqtxTa8FcJsER6BL8xvlODa6XwJLQ0Ki7y4,28529
17
17
  awslabs/openapi_mcp_server/auth/register.py,sha256=p6rGLNSkbI-Y4KlSG24koMtS-4vvI_K0d5iZisVqLn0,4104
18
18
  awslabs/openapi_mcp_server/patch/__init__.py,sha256=sks2igP1hnfrjYhQmW5e7UpOQ_ZQ_O3NK67lcQMRDa0,795
19
19
  awslabs/openapi_mcp_server/prompts/__init__.py,sha256=exMV01HgSORPPbkPC7AZE2UqfrnK1INNW7nrv73wZ_4,783
@@ -30,9 +30,9 @@ awslabs/openapi_mcp_server/utils/http_client.py,sha256=a2wu7lfyuq1O_6ilaFQ9geFJy
30
30
  awslabs/openapi_mcp_server/utils/metrics_provider.py,sha256=1R__ZUxUrrB5KoKx4q6WYWHhaDTpFnr0UWTgZO28HVI,17731
31
31
  awslabs/openapi_mcp_server/utils/openapi.py,sha256=eRQUC5AidkyR1ALQNsR0kLXlr0Mq8ZXCduLVWUXXhuA,8802
32
32
  awslabs/openapi_mcp_server/utils/openapi_validator.py,sha256=MVJj84a8vw0BUn21pfkav6oJagDF1dSotcLK9otXzE4,9614
33
- awslabs_openapi_mcp_server-0.1.1.dist-info/METADATA,sha256=8ki5RcpM4Po80PaP1L_ubxy5xrlz0-ls1kWRuihLrvQ,16496
34
- awslabs_openapi_mcp_server-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
- awslabs_openapi_mcp_server-0.1.1.dist-info/entry_points.txt,sha256=0BwvRNOdGm62ExFDks-9tSTWgtOdI3qmg-aemCMXQkM,86
36
- awslabs_openapi_mcp_server-0.1.1.dist-info/licenses/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
37
- awslabs_openapi_mcp_server-0.1.1.dist-info/licenses/NOTICE,sha256=fG29aqEG3L4KHNXheKdyD5TdsgFh7eaaFlXu-okbf5o,94
38
- awslabs_openapi_mcp_server-0.1.1.dist-info/RECORD,,
33
+ awslabs_openapi_mcp_server-0.2.1.dist-info/METADATA,sha256=d45aQj7DUXGL6-Yz8i8lxjqOPJiJpZ17Nr_bqmm4is4,18552
34
+ awslabs_openapi_mcp_server-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
+ awslabs_openapi_mcp_server-0.2.1.dist-info/entry_points.txt,sha256=0BwvRNOdGm62ExFDks-9tSTWgtOdI3qmg-aemCMXQkM,86
36
+ awslabs_openapi_mcp_server-0.2.1.dist-info/licenses/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
37
+ awslabs_openapi_mcp_server-0.2.1.dist-info/licenses/NOTICE,sha256=fG29aqEG3L4KHNXheKdyD5TdsgFh7eaaFlXu-okbf5o,94
38
+ awslabs_openapi_mcp_server-0.2.1.dist-info/RECORD,,